mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 02:42:20 +00:00
Merge branch 'sector-portals' into 'next'
Sector portals See merge request STJr/SRB2!2139
This commit is contained in:
commit
845df8f1df
18 changed files with 1078 additions and 278 deletions
|
@ -10,6 +10,45 @@ udmf
|
|||
prefix = "(0)";
|
||||
}
|
||||
|
||||
6
|
||||
{
|
||||
title = "Sector Set Portal";
|
||||
prefix = "(6)";
|
||||
arg0
|
||||
{
|
||||
title = "Target sector tag";
|
||||
type = 13;
|
||||
}
|
||||
arg1
|
||||
{
|
||||
title = "Portal type";
|
||||
type = 11;
|
||||
enum
|
||||
{
|
||||
0 = "Link to portal with same tag";
|
||||
1 = "Copy portal from second tag";
|
||||
2 = "Skybox portal";
|
||||
3 = "Plane portal";
|
||||
4 = "Horizon portal";
|
||||
5 = "Copy portal to line";
|
||||
6 = "Interactive portal (unimplemented)";
|
||||
7 = "Link to sector with second tag";
|
||||
8 = "Link to object with second tag";
|
||||
}
|
||||
}
|
||||
arg2
|
||||
{
|
||||
title = "Affected planes";
|
||||
type = 11;
|
||||
enum = "floorceiling";
|
||||
}
|
||||
arg3
|
||||
{
|
||||
title = "Misc";
|
||||
tooltip = "For type 0 portal: specifies whether the line belongs to the sector viewed\nthrough the portal (1) or the sector in which the portal is seen (0).\nFor type 1 portal: specifies the sector tag of the portal to copy.\nFor type 7 portal: specifies the sector tag to make a portal to.\nFor type 8 portal: specifies the object tag to make a portal to.";
|
||||
}
|
||||
}
|
||||
|
||||
7
|
||||
{
|
||||
title = "Sector Flat Alignment";
|
||||
|
|
|
@ -4291,7 +4291,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_POLYANCHOR",
|
||||
"MT_POLYSPAWN",
|
||||
|
||||
// Skybox objects
|
||||
// Portal objects
|
||||
"MT_SKYBOX",
|
||||
|
||||
// Debris
|
||||
|
|
|
@ -566,7 +566,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
|
||||
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);
|
||||
dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y));
|
||||
|
@ -1139,9 +1139,6 @@ 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
|
||||
|
||||
SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight)
|
||||
SLOPEPARAMS(gl_backsector->f_slope, worldlow, worldlowslope, gl_backsector->floorheight)
|
||||
|
||||
|
@ -1506,7 +1503,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
else
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
xscale = FixedToFloat(gl_sidedef->scalex_mid);
|
||||
|
@ -1885,12 +1882,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
|
||||
|
||||
|
@ -2409,6 +2400,7 @@ static void HWR_AddLine(seg_t * line)
|
|||
#endif
|
||||
|
||||
gl_backsector = line->backsector;
|
||||
bothceilingssky = bothfloorssky = false;
|
||||
|
||||
#ifdef NEWCLIP
|
||||
if (!line->backsector)
|
||||
|
@ -2417,13 +2409,14 @@ static void HWR_AddLine(seg_t * line)
|
|||
}
|
||||
else
|
||||
{
|
||||
boolean bothceilingssky = false, 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
|
||||
&& !(P_SectorHasCeilingPortal(gl_backsector) || P_SectorHasCeilingPortal(gl_frontsector)))
|
||||
bothceilingssky = true;
|
||||
if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum)
|
||||
|
||||
if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum
|
||||
&& !(P_SectorHasFloorPortal(gl_backsector) || P_SectorHasFloorPortal(gl_frontsector)))
|
||||
bothfloorssky = true;
|
||||
|
||||
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
||||
|
@ -3020,64 +3013,16 @@ static void HWR_Subsector(size_t num)
|
|||
}
|
||||
|
||||
//SoM: 4/7/2000: Test to make Boom water work in Hardware mode.
|
||||
gl_frontsector = R_FakeFlat(gl_frontsector, &tempsec, &floorlightlevel,
|
||||
&ceilinglightlevel, false);
|
||||
//FIXME: Use floorlightlevel and ceilinglightlevel insted of lightlevel.
|
||||
gl_frontsector = R_FakeFlat(gl_frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false);
|
||||
|
||||
floorcolormap = ceilingcolormap = gl_frontsector->extra_colormap;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// sector lighting, DISABLED because it's done in HWR_StoreWallRange
|
||||
// ------------------------------------------------------------------------
|
||||
/// \todo store a RGBA instead of just intensity, allow coloured sector lighting
|
||||
//light = (FUBYTE)(sub->sector->lightlevel & 0xFF) / 255.0f;
|
||||
//gl_cursectorlight.red = light;
|
||||
//gl_cursectorlight.green = light;
|
||||
//gl_cursectorlight.blue = light;
|
||||
//gl_cursectorlight.alpha = light;
|
||||
|
||||
// ----- end special tricks -----
|
||||
cullFloorHeight = P_GetSectorFloorZAt (gl_frontsector, viewx, viewy);
|
||||
cullCeilingHeight = P_GetSectorCeilingZAt(gl_frontsector, viewx, viewy);
|
||||
locFloorHeight = P_GetSectorFloorZAt (gl_frontsector, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y);
|
||||
locCeilingHeight = P_GetSectorCeilingZAt(gl_frontsector, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y);
|
||||
|
||||
if (gl_frontsector->ffloors)
|
||||
{
|
||||
boolean anyMoved = gl_frontsector->moved;
|
||||
|
||||
if (anyMoved == false)
|
||||
{
|
||||
for (rover = gl_frontsector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *controlSec = §ors[rover->secnum];
|
||||
if (controlSec->moved == true)
|
||||
{
|
||||
anyMoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (anyMoved == true)
|
||||
{
|
||||
gl_frontsector->numlights = sub->sector->numlights = 0;
|
||||
R_Prep3DFloors(gl_frontsector);
|
||||
sub->sector->lightlist = gl_frontsector->lightlist;
|
||||
sub->sector->numlights = gl_frontsector->numlights;
|
||||
sub->sector->moved = gl_frontsector->moved = false;
|
||||
}
|
||||
|
||||
light = R_GetPlaneLight(gl_frontsector, locFloorHeight, false);
|
||||
if (gl_frontsector->floorlightsec == -1 && !gl_frontsector->floorlightabsolute)
|
||||
floorlightlevel = max(0, min(255, *gl_frontsector->lightlist[light].lightlevel + gl_frontsector->floorlightlevel));
|
||||
floorcolormap = *gl_frontsector->lightlist[light].extra_colormap;
|
||||
|
||||
light = R_GetPlaneLight(gl_frontsector, locCeilingHeight, false);
|
||||
if (gl_frontsector->ceilinglightsec == -1 && !gl_frontsector->ceilinglightabsolute)
|
||||
ceilinglightlevel = max(0, min(255, *gl_frontsector->lightlist[light].lightlevel + gl_frontsector->ceilinglightlevel));
|
||||
ceilingcolormap = *gl_frontsector->lightlist[light].extra_colormap;
|
||||
}
|
||||
R_CheckSectorLightLists(sub->sector, gl_frontsector, &floorlightlevel, &ceilinglightlevel, &floorcolormap, &ceilingcolormap);
|
||||
|
||||
sub->sector->extra_colormap = gl_frontsector->extra_colormap;
|
||||
|
||||
|
|
|
@ -5123,7 +5123,7 @@ typedef enum mobj_type
|
|||
MT_POLYANCHOR,
|
||||
MT_POLYSPAWN,
|
||||
|
||||
// Skybox objects
|
||||
// Portal objects
|
||||
MT_SKYBOX,
|
||||
|
||||
// Debris
|
||||
|
|
|
@ -3477,7 +3477,7 @@ static void PTR_GlideClimbTraverse(line_t *li)
|
|||
}
|
||||
|
||||
// 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;
|
||||
angle_t climbangle, climbline;
|
||||
|
|
227
src/p_saveg.c
227
src/p_saveg.c
|
@ -41,20 +41,19 @@ UINT8 *save_p;
|
|||
|
||||
// Block UINT32s to attempt to ensure that the correct data is
|
||||
// being sent and received
|
||||
#define ARCHIVEBLOCK_MISC 0x7FEEDEED
|
||||
#define ARCHIVEBLOCK_PLAYERS 0x7F448008
|
||||
#define ARCHIVEBLOCK_WORLD 0x7F8C08C0
|
||||
#define ARCHIVEBLOCK_POBJS 0x7F928546
|
||||
#define ARCHIVEBLOCK_THINKERS 0x7F37037C
|
||||
#define ARCHIVEBLOCK_SPECIALS 0x7F228378
|
||||
#define ARCHIVEBLOCK_EMBLEMS 0x7F4A5445
|
||||
#define ARCHIVEBLOCK_MISC 0x7FEEDEED
|
||||
#define ARCHIVEBLOCK_PLAYERS 0x7F448008
|
||||
#define ARCHIVEBLOCK_WORLD 0x7F8C08C0
|
||||
#define ARCHIVEBLOCK_POBJS 0x7F928546
|
||||
#define ARCHIVEBLOCK_THINKERS 0x7F37037C
|
||||
#define ARCHIVEBLOCK_SPECIALS 0x7F228378
|
||||
#define ARCHIVEBLOCK_EMBLEMS 0x7F4A5445
|
||||
#define ARCHIVEBLOCK_SECPORTALS 0x7FBE34C9
|
||||
|
||||
// Note: This cannot be bigger
|
||||
// than an UINT16
|
||||
typedef enum
|
||||
{
|
||||
// RFLAGPOINT = 0x01,
|
||||
// BFLAGPOINT = 0x02,
|
||||
CAPSULE = 0x04,
|
||||
AWAYVIEW = 0x08,
|
||||
FIRSTAXIS = 0x10,
|
||||
|
@ -853,33 +852,43 @@ static void P_NetUnArchiveWaypoints(void)
|
|||
#define SD_DIFF3 0x80
|
||||
|
||||
// diff3 flags
|
||||
#define SD_TAGLIST 0x01
|
||||
#define SD_COLORMAP 0x02
|
||||
#define SD_TAGLIST 0x01
|
||||
#define SD_COLORMAP 0x02
|
||||
#define SD_CRUMBLESTATE 0x04
|
||||
#define SD_FLOORLIGHT 0x08
|
||||
#define SD_CEILLIGHT 0x10
|
||||
#define SD_FLAG 0x20
|
||||
#define SD_SPECIALFLAG 0x40
|
||||
#define SD_DIFF4 0x80
|
||||
#define SD_FLOORLIGHT 0x08
|
||||
#define SD_CEILLIGHT 0x10
|
||||
#define SD_FLAG 0x20
|
||||
#define SD_SPECIALFLAG 0x40
|
||||
#define SD_DIFF4 0x80
|
||||
|
||||
//diff4 flags
|
||||
// diff4 flags
|
||||
#define SD_DAMAGETYPE 0x01
|
||||
#define SD_TRIGGERTAG 0x02
|
||||
#define SD_TRIGGERER 0x04
|
||||
#define SD_GRAVITY 0x08
|
||||
#define SD_FXSCALE 0x10
|
||||
#define SD_FYSCALE 0x20
|
||||
#define SD_CXSCALE 0x40
|
||||
#define SD_CYSCALE 0x80
|
||||
#define SD_FXSCALE 0x08
|
||||
#define SD_FYSCALE 0x10
|
||||
#define SD_CXSCALE 0x20
|
||||
#define SD_CYSCALE 0x40
|
||||
#define SD_DIFF5 0x80
|
||||
|
||||
// diff5 flags
|
||||
#define SD_GRAVITY 0x01
|
||||
#define SD_FLOORPORTAL 0x02
|
||||
#define SD_CEILPORTAL 0x04
|
||||
|
||||
// diff1 flags
|
||||
#define LD_FLAG 0x01
|
||||
#define LD_SPECIAL 0x02
|
||||
#define LD_CLLCOUNT 0x04
|
||||
#define LD_ARGS 0x08
|
||||
#define LD_STRINGARGS 0x10
|
||||
#define LD_EXECUTORDELAY 0x20
|
||||
#define LD_SIDE1 0x40
|
||||
#define LD_SIDE2 0x80
|
||||
#define LD_SIDE1 0x20
|
||||
#define LD_SIDE2 0x40
|
||||
#define LD_DIFF2 0x80
|
||||
|
||||
// diff2 flags
|
||||
#define LD_EXECUTORDELAY 0x01
|
||||
#define LD_TRANSFPORTAL 0x02
|
||||
|
||||
// sidedef flags
|
||||
enum
|
||||
|
@ -1028,11 +1037,11 @@ static void ArchiveSectors(void)
|
|||
size_t i, j;
|
||||
const sector_t *ss = sectors;
|
||||
const sector_t *spawnss = spawnsectors;
|
||||
UINT8 diff, diff2, diff3, diff4;
|
||||
UINT8 diff, diff2, diff3, diff4, diff5;
|
||||
|
||||
for (i = 0; i < numsectors; i++, ss++, spawnss++)
|
||||
{
|
||||
diff = diff2 = diff3 = diff4 = 0;
|
||||
diff = diff2 = diff3 = diff4 = diff5 = 0;
|
||||
if (ss->floorheight != spawnss->floorheight)
|
||||
diff |= SD_FLOORHT;
|
||||
if (ss->ceilingheight != spawnss->ceilingheight)
|
||||
|
@ -1094,11 +1103,18 @@ static void ArchiveSectors(void)
|
|||
if (ss->triggerer != spawnss->triggerer)
|
||||
diff4 |= SD_TRIGGERER;
|
||||
if (ss->gravity != spawnss->gravity)
|
||||
diff4 |= SD_GRAVITY;
|
||||
diff5 |= SD_GRAVITY;
|
||||
if (ss->portal_floor != spawnss->portal_floor)
|
||||
diff5 |= SD_FLOORPORTAL;
|
||||
if (ss->portal_ceiling != spawnss->portal_ceiling)
|
||||
diff5 |= SD_CEILPORTAL;
|
||||
|
||||
if (ss->ffloors && CheckFFloorDiff(ss))
|
||||
diff |= SD_FFLOORS;
|
||||
|
||||
if (diff5)
|
||||
diff4 |= SD_DIFF5;
|
||||
|
||||
if (diff4)
|
||||
diff3 |= SD_DIFF4;
|
||||
|
||||
|
@ -1118,6 +1134,8 @@ static void ArchiveSectors(void)
|
|||
WRITEUINT8(save_p, diff3);
|
||||
if (diff3 & SD_DIFF4)
|
||||
WRITEUINT8(save_p, diff4);
|
||||
if (diff4 & SD_DIFF5)
|
||||
WRITEUINT8(save_p, diff5);
|
||||
if (diff & SD_FLOORHT)
|
||||
WRITEFIXED(save_p, ss->floorheight);
|
||||
if (diff & SD_CEILHT)
|
||||
|
@ -1174,8 +1192,6 @@ static void ArchiveSectors(void)
|
|||
WRITEINT16(save_p, ss->triggertag);
|
||||
if (diff4 & SD_TRIGGERER)
|
||||
WRITEUINT8(save_p, ss->triggerer);
|
||||
if (diff4 & SD_GRAVITY)
|
||||
WRITEFIXED(save_p, ss->gravity);
|
||||
if (diff4 & SD_FXSCALE)
|
||||
WRITEFIXED(save_p, ss->floorxscale);
|
||||
if (diff4 & SD_FYSCALE)
|
||||
|
@ -1184,6 +1200,12 @@ static void ArchiveSectors(void)
|
|||
WRITEFIXED(save_p, ss->ceilingxscale);
|
||||
if (diff4 & SD_CYSCALE)
|
||||
WRITEFIXED(save_p, ss->ceilingyscale);
|
||||
if (diff5 & SD_GRAVITY)
|
||||
WRITEFIXED(save_p, ss->gravity);
|
||||
if (diff5 & SD_FLOORPORTAL)
|
||||
WRITEUINT32(save_p, ss->portal_floor);
|
||||
if (diff5 & SD_CEILPORTAL)
|
||||
WRITEUINT32(save_p, ss->portal_ceiling);
|
||||
if (diff & SD_FFLOORS)
|
||||
ArchiveFFloors(ss);
|
||||
}
|
||||
|
@ -1196,7 +1218,7 @@ static void UnArchiveSectors(void)
|
|||
{
|
||||
UINT32 i;
|
||||
UINT16 j;
|
||||
UINT8 diff, diff2, diff3, diff4;
|
||||
UINT8 diff, diff2, diff3, diff4, diff5;
|
||||
for (;;)
|
||||
{
|
||||
i = READUINT32(save_p);
|
||||
|
@ -1220,6 +1242,10 @@ static void UnArchiveSectors(void)
|
|||
diff4 = READUINT8(save_p);
|
||||
else
|
||||
diff4 = 0;
|
||||
if (diff4 & SD_DIFF5)
|
||||
diff5 = READUINT8(save_p);
|
||||
else
|
||||
diff5 = 0;
|
||||
|
||||
if (diff & SD_FLOORHT)
|
||||
sectors[i].floorheight = READFIXED(save_p);
|
||||
|
@ -1303,8 +1329,6 @@ static void UnArchiveSectors(void)
|
|||
sectors[i].triggertag = READINT16(save_p);
|
||||
if (diff4 & SD_TRIGGERER)
|
||||
sectors[i].triggerer = READUINT8(save_p);
|
||||
if (diff4 & SD_GRAVITY)
|
||||
sectors[i].gravity = READFIXED(save_p);
|
||||
if (diff4 & SD_FXSCALE)
|
||||
sectors[i].floorxscale = READFIXED(save_p);
|
||||
if (diff4 & SD_FYSCALE)
|
||||
|
@ -1313,6 +1337,12 @@ static void UnArchiveSectors(void)
|
|||
sectors[i].ceilingxscale = READFIXED(save_p);
|
||||
if (diff4 & SD_CYSCALE)
|
||||
sectors[i].ceilingyscale = READFIXED(save_p);
|
||||
if (diff5 & SD_GRAVITY)
|
||||
sectors[i].gravity = READFIXED(save_p);
|
||||
if (diff5 & SD_FLOORPORTAL)
|
||||
sectors[i].portal_floor = READUINT32(save_p);
|
||||
if (diff5 & SD_CEILPORTAL)
|
||||
sectors[i].portal_ceiling = READUINT32(save_p);
|
||||
|
||||
if (diff & SD_FFLOORS)
|
||||
UnArchiveFFloors(§ors[i]);
|
||||
|
@ -1409,13 +1439,14 @@ static void ArchiveLines(void)
|
|||
size_t i;
|
||||
const line_t *li = lines;
|
||||
const line_t *spawnli = spawnlines;
|
||||
UINT8 diff;
|
||||
UINT32 diff2;
|
||||
UINT32 diff3;
|
||||
UINT8 diff, diff2;
|
||||
UINT32 side1diff;
|
||||
UINT32 side2diff;
|
||||
|
||||
for (i = 0; i < numlines; i++, spawnli++, li++)
|
||||
{
|
||||
diff = diff2 = diff3 = 0;
|
||||
diff = diff2 = 0;
|
||||
side1diff = side2diff = 0;
|
||||
|
||||
if (li->special != spawnli->special)
|
||||
diff |= LD_SPECIAL;
|
||||
|
@ -1430,25 +1461,33 @@ static void ArchiveLines(void)
|
|||
diff |= LD_STRINGARGS;
|
||||
|
||||
if (li->executordelay != spawnli->executordelay)
|
||||
diff |= LD_EXECUTORDELAY;
|
||||
diff2 |= LD_EXECUTORDELAY;
|
||||
|
||||
if (li->secportal != spawnli->secportal)
|
||||
diff2 |= LD_TRANSFPORTAL;
|
||||
|
||||
if (li->sidenum[0] != NO_SIDEDEF)
|
||||
{
|
||||
diff2 = GetSideDiff(&sides[li->sidenum[0]], &spawnsides[li->sidenum[0]]);
|
||||
if (diff2)
|
||||
side1diff = GetSideDiff(&sides[li->sidenum[0]], &spawnsides[li->sidenum[0]]);
|
||||
if (side1diff)
|
||||
diff |= LD_SIDE1;
|
||||
}
|
||||
if (li->sidenum[1] != NO_SIDEDEF)
|
||||
{
|
||||
diff3 = GetSideDiff(&sides[li->sidenum[1]], &spawnsides[li->sidenum[1]]);
|
||||
if (diff3)
|
||||
side2diff = GetSideDiff(&sides[li->sidenum[1]], &spawnsides[li->sidenum[1]]);
|
||||
if (side2diff)
|
||||
diff |= LD_SIDE2;
|
||||
}
|
||||
|
||||
if (diff2)
|
||||
diff |= LD_DIFF2;
|
||||
|
||||
if (diff)
|
||||
{
|
||||
WRITEUINT32(save_p, i);
|
||||
WRITEUINT8(save_p, diff);
|
||||
if (diff & LD_DIFF2)
|
||||
WRITEUINT8(save_p, diff2);
|
||||
if (diff & LD_FLAG)
|
||||
WRITEINT16(save_p, li->flags);
|
||||
if (diff & LD_SPECIAL)
|
||||
|
@ -1480,12 +1519,14 @@ static void ArchiveLines(void)
|
|||
WRITECHAR(save_p, li->stringargs[j][k]);
|
||||
}
|
||||
}
|
||||
if (diff & LD_EXECUTORDELAY)
|
||||
WRITEINT32(save_p, li->executordelay);
|
||||
if (diff & LD_SIDE1)
|
||||
ArchiveSide(&sides[li->sidenum[0]], diff2);
|
||||
ArchiveSide(&sides[li->sidenum[0]], side1diff);
|
||||
if (diff & LD_SIDE2)
|
||||
ArchiveSide(&sides[li->sidenum[1]], diff3);
|
||||
ArchiveSide(&sides[li->sidenum[1]], side2diff);
|
||||
if (diff2 & LD_EXECUTORDELAY)
|
||||
WRITEINT32(save_p, li->executordelay);
|
||||
if (diff2 & LD_TRANSFPORTAL)
|
||||
WRITEUINT32(save_p, li->secportal);
|
||||
}
|
||||
}
|
||||
WRITEUINT32(save_p, 0xffffffff);
|
||||
|
@ -1537,7 +1578,7 @@ static void UnArchiveLines(void)
|
|||
{
|
||||
UINT32 i;
|
||||
line_t *li;
|
||||
UINT8 diff;
|
||||
UINT8 diff, diff2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1549,6 +1590,10 @@ static void UnArchiveLines(void)
|
|||
I_Error("Invalid line number %u from server", i);
|
||||
|
||||
diff = READUINT8(save_p);
|
||||
if (diff & LD_DIFF2)
|
||||
diff2 = READUINT8(save_p);
|
||||
else
|
||||
diff2 = 0;
|
||||
li = &lines[i];
|
||||
|
||||
if (diff & LD_FLAG)
|
||||
|
@ -1584,12 +1629,14 @@ static void UnArchiveLines(void)
|
|||
li->stringargs[j][len] = '\0';
|
||||
}
|
||||
}
|
||||
if (diff & LD_EXECUTORDELAY)
|
||||
li->executordelay = READINT32(save_p);
|
||||
if (diff & LD_SIDE1)
|
||||
UnArchiveSide(&sides[li->sidenum[0]]);
|
||||
if (diff & LD_SIDE2)
|
||||
UnArchiveSide(&sides[li->sidenum[1]]);
|
||||
if (diff2 & LD_EXECUTORDELAY)
|
||||
li->executordelay = READINT32(save_p);
|
||||
if (diff2 & LD_TRANSFPORTAL)
|
||||
li->secportal = READUINT32(save_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4851,6 +4898,86 @@ static inline void P_NetUnArchiveEmblems(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void P_NetArchiveSectorPortals(void)
|
||||
{
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_SECPORTALS);
|
||||
|
||||
WRITEUINT32(save_p, secportalcount);
|
||||
|
||||
for (size_t i = 0; i < secportalcount; i++)
|
||||
{
|
||||
UINT8 type = secportals[i].type;
|
||||
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEFIXED(save_p, secportals[i].origin.x);
|
||||
WRITEFIXED(save_p, secportals[i].origin.y);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SECPORTAL_LINE:
|
||||
WRITEUINT32(save_p, SaveLine(secportals[i].line.start));
|
||||
WRITEUINT32(save_p, SaveLine(secportals[i].line.dest));
|
||||
break;
|
||||
case SECPORTAL_PLANE:
|
||||
case SECPORTAL_HORIZON:
|
||||
case SECPORTAL_FLOOR:
|
||||
case SECPORTAL_CEILING:
|
||||
WRITEUINT32(save_p, SaveSector(secportals[i].sector));
|
||||
break;
|
||||
case SECPORTAL_OBJECT:
|
||||
if (secportals[i].mobj && !P_MobjWasRemoved(secportals[i].mobj))
|
||||
SaveMobjnum(secportals[i].mobj);
|
||||
else
|
||||
WRITEUINT32(save_p, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void P_NetUnArchiveSectorPortals(void)
|
||||
{
|
||||
if (READUINT32(save_p) != ARCHIVEBLOCK_SECPORTALS)
|
||||
I_Error("Bad $$$.sav at archive block Secportals");
|
||||
|
||||
Z_Free(secportals);
|
||||
P_InitSectorPortals();
|
||||
|
||||
UINT32 count = READUINT32(save_p);
|
||||
|
||||
for (UINT32 i = 0; i < count; i++)
|
||||
{
|
||||
UINT32 id = P_NewSectorPortal();
|
||||
|
||||
sectorportal_t *secportal = &secportals[id];
|
||||
|
||||
secportal->type = READUINT8(save_p);
|
||||
secportal->origin.x = READFIXED(save_p);
|
||||
secportal->origin.y = READFIXED(save_p);
|
||||
|
||||
switch (secportal->type)
|
||||
{
|
||||
case SECPORTAL_LINE:
|
||||
secportal->line.start = LoadLine(READUINT32(save_p));
|
||||
secportal->line.dest = LoadLine(READUINT32(save_p));
|
||||
break;
|
||||
case SECPORTAL_PLANE:
|
||||
case SECPORTAL_HORIZON:
|
||||
case SECPORTAL_FLOOR:
|
||||
case SECPORTAL_CEILING:
|
||||
secportal->sector = LoadSector(READUINT32(save_p));
|
||||
break;
|
||||
case SECPORTAL_OBJECT:
|
||||
id = READUINT32(save_p);
|
||||
secportal->mobj = (id == 0) ? NULL : P_FindNewPosition(id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void P_ArchiveLuabanksAndConsistency(void)
|
||||
{
|
||||
UINT8 i, banksinuse = NUM_LUABANKS;
|
||||
|
@ -4937,6 +5064,7 @@ void P_SaveNetGame(boolean resending)
|
|||
P_NetArchiveSpecials();
|
||||
P_NetArchiveColormaps();
|
||||
P_NetArchiveWaypoints();
|
||||
P_NetArchiveSectorPortals();
|
||||
}
|
||||
LUA_Archive();
|
||||
|
||||
|
@ -4977,6 +5105,7 @@ boolean P_LoadNetGame(boolean reloading)
|
|||
P_NetUnArchiveSpecials();
|
||||
P_NetUnArchiveColormaps();
|
||||
P_NetUnArchiveWaypoints();
|
||||
P_NetUnArchiveSectorPortals();
|
||||
P_RelinkPointers();
|
||||
P_FinishMobjs();
|
||||
}
|
||||
|
|
|
@ -993,6 +993,9 @@ static void P_InitializeSector(sector_t *ss)
|
|||
ss->lightingdata = NULL;
|
||||
ss->fadecolormapdata = NULL;
|
||||
|
||||
ss->portal_floor = UINT32_MAX;
|
||||
ss->portal_ceiling = UINT32_MAX;
|
||||
|
||||
ss->heightsec = -1;
|
||||
ss->camsec = -1;
|
||||
|
||||
|
@ -1110,6 +1113,7 @@ static void P_InitializeLinedef(line_t *ld)
|
|||
ld->polyobj = NULL;
|
||||
|
||||
ld->callcount = 0;
|
||||
ld->secportal = UINT32_MAX;
|
||||
|
||||
// cph 2006/09/30 - fix sidedef errors right away.
|
||||
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
|
||||
|
@ -7883,6 +7887,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
P_InitThinkers();
|
||||
R_InitMobjInterpolators();
|
||||
P_InitCachedActions();
|
||||
P_InitSectorPortals();
|
||||
|
||||
// internal game map
|
||||
maplumpname = G_BuildMapName(gamemap);
|
||||
|
|
365
src/p_spec.c
365
src/p_spec.c
|
@ -52,6 +52,10 @@ mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
|
|||
mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
|
||||
mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
|
||||
|
||||
size_t secportalcount;
|
||||
size_t secportalcapacity;
|
||||
sectorportal_t *secportals;
|
||||
|
||||
/** Animated texture descriptor
|
||||
* This keeps track of an animated texture or an animated flat.
|
||||
* \sa P_UpdateSpecials, P_InitPicAnims, animdef_t
|
||||
|
@ -6199,6 +6203,196 @@ fixed_t P_GetSectorGravityFactor(sector_t *sec)
|
|||
return sec->gravity;
|
||||
}
|
||||
|
||||
void P_InitSectorPortals(void)
|
||||
{
|
||||
secportalcount = 0;
|
||||
secportalcapacity = 0;
|
||||
secportals = NULL;
|
||||
}
|
||||
|
||||
UINT32 P_NewSectorPortal(void)
|
||||
{
|
||||
size_t i = secportalcount++;
|
||||
if (i == UINT32_MAX)
|
||||
I_Error("Too many sector portals");
|
||||
|
||||
if (secportalcapacity == 0 || secportalcount == secportalcapacity)
|
||||
{
|
||||
secportalcapacity = secportalcapacity ? (secportalcapacity * 2) : 16;
|
||||
secportals = Z_Realloc(secportals, secportalcapacity * sizeof(sectorportal_t), PU_LEVEL, NULL);
|
||||
}
|
||||
|
||||
secportals[i].type = SECPORTAL_NONE;
|
||||
|
||||
return (UINT32)i;
|
||||
}
|
||||
|
||||
boolean P_IsSectorPortalValid(sectorportal_t *secportal)
|
||||
{
|
||||
if (secportal == NULL)
|
||||
return false;
|
||||
|
||||
switch (secportal->type)
|
||||
{
|
||||
case SECPORTAL_LINE:
|
||||
case SECPORTAL_FLOOR:
|
||||
case SECPORTAL_CEILING:
|
||||
return true;
|
||||
case SECPORTAL_OBJECT:
|
||||
return secportal->mobj && !P_MobjWasRemoved(secportal->mobj);
|
||||
case SECPORTAL_SKYBOX:
|
||||
return skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0]);
|
||||
case SECPORTAL_PLANE:
|
||||
case SECPORTAL_HORIZON:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean P_SectorHasPortal(sector_t *sector)
|
||||
{
|
||||
return P_SectorHasFloorPortal(sector) || P_SectorHasCeilingPortal(sector);
|
||||
}
|
||||
|
||||
sectorportal_t *P_SectorGetFloorPortal(sector_t *sector)
|
||||
{
|
||||
UINT32 num = sector->portal_floor;
|
||||
if (num >= secportalcount)
|
||||
return NULL;
|
||||
|
||||
return &secportals[num];
|
||||
}
|
||||
|
||||
sectorportal_t *P_SectorGetCeilingPortal(sector_t *sector)
|
||||
{
|
||||
UINT32 num = sector->portal_ceiling;
|
||||
if (num >= secportalcount)
|
||||
return NULL;
|
||||
|
||||
return &secportals[num];
|
||||
}
|
||||
|
||||
boolean P_SectorHasFloorPortal(sector_t *sector)
|
||||
{
|
||||
return P_IsSectorPortalValid(P_SectorGetFloorPortal(sector));
|
||||
}
|
||||
|
||||
boolean P_SectorHasCeilingPortal(sector_t *sector)
|
||||
{
|
||||
return P_IsSectorPortalValid(P_SectorGetCeilingPortal(sector));
|
||||
}
|
||||
|
||||
boolean P_CompareSectorPortals(sectorportal_t *a, sectorportal_t *b)
|
||||
{
|
||||
if (a == NULL && b == NULL)
|
||||
return true;
|
||||
else if (!a || !b)
|
||||
return false;
|
||||
else if (a->type != b->type)
|
||||
return false;
|
||||
|
||||
switch (a->type)
|
||||
{
|
||||
case SECPORTAL_LINE:
|
||||
return a->line.start == b->line.start && a->line.dest == b->line.dest;
|
||||
case SECPORTAL_FLOOR:
|
||||
case SECPORTAL_CEILING:
|
||||
return a->sector == b->sector;
|
||||
case SECPORTAL_OBJECT:
|
||||
return a->mobj == b->mobj;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static mobj_t *P_GetMobjByTag(INT32 tag)
|
||||
{
|
||||
INT32 mtnum = -1;
|
||||
|
||||
TAG_ITER_THINGS(tag, mtnum)
|
||||
{
|
||||
mobj_t *mo = mapthings[mtnum].mobj;
|
||||
if (mo)
|
||||
return mo;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void P_DoPortalCopyFromLine(sector_t *dest_sector, int plane_type, int tag)
|
||||
{
|
||||
INT32 secnum = -1;
|
||||
TAG_ITER_SECTORS(tag, secnum)
|
||||
{
|
||||
sector_t *src_sector = §ors[secnum];
|
||||
if (plane_type == TMP_FLOOR || plane_type == TMP_BOTH)
|
||||
dest_sector->portal_floor = src_sector->portal_floor;
|
||||
if (plane_type == TMP_CEILING || plane_type == TMP_BOTH)
|
||||
dest_sector->portal_ceiling = src_sector->portal_ceiling;
|
||||
}
|
||||
}
|
||||
|
||||
static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, UINT32 *result)
|
||||
{
|
||||
sectorportal_t *secportal = NULL;
|
||||
|
||||
if (*num >= secportalcount)
|
||||
{
|
||||
*num = P_NewSectorPortal();
|
||||
secportal = &secportals[*num];
|
||||
secportal->origin.x = sector->soundorg.x;
|
||||
secportal->origin.y = sector->soundorg.y;
|
||||
*result = *num;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = *num;
|
||||
secportal = &secportals[*num];
|
||||
}
|
||||
|
||||
return secportal;
|
||||
}
|
||||
|
||||
static sectorportal_t *P_SectorGetFloorPortalOrCreate(sector_t *sector, UINT32 *result)
|
||||
{
|
||||
return P_SectorGetPortalOrCreate(sector, §or->portal_floor, result);
|
||||
}
|
||||
|
||||
static sectorportal_t *P_SectorGetCeilingPortalOrCreate(sector_t *sector, UINT32 *result)
|
||||
{
|
||||
return P_SectorGetPortalOrCreate(sector, §or->portal_ceiling, result);
|
||||
}
|
||||
|
||||
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
|
||||
* thinkers.
|
||||
*
|
||||
|
@ -6365,6 +6559,146 @@ 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));
|
||||
break;
|
||||
|
||||
case SPECIAL_SECTOR_SETPORTAL: // Sector portal
|
||||
{
|
||||
int target_sector_tag = lines[i].args[0];
|
||||
int portal_type = lines[i].args[1];
|
||||
int plane_type = lines[i].args[2];
|
||||
int misc = lines[i].args[3];
|
||||
|
||||
boolean floor, ceiling;
|
||||
if (plane_type == TMP_BOTH)
|
||||
floor = ceiling = true;
|
||||
else
|
||||
{
|
||||
floor = plane_type == TMP_FLOOR;
|
||||
ceiling = plane_type == TMP_CEILING;
|
||||
}
|
||||
|
||||
UINT32 portal_num = UINT32_MAX;
|
||||
|
||||
// Eternity's floor and horizon portal types
|
||||
if (portal_type == TMSECPORTAL_PLANE || portal_type == TMSECPORTAL_HORIZON)
|
||||
{
|
||||
secportaltype_e type = portal_type == TMSECPORTAL_HORIZON ? SECPORTAL_HORIZON : SECPORTAL_PLANE;
|
||||
if (floor)
|
||||
{
|
||||
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(lines[i].frontsector, &portal_num);
|
||||
floorportal->type = type;
|
||||
floorportal->sector = lines[i].frontsector;
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
if (ceiling)
|
||||
{
|
||||
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(lines[i].frontsector, &portal_num);
|
||||
ceilportal->type = type;
|
||||
ceilportal->sector = lines[i].frontsector;
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
INT32 s1 = -1;
|
||||
|
||||
TAG_ITER_SECTORS(target_sector_tag, s1)
|
||||
{
|
||||
sector_t *target_sector = §ors[s1];
|
||||
|
||||
// Line portal
|
||||
if (portal_type == TMSECPORTAL_NORMAL)
|
||||
{
|
||||
INT32 linenum = -1;
|
||||
TAG_ITER_LINES(misc, linenum)
|
||||
{
|
||||
if (lines[linenum].special == SPECIAL_SECTOR_SETPORTAL
|
||||
&& lines[linenum].args[0] == target_sector_tag
|
||||
&& lines[linenum].args[1] == portal_type
|
||||
&& lines[linenum].args[2] == plane_type
|
||||
&& lines[linenum].args[3] == 1)
|
||||
{
|
||||
if (floor)
|
||||
{
|
||||
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
|
||||
floorportal->type = SECPORTAL_LINE;
|
||||
floorportal->line.start = &lines[i];
|
||||
floorportal->line.dest = &lines[linenum];
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
if (ceiling)
|
||||
{
|
||||
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
|
||||
ceilportal->type = SECPORTAL_LINE;
|
||||
ceilportal->line.start = &lines[i];
|
||||
ceilportal->line.dest = &lines[linenum];
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Skybox portal
|
||||
else if (portal_type == TMSECPORTAL_SKYBOX)
|
||||
{
|
||||
if (floor)
|
||||
{
|
||||
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
|
||||
floorportal->type = SECPORTAL_SKYBOX;
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
if (ceiling)
|
||||
{
|
||||
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
|
||||
ceilportal->type = SECPORTAL_SKYBOX;
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
}
|
||||
// Plane portal
|
||||
else if (portal_type == TMSECPORTAL_SECTOR)
|
||||
{
|
||||
INT32 s2 = -1;
|
||||
TAG_ITER_SECTORS(misc, s2) // Sector tag to make a portal to
|
||||
{
|
||||
sector_t *view_sector = §ors[s2];
|
||||
if (floor)
|
||||
{
|
||||
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
|
||||
floorportal->type = SECPORTAL_CEILING;
|
||||
floorportal->sector = view_sector;
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
if (ceiling)
|
||||
{
|
||||
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
|
||||
ceilportal->type = SECPORTAL_FLOOR;
|
||||
ceilportal->sector = view_sector;
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use mobj as viewpoint
|
||||
else if (portal_type == TMSECPORTAL_OBJECT)
|
||||
{
|
||||
mobj_t *mobj = P_GetMobjByTag(misc);
|
||||
if (!mobj)
|
||||
break;
|
||||
if (floor)
|
||||
{
|
||||
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
|
||||
floorportal->type = SECPORTAL_OBJECT;
|
||||
P_SetTarget(&floorportal->mobj, mobj);
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
if (ceiling)
|
||||
{
|
||||
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
|
||||
ceilportal->type = SECPORTAL_OBJECT;
|
||||
P_SetTarget(&ceilportal->mobj, mobj);
|
||||
P_CopySectorPortalToLines(portal_num, target_sector_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: // Flat alignment - redone by toast
|
||||
{
|
||||
// Set calculated offsets such that line's v1 is the apparent origin
|
||||
|
@ -7140,10 +7474,6 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Allocate each list
|
||||
for (i = 0; i < numsectors; i++)
|
||||
if(secthinkers[i].thinkers)
|
||||
|
@ -7172,6 +7502,33 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
}
|
||||
}
|
||||
|
||||
// Copy portals
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
if (lines[i].special != SPECIAL_SECTOR_SETPORTAL)
|
||||
continue;
|
||||
|
||||
int portal_type = lines[i].args[1];
|
||||
if (portal_type != TMSECPORTAL_COPIED)
|
||||
continue;
|
||||
|
||||
int target_sector_tag = lines[i].args[0];
|
||||
int plane_type = lines[i].args[2];
|
||||
int tag_to_copy = lines[i].args[3];
|
||||
|
||||
if (plane_type == 3)
|
||||
plane_type = TMP_BOTH;
|
||||
|
||||
if (target_sector_tag == 0)
|
||||
P_DoPortalCopyFromLine(lines[i].frontsector, plane_type, tag_to_copy);
|
||||
else
|
||||
{
|
||||
INT32 s1 = -1;
|
||||
TAG_ITER_SECTORS(target_sector_tag, s1)
|
||||
P_DoPortalCopyFromLine(§ors[s1], plane_type, tag_to_copy);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fromnetsave)
|
||||
P_RunLevelLoadExecutors();
|
||||
}
|
||||
|
|
31
src/p_spec.h
31
src/p_spec.h
|
@ -21,6 +21,10 @@ extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpo
|
|||
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
|
||||
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
|
||||
|
||||
extern size_t secportalcount;
|
||||
extern size_t secportalcapacity;
|
||||
extern sectorportal_t *secportals;
|
||||
|
||||
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
|
||||
#define SCROLL_SHIFT 5
|
||||
|
||||
|
@ -472,6 +476,20 @@ typedef enum
|
|||
TMB_MODULATE = 4,
|
||||
} textmapblendmodes_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TMSECPORTAL_NORMAL = 0,
|
||||
TMSECPORTAL_COPIED = 1,
|
||||
TMSECPORTAL_SKYBOX = 2,
|
||||
TMSECPORTAL_PLANE = 3,
|
||||
TMSECPORTAL_HORIZON = 4,
|
||||
TMSECPORTAL_COPY_PORTAL_TO_LINE = 5,
|
||||
TMSECPORTAL_INTERACTIVE = 6, // unimplemented
|
||||
// The two portal types below are new to SRB2
|
||||
TMSECPORTAL_SECTOR = 7,
|
||||
TMSECPORTAL_OBJECT = 8
|
||||
} textmapsecportaltype_t;
|
||||
|
||||
// GETSECSPECIAL (specialval, section)
|
||||
//
|
||||
// Pulls out the special # from a particular section.
|
||||
|
@ -521,6 +539,19 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max);
|
|||
void P_SetupSignExit(player_t *player);
|
||||
boolean P_IsFlagAtBase(mobjtype_t flag);
|
||||
|
||||
void P_InitSectorPortals(void);
|
||||
UINT32 P_NewSectorPortal(void);
|
||||
|
||||
boolean P_IsSectorPortalValid(sectorportal_t *secportal);
|
||||
|
||||
sectorportal_t *P_SectorGetFloorPortal(sector_t *sector);
|
||||
sectorportal_t *P_SectorGetCeilingPortal(sector_t *sector);
|
||||
|
||||
boolean P_SectorHasPortal(sector_t *sector);
|
||||
boolean P_SectorHasFloorPortal(sector_t *sector);
|
||||
boolean P_SectorHasCeilingPortal(sector_t *sector);
|
||||
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);
|
||||
|
|
225
src/r_bsp.c
225
src/r_bsp.c
|
@ -36,6 +36,11 @@ 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
|
||||
|
||||
boolean horizonline = false;
|
||||
|
||||
// indicates doors closed wrt automap bugfix:
|
||||
INT32 doorclosed;
|
||||
|
||||
|
@ -366,6 +371,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
|
||||
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
|
||||
{
|
||||
if (P_SectorHasPortal(front) && !P_SectorHasPortal(back))
|
||||
return false;
|
||||
else if (!P_SectorHasPortal(front) && P_SectorHasPortal(back))
|
||||
return false;
|
||||
|
||||
return (
|
||||
!line->polyseg &&
|
||||
back->ceilingpic == front->ceilingpic
|
||||
|
@ -407,7 +417,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;
|
||||
|
||||
|
@ -465,6 +474,8 @@ static void R_AddLine(seg_t *line)
|
|||
return;
|
||||
|
||||
backsector = line->backsector;
|
||||
horizonline = line->linedef->special == SPECIAL_HORIZON_LINE;
|
||||
bothceilingssky = bothfloorssky = false;
|
||||
|
||||
// Portal line
|
||||
if (line->linedef->special == 40 && line->side == 0)
|
||||
|
@ -489,6 +500,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->secportal, x1, x2);
|
||||
goto clipsolid;
|
||||
}
|
||||
}
|
||||
|
||||
// Single sided line?
|
||||
if (!backsector)
|
||||
|
@ -498,9 +518,15 @@ static void R_AddLine(seg_t *line)
|
|||
|
||||
doorclosed = 0;
|
||||
|
||||
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
|
||||
&& !(P_SectorHasCeilingPortal(backsector) || P_SectorHasCeilingPortal(frontsector)))
|
||||
bothceilingssky = true;
|
||||
if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum)
|
||||
|
||||
// likewise, but for floors and upper textures
|
||||
if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum
|
||||
&& !(P_SectorHasFloorPortal(backsector) || P_SectorHasFloorPortal(frontsector)))
|
||||
bothfloorssky = true;
|
||||
|
||||
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
||||
|
@ -585,7 +611,6 @@ static void R_AddLine(seg_t *line)
|
|||
// Reject empty lines used for triggers and special events.
|
||||
// Identical floor and ceiling on both sides, identical light levels on both sides,
|
||||
// and no middle texture.
|
||||
|
||||
if (R_IsEmptyLine(line, frontsector, backsector))
|
||||
return;
|
||||
|
||||
|
@ -880,66 +905,32 @@ static void R_Subsector(size_t num)
|
|||
floorcenterz = P_GetSectorFloorZAt (frontsector, frontsector->soundorg.x, frontsector->soundorg.y);
|
||||
ceilingcenterz = P_GetSectorCeilingZAt(frontsector, frontsector->soundorg.x, frontsector->soundorg.y);
|
||||
|
||||
// Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps.
|
||||
if (frontsector->ffloors)
|
||||
{
|
||||
boolean anyMoved = frontsector->moved;
|
||||
|
||||
if (anyMoved == false)
|
||||
{
|
||||
for (rover = frontsector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *controlSec = §ors[rover->secnum];
|
||||
|
||||
if (controlSec->moved == true)
|
||||
{
|
||||
anyMoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (anyMoved == true)
|
||||
{
|
||||
frontsector->numlights = sub->sector->numlights = 0;
|
||||
R_Prep3DFloors(frontsector);
|
||||
sub->sector->lightlist = frontsector->lightlist;
|
||||
sub->sector->numlights = frontsector->numlights;
|
||||
sub->sector->moved = frontsector->moved = false;
|
||||
}
|
||||
|
||||
light = R_GetPlaneLight(frontsector, floorcenterz, false);
|
||||
if (frontsector->floorlightsec == -1 && !frontsector->floorlightabsolute)
|
||||
floorlightlevel = max(0, min(255, *frontsector->lightlist[light].lightlevel + frontsector->floorlightlevel));
|
||||
floorcolormap = *frontsector->lightlist[light].extra_colormap;
|
||||
light = R_GetPlaneLight(frontsector, ceilingcenterz, false);
|
||||
if (frontsector->ceilinglightsec == -1 && !frontsector->ceilinglightabsolute)
|
||||
ceilinglightlevel = max(0, min(255, *frontsector->lightlist[light].lightlevel + frontsector->ceilinglightlevel));
|
||||
ceilingcolormap = *frontsector->lightlist[light].extra_colormap;
|
||||
}
|
||||
R_CheckSectorLightLists(sub->sector, frontsector, &floorlightlevel, &ceilinglightlevel, &floorcolormap, &ceilingcolormap);
|
||||
|
||||
sub->sector->extra_colormap = frontsector->extra_colormap;
|
||||
|
||||
if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz
|
||||
|| frontsector->floorpic == skyflatnum
|
||||
|| P_SectorHasFloorPortal(frontsector)
|
||||
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
|
||||
{
|
||||
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
|
||||
floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel,
|
||||
frontsector->floorxoffset, frontsector->flooryoffset,
|
||||
frontsector->floorxscale, frontsector->flooryscale, frontsector->floorangle,
|
||||
floorcolormap, NULL, NULL, frontsector->f_slope);
|
||||
floorcolormap, NULL, NULL, frontsector->f_slope, P_SectorGetFloorPortal(frontsector));
|
||||
}
|
||||
else
|
||||
floorplane = NULL;
|
||||
|
||||
if (P_GetSectorCeilingZAt(frontsector, viewx, viewy) > viewz
|
||||
|| frontsector->ceilingpic == skyflatnum
|
||||
|| P_SectorHasCeilingPortal(frontsector)
|
||||
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))
|
||||
{
|
||||
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel,
|
||||
ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel,
|
||||
frontsector->ceilingxoffset, frontsector->ceilingyoffset,
|
||||
frontsector->ceilingxscale, frontsector->ceilingyscale, frontsector->ceilingangle,
|
||||
ceilingcolormap, NULL, NULL, frontsector->c_slope);
|
||||
ceilingcolormap, NULL, NULL, frontsector->c_slope, P_SectorGetCeilingPortal(frontsector));
|
||||
}
|
||||
else
|
||||
ceilingplane = NULL;
|
||||
|
@ -980,10 +971,10 @@ static void R_Subsector(size_t num)
|
|||
light = R_GetPlaneLight(frontsector, planecenterz,
|
||||
viewz < heightcheck);
|
||||
|
||||
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
|
||||
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->bottomheight, *rover->bottompic,
|
||||
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs,
|
||||
*rover->bottomxscale, *rover->bottomyscale, *rover->bottomangle,
|
||||
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope);
|
||||
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, NULL);
|
||||
|
||||
ffloor[numffloors].slope = *rover->b_slope;
|
||||
|
||||
|
@ -1010,10 +1001,10 @@ static void R_Subsector(size_t num)
|
|||
{
|
||||
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
|
||||
|
||||
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
|
||||
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->topheight, *rover->toppic,
|
||||
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs,
|
||||
*rover->topxscale, *rover->topyscale, *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;
|
||||
|
||||
|
@ -1053,18 +1044,17 @@ static void R_Subsector(size_t num)
|
|||
&& (viewz < polysec->floorheight))
|
||||
{
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic,
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec, polysec->floorheight, polysec->floorpic,
|
||||
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel),
|
||||
polysec->floorxoffset, polysec->flooryoffset,
|
||||
polysec->floorxscale, polysec->flooryscale,
|
||||
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++;
|
||||
}
|
||||
|
@ -1079,18 +1069,17 @@ static void R_Subsector(size_t num)
|
|||
&& (viewz > polysec->ceilingheight))
|
||||
{
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec, polysec->ceilingheight, polysec->ceilingpic,
|
||||
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel),
|
||||
polysec->ceilingxoffset, polysec->ceilingyoffset,
|
||||
polysec->ceilingxscale, polysec->ceilingyscale,
|
||||
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++;
|
||||
}
|
||||
|
@ -1099,18 +1088,18 @@ static void R_Subsector(size_t num)
|
|||
}
|
||||
}
|
||||
|
||||
// killough 9/18/98: Fix underwater slowdown, by passing real sector
|
||||
// instead of fake one. Improve sprite lighting by basing sprite
|
||||
// lightlevels on floor & ceiling lightlevels in the surrounding area.
|
||||
//
|
||||
// 10/98 killough:
|
||||
//
|
||||
// NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
|
||||
// That is part of the 242 effect!!! If you simply pass sub->sector to
|
||||
// the old code you will not get correct lighting for underwater sprites!!!
|
||||
// Either you must pass the fake sector and handle validcount here, on the
|
||||
// real sector, or you must account for the lighting in some other way,
|
||||
// like passing it as an argument.
|
||||
// killough 9/18/98: Fix underwater slowdown, by passing real sector
|
||||
// instead of fake one. Improve sprite lighting by basing sprite
|
||||
// lightlevels on floor & ceiling lightlevels in the surrounding area.
|
||||
//
|
||||
// 10/98 killough:
|
||||
//
|
||||
// NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
|
||||
// That is part of the 242 effect!!! If you simply pass sub->sector to
|
||||
// the old code you will not get correct lighting for underwater sprites!!!
|
||||
// Either you must pass the fake sector and handle validcount here, on the
|
||||
// real sector, or you must account for the lighting in some other way,
|
||||
// like passing it as an argument.
|
||||
R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2);
|
||||
|
||||
firstseg = NULL;
|
||||
|
@ -1121,7 +1110,6 @@ static void R_Subsector(size_t num)
|
|||
|
||||
while (count--)
|
||||
{
|
||||
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
|
||||
if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects
|
||||
R_AddLine(line);
|
||||
line++;
|
||||
|
@ -1129,6 +1117,51 @@ static void R_Subsector(size_t num)
|
|||
}
|
||||
}
|
||||
|
||||
void R_CheckSectorLightLists(sector_t *sector, sector_t *fakeflat, INT32 *floorlightlevel, INT32 *ceilinglightlevel, extracolormap_t **floorcolormap, extracolormap_t **ceilingcolormap)
|
||||
{
|
||||
// Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps.
|
||||
if (fakeflat->ffloors)
|
||||
{
|
||||
fixed_t floorcenterz = P_GetSectorFloorZAt (fakeflat, fakeflat->soundorg.x, fakeflat->soundorg.y);
|
||||
fixed_t ceilingcenterz = P_GetSectorCeilingZAt(fakeflat, fakeflat->soundorg.x, fakeflat->soundorg.y);
|
||||
|
||||
boolean anyMoved = fakeflat->moved;
|
||||
|
||||
if (anyMoved == false)
|
||||
{
|
||||
for (ffloor_t *rover = fakeflat->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *controlSec = §ors[rover->secnum];
|
||||
|
||||
if (controlSec->moved == true)
|
||||
{
|
||||
anyMoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (anyMoved == true)
|
||||
{
|
||||
fakeflat->numlights = sector->numlights = 0;
|
||||
R_Prep3DFloors(fakeflat);
|
||||
sector->lightlist = fakeflat->lightlist;
|
||||
sector->numlights = fakeflat->numlights;
|
||||
sector->moved = fakeflat->moved = false;
|
||||
}
|
||||
|
||||
INT32 light = R_GetPlaneLight(fakeflat, floorcenterz, false);
|
||||
if (fakeflat->floorlightsec == -1 && !fakeflat->floorlightabsolute)
|
||||
*floorlightlevel = max(0, min(255, *fakeflat->lightlist[light].lightlevel + fakeflat->floorlightlevel));
|
||||
*floorcolormap = *fakeflat->lightlist[light].extra_colormap;
|
||||
|
||||
light = R_GetPlaneLight(fakeflat, ceilingcenterz, false);
|
||||
if (fakeflat->ceilinglightsec == -1 && !fakeflat->ceilinglightabsolute)
|
||||
*ceilinglightlevel = max(0, min(255, *fakeflat->lightlist[light].lightlevel + fakeflat->ceilinglightlevel));
|
||||
*ceilingcolormap = *fakeflat->lightlist[light].extra_colormap;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_Prep3DFloors
|
||||
//
|
||||
|
@ -1314,3 +1347,59 @@ void R_RenderBSPNode(INT32 bspnum)
|
|||
|
||||
R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
|
||||
}
|
||||
|
||||
void R_RenderPortalHorizonLine(sector_t *sector)
|
||||
{
|
||||
INT32 floorlightlevel, ceilinglightlevel;
|
||||
static sector_t tempsec; // Deep water hack
|
||||
extracolormap_t *floorcolormap;
|
||||
extracolormap_t *ceilingcolormap;
|
||||
|
||||
frontsector = sector;
|
||||
backsector = NULL;
|
||||
|
||||
// Deep water/fake ceiling effect.
|
||||
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false);
|
||||
|
||||
floorcolormap = ceilingcolormap = frontsector->extra_colormap;
|
||||
|
||||
R_CheckSectorLightLists(sector, frontsector, &floorlightlevel, &ceilinglightlevel, &floorcolormap, &ceilingcolormap);
|
||||
|
||||
sector->extra_colormap = frontsector->extra_colormap;
|
||||
|
||||
if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz
|
||||
|| frontsector->floorpic == skyflatnum
|
||||
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
|
||||
{
|
||||
floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel,
|
||||
frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorxscale, frontsector->flooryscale,
|
||||
frontsector->floorangle, floorcolormap, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
floorplane = NULL;
|
||||
|
||||
if (P_GetSectorCeilingZAt(frontsector, viewx, viewy) > viewz
|
||||
|| frontsector->ceilingpic == skyflatnum
|
||||
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))
|
||||
{
|
||||
ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic,
|
||||
ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingxscale, frontsector->ceilingyscale,
|
||||
frontsector->ceilingyoffset, frontsector->ceilingangle,
|
||||
ceilingcolormap, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
ceilingplane = NULL;
|
||||
|
||||
numffloors = 0;
|
||||
portalline = false;
|
||||
doorclosed = 0;
|
||||
bothceilingssky = bothfloorssky = false;
|
||||
horizonline = true;
|
||||
|
||||
firstseg = NULL;
|
||||
curline = &segs[0];
|
||||
|
||||
R_ClipSolidWallSegment(portalclipstart, portalclipend);
|
||||
|
||||
curline = NULL;
|
||||
}
|
||||
|
|
10
src/r_bsp.h
10
src/r_bsp.h
|
@ -25,13 +25,17 @@ 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 boolean horizonline;
|
||||
|
||||
extern INT32 doorclosed;
|
||||
|
||||
// BSP?
|
||||
|
@ -39,6 +43,7 @@ void R_ClearClipSegs(void);
|
|||
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
||||
void R_ClearDrawSegs(void);
|
||||
void R_RenderBSPNode(INT32 bspnum);
|
||||
void R_RenderPortalHorizonLine(sector_t *sector);
|
||||
|
||||
void R_SortPolyObjects(subsector_t *sub);
|
||||
|
||||
|
@ -52,4 +57,5 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back);
|
|||
|
||||
INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside);
|
||||
void R_Prep3DFloors(sector_t *sector);
|
||||
void R_CheckSectorLightLists(sector_t *sector, sector_t *fakeflat, INT32 *floorlightlevel, INT32 *ceilinglightlevel, extracolormap_t **floorcolormap, extracolormap_t **ceilingcolormap);
|
||||
#endif
|
||||
|
|
38
src/r_defs.h
38
src/r_defs.h
|
@ -211,6 +211,34 @@ typedef enum
|
|||
BT_STRONG,
|
||||
} busttype_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SECPORTAL_LINE, // Works similar to a line portal
|
||||
SECPORTAL_SKYBOX, // Uses the skybox object as the reference view
|
||||
SECPORTAL_PLANE, // Eternity Engine's plane portal type
|
||||
SECPORTAL_HORIZON, // Eternity Engine's horizon portal type
|
||||
SECPORTAL_OBJECT, // Uses an object as the reference view
|
||||
SECPORTAL_FLOOR, // Uses a sector as the reference view; the view height is aligned with the sector's floor
|
||||
SECPORTAL_CEILING, // Uses a sector as the reference view; the view height is aligned with the sector's ceiling
|
||||
SECPORTAL_NONE = 0xFF
|
||||
} secportaltype_e;
|
||||
|
||||
typedef struct sectorportal_s
|
||||
{
|
||||
secportaltype_e type;
|
||||
union {
|
||||
struct {
|
||||
struct line_s *start;
|
||||
struct line_s *dest;
|
||||
} line;
|
||||
struct sector_s *sector;
|
||||
struct mobj_s *mobj;
|
||||
};
|
||||
struct {
|
||||
fixed_t x, y;
|
||||
} origin;
|
||||
} sectorportal_t;
|
||||
|
||||
typedef struct ffloor_s
|
||||
{
|
||||
fixed_t *topheight;
|
||||
|
@ -505,6 +533,10 @@ typedef struct sector_s
|
|||
|
||||
// colormap structure
|
||||
extracolormap_t *spawn_extra_colormap;
|
||||
|
||||
// portals
|
||||
UINT32 portal_floor;
|
||||
UINT32 portal_ceiling;
|
||||
} sector_t;
|
||||
|
||||
//
|
||||
|
@ -518,7 +550,9 @@ typedef enum
|
|||
ST_NEGATIVE
|
||||
} slopetype_t;
|
||||
|
||||
#define HORIZONSPECIAL 41
|
||||
#define SPECIAL_HORIZON_LINE 41
|
||||
|
||||
#define SPECIAL_SECTOR_SETPORTAL 6
|
||||
|
||||
#define NUMLINEARGS 10
|
||||
#define NUMLINESTRINGARGS 2
|
||||
|
@ -561,6 +595,8 @@ typedef struct line_s
|
|||
polyobj_t *polyobj; // Belongs to a polyobject?
|
||||
|
||||
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
|
||||
|
||||
UINT32 secportal; // transferred sector portal
|
||||
} line_t;
|
||||
|
||||
typedef struct
|
||||
|
|
23
src/r_main.c
23
src/r_main.c
|
@ -1534,9 +1534,8 @@ void R_RenderPlayerView(player_t *player)
|
|||
|
||||
ps_numsprites.value.i = numvisiblesprites;
|
||||
|
||||
// Add skybox portals caused by sky visplanes.
|
||||
if (cv_skybox.value && skyboxmo[0])
|
||||
Portal_AddSkyboxPortals();
|
||||
// Add portals caused by visplanes.
|
||||
Portal_AddPlanePortals(cv_skybox.value);
|
||||
|
||||
// Portal rendering. Hijacks the BSP traversal.
|
||||
PS_START_TIMING(ps_sw_portaltime);
|
||||
|
@ -1569,9 +1568,21 @@ void R_RenderPlayerView(player_t *player)
|
|||
Mask_Pre(&masks[nummasks - 1]);
|
||||
curdrawsegs = ds_p;
|
||||
|
||||
// Render the BSP from the new viewpoint, and clip
|
||||
// any sprites with the new clipsegs and window.
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
if (portal->is_horizon)
|
||||
{
|
||||
// If the portal is a plane or a horizon portal, then we just render a horizon line
|
||||
R_RenderPortalHorizonLine(portal->horizon_sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Render the BSP from the new viewpoint, and clip
|
||||
// any sprites with the new clipsegs and window.
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
}
|
||||
|
||||
// Don't add skybox portals while already rendering a skybox view, because that'll cause an infinite loop
|
||||
Portal_AddPlanePortals(cv_skybox.value && !portal->is_skybox);
|
||||
|
||||
Mask_Post(&masks[nummasks - 1]);
|
||||
|
||||
R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal);
|
||||
|
|
|
@ -368,10 +368,10 @@ static visplane_t *new_visplane(unsigned hash)
|
|||
// Same height, same flattexture, same lightlevel.
|
||||
// If not, allocates another of them.
|
||||
//
|
||||
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||
visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||
fixed_t xoff, fixed_t yoff, fixed_t xscale, fixed_t yscale,
|
||||
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;
|
||||
|
@ -430,7 +430,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
|||
&& check->viewangle == viewangle
|
||||
&& check->plangle == plangle
|
||||
&& check->slope == slope
|
||||
&& check->polyobj == polyobj)
|
||||
&& check->polyobj == polyobj
|
||||
&& P_CompareSectorPortals(check->portalsector, portalsector))
|
||||
{
|
||||
return check;
|
||||
}
|
||||
|
@ -459,6 +460,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
|||
check->viewz = viewz;
|
||||
check->viewangle = viewangle;
|
||||
check->plangle = plangle;
|
||||
check->sector = sector;
|
||||
check->portalsector = portalsector;
|
||||
check->polyobj = polyobj;
|
||||
check->slope = slope;
|
||||
|
||||
|
@ -537,8 +540,10 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
|
|||
new_pl->viewz = pl->viewz;
|
||||
new_pl->viewangle = pl->viewangle;
|
||||
new_pl->plangle = pl->plangle;
|
||||
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;
|
||||
|
|
|
@ -51,9 +51,11 @@ typedef struct visplane_s
|
|||
fixed_t xoffs, yoffs; // Scrolling flats.
|
||||
fixed_t xscale, yscale;
|
||||
|
||||
sector_t *sector;
|
||||
struct ffloor_s *ffloor;
|
||||
polyobj_t *polyobj;
|
||||
pslope_t *slope;
|
||||
sectorportal_t *portalsector;
|
||||
} visplane_t;
|
||||
|
||||
extern visplane_t *visplanes[MAXVISPLANES];
|
||||
|
@ -71,8 +73,9 @@ void R_ClearPlanes(void);
|
|||
void R_ClearFFloorClips (void);
|
||||
|
||||
void R_DrawPlanes(void);
|
||||
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, fixed_t xscale, fixed_t yscale,
|
||||
angle_t plangle, extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope);
|
||||
visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||
fixed_t xoff, fixed_t yoff, fixed_t xscale, fixed_t yscale, angle_t plangle,
|
||||
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);
|
||||
|
|
252
src/r_portal.c
252
src/r_portal.c
|
@ -16,6 +16,8 @@
|
|||
#include "r_main.h"
|
||||
#include "doomstat.h"
|
||||
#include "p_spec.h" // Skybox viewpoints
|
||||
#include "p_slopes.h" // P_GetSectorFloorZAt and P_GetSectorCeilingZAt
|
||||
#include "p_local.h"
|
||||
#include "z_zone.h"
|
||||
#include "r_things.h"
|
||||
#include "r_sky.h"
|
||||
|
@ -140,30 +142,17 @@ void Portal_Remove (portal_t* portal)
|
|||
Z_Free(portal);
|
||||
}
|
||||
|
||||
/** Creates a portal out of two lines and a determined screen range.
|
||||
*
|
||||
* line1 determines the entrance, and line2 the exit.
|
||||
* x1 and x2 determine the screen's column bounds.
|
||||
|
||||
* The view's offset from the entry line center is obtained,
|
||||
* and then rotated&translated to the exit line's center.
|
||||
* When the portal renders, it will create the illusion of
|
||||
* the two lines being seamed together.
|
||||
*/
|
||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
||||
static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t *dest)
|
||||
{
|
||||
portal_t* portal = Portal_Add(x1, x2);
|
||||
|
||||
// Offset the portal view by the linedef centers
|
||||
line_t* start = &lines[line1];
|
||||
line_t* dest = &lines[line2];
|
||||
|
||||
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
|
||||
|
||||
fixed_t disttopoint;
|
||||
angle_t angtopoint;
|
||||
|
||||
vertex_t dest_c, start_c;
|
||||
struct {
|
||||
fixed_t x, y;
|
||||
} dest_c, start_c;
|
||||
|
||||
// looking glass center
|
||||
start_c.x = (start->v1->x + start->v2->x) / 2;
|
||||
|
@ -181,8 +170,31 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con
|
|||
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||
portal->viewangle = viewangle + dangle;
|
||||
}
|
||||
|
||||
/** Creates a portal out of two lines and a determined screen range.
|
||||
*
|
||||
* line1 determines the entrance, and line2 the exit.
|
||||
* x1 and x2 determine the screen's column bounds.
|
||||
|
||||
* The view's offset from the entry line center is obtained,
|
||||
* and then rotated&translated to the exit line's center.
|
||||
* When the portal renders, it will create the illusion of
|
||||
* the two lines being seamed together.
|
||||
*/
|
||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
||||
{
|
||||
portal_t* portal = Portal_Add(x1, x2);
|
||||
|
||||
line_t* start = &lines[line1];
|
||||
line_t* dest = &lines[line2];
|
||||
|
||||
Portal_GetViewpointForLine(portal, start, dest);
|
||||
|
||||
portal->clipline = line2;
|
||||
portal->is_skybox = false;
|
||||
portal->is_horizon = false;
|
||||
portal->horizon_sector = NULL;
|
||||
|
||||
Portal_ClipRange(portal);
|
||||
|
||||
|
@ -252,30 +264,14 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Creates a skybox portal out of a visplane.
|
||||
*
|
||||
* Applies the necessary offsets and rotation to give
|
||||
* a depth illusion to the skybox.
|
||||
*/
|
||||
void Portal_AddSkybox (const visplane_t* plane)
|
||||
static void Portal_GetViewpointForSkybox(portal_t *portal)
|
||||
{
|
||||
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->viewy = skyboxmo[0]->y;
|
||||
portal->viewz = skyboxmo[0]->z;
|
||||
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 (skyboxmo[1])
|
||||
|
@ -302,34 +298,192 @@ void Portal_AddSkybox (const visplane_t* plane)
|
|||
portal->viewz += viewz / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
portal->viewz += viewz * -mh->skybox_scalez;
|
||||
|
||||
portal->clipline = -1;
|
||||
}
|
||||
|
||||
/** Creates portals for the currently existing sky visplanes.
|
||||
/** Creates a skybox portal out of a visplane.
|
||||
*
|
||||
* Applies the necessary offsets and rotation to give
|
||||
* a depth illusion to the skybox.
|
||||
*/
|
||||
static boolean Portal_AddSkybox (const visplane_t* plane)
|
||||
{
|
||||
INT16 start, end;
|
||||
portal_t* portal;
|
||||
|
||||
if (TrimVisplaneBounds(plane, &start, &end))
|
||||
return false;
|
||||
|
||||
portal = Portal_Add(start, end);
|
||||
|
||||
Portal_ClipVisplane(plane, portal);
|
||||
|
||||
portal->clipline = -1;
|
||||
portal->is_skybox = true;
|
||||
portal->is_horizon = false;
|
||||
portal->horizon_sector = NULL;
|
||||
|
||||
Portal_GetViewpointForSkybox(portal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *secportal)
|
||||
{
|
||||
fixed_t x, y, z;
|
||||
angle_t angle;
|
||||
|
||||
switch (secportal->type)
|
||||
{
|
||||
case SECPORTAL_LINE:
|
||||
Portal_GetViewpointForLine(portal, secportal->line.start, secportal->line.dest);
|
||||
return;
|
||||
case SECPORTAL_OBJECT:
|
||||
if (!secportal->mobj || P_MobjWasRemoved(secportal->mobj))
|
||||
return;
|
||||
x = secportal->mobj->x;
|
||||
y = secportal->mobj->y;
|
||||
z = secportal->mobj->z;
|
||||
angle = secportal->mobj->angle;
|
||||
break;
|
||||
case SECPORTAL_FLOOR:
|
||||
x = secportal->sector->soundorg.x;
|
||||
y = secportal->sector->soundorg.y;
|
||||
z = P_GetSectorFloorZAt(secportal->sector, x, y);
|
||||
angle = 0;
|
||||
break;
|
||||
case SECPORTAL_CEILING:
|
||||
x = secportal->sector->soundorg.x;
|
||||
y = secportal->sector->soundorg.y;
|
||||
z = P_GetSectorCeilingZAt(secportal->sector, x, y);
|
||||
angle = 0;
|
||||
break;
|
||||
case SECPORTAL_PLANE:
|
||||
case SECPORTAL_HORIZON:
|
||||
portal->is_horizon = true;
|
||||
portal->horizon_sector = secportal->sector;
|
||||
x = secportal->sector->soundorg.x;
|
||||
y = secportal->sector->soundorg.y;
|
||||
if (secportal->type == SECPORTAL_PLANE)
|
||||
z = -viewz;
|
||||
else
|
||||
z = 0;
|
||||
angle = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
fixed_t refx = secportal->origin.x - viewx;
|
||||
fixed_t refy = secportal->origin.y - viewy;
|
||||
|
||||
// Rotate the X/Y to match the target angle
|
||||
if (angle != 0)
|
||||
{
|
||||
fixed_t tr_x = refx, tr_y = refy;
|
||||
angle_t ang = angle >> ANGLETOFINESHIFT;
|
||||
refx = FixedMul(tr_x, FINECOSINE(ang)) - FixedMul(tr_y, FINESINE(ang));
|
||||
refy = FixedMul(tr_x, FINESINE(ang)) + FixedMul(tr_y, FINECOSINE(ang));
|
||||
}
|
||||
|
||||
portal->viewx = x - refx;
|
||||
portal->viewy = y - refy;
|
||||
portal->viewz = z + viewz;
|
||||
portal->viewangle = angle + viewangle;
|
||||
}
|
||||
|
||||
/** Creates a sector portal out of a visplane.
|
||||
*/
|
||||
static boolean Portal_AddSectorPortal (const visplane_t* plane)
|
||||
{
|
||||
INT16 start, end;
|
||||
sectorportal_t *secportal = plane->portalsector;
|
||||
|
||||
// Shortcut
|
||||
if (secportal->type == SECPORTAL_SKYBOX)
|
||||
{
|
||||
if (cv_skybox.value && skyboxmo[0])
|
||||
return Portal_AddSkybox(plane);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TrimVisplaneBounds(plane, &start, &end))
|
||||
return false;
|
||||
|
||||
portal_t* portal = Portal_Add(start, end);
|
||||
|
||||
Portal_ClipVisplane(plane, portal);
|
||||
|
||||
portal->clipline = -1;
|
||||
portal->is_horizon = false;
|
||||
portal->is_skybox = false;
|
||||
portal->horizon_sector = NULL;
|
||||
|
||||
Portal_GetViewpointForSecPortal(portal, secportal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Creates a transferred sector portal.
|
||||
*/
|
||||
void Portal_AddTransferred (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_skybox = false;
|
||||
portal->is_horizon = false;
|
||||
portal->horizon_sector = NULL;
|
||||
|
||||
if (secportal->type == SECPORTAL_SKYBOX)
|
||||
Portal_GetViewpointForSkybox(portal);
|
||||
else
|
||||
Portal_GetViewpointForSecPortal(portal, secportal);
|
||||
|
||||
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 portal visplanes.
|
||||
* The visplanes are also removed and cleared from the list.
|
||||
*/
|
||||
void Portal_AddSkyboxPortals (void)
|
||||
void Portal_AddPlanePortals (boolean add_skyboxes)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
Portal_AddSkybox(pl);
|
||||
if (pl->minx >= pl->maxx)
|
||||
continue;
|
||||
|
||||
boolean added_portal = false;
|
||||
|
||||
// Render sector portal if recursiveness limit hasn't been reached
|
||||
if (pl->portalsector && portalrender < cv_maxportals.value)
|
||||
added_portal = Portal_AddSectorPortal(pl);
|
||||
|
||||
// Render skybox portal
|
||||
if (!added_portal && pl->picnum == skyflatnum && add_skyboxes && skyboxmo[0])
|
||||
added_portal = Portal_AddSkybox(pl);
|
||||
|
||||
// don't render this visplane anymore
|
||||
if (added_portal)
|
||||
{
|
||||
pl->minx = 0;
|
||||
pl->maxx = -1;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CONS_Debug(DBG_RENDER, "Skybox portals: %d\n", count);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,12 @@ typedef struct portal_s
|
|||
fixed_t viewz;
|
||||
angle_t viewangle;
|
||||
|
||||
// For horizon portals
|
||||
boolean is_horizon;
|
||||
sector_t *horizon_sector;
|
||||
|
||||
boolean is_skybox;
|
||||
|
||||
UINT8 pass; /**< Keeps track of the portal's recursion depth. */
|
||||
INT32 clipline; /**< Optional clipline for line-based portals. */
|
||||
|
||||
|
@ -49,13 +55,13 @@ extern line_t *portalclipline;
|
|||
extern sector_t *portalcullsector;
|
||||
extern INT32 portalclipstart, portalclipend;
|
||||
|
||||
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_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_AddTransferred (UINT32 secportalnum, const INT32 x1, const INT32 x2);
|
||||
|
||||
void Portal_ClipRange (portal_t* portal);
|
||||
void Portal_ClipApply (const portal_t* portal);
|
||||
|
||||
void Portal_AddSkyboxPortals (void);
|
||||
void Portal_AddPlanePortals (boolean add_skyboxes);
|
||||
#endif
|
||||
|
|
26
src/r_segs.c
26
src/r_segs.c
|
@ -1867,9 +1867,6 @@ 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
|
||||
|
||||
SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight)
|
||||
SLOPEPARAMS(backsector->f_slope, worldlow, worldlowslope, backsector->floorheight)
|
||||
worldhigh -= viewz;
|
||||
|
@ -1877,21 +1874,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;
|
||||
|
||||
|
@ -1991,6 +1973,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(P_SectorGetFloorPortal(frontsector), P_SectorGetFloorPortal(backsector))
|
||||
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
|
||||
{
|
||||
markfloor = true;
|
||||
|
@ -2026,9 +2009,10 @@ 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(P_SectorGetCeilingPortal(frontsector), P_SectorGetCeilingPortal(backsector))
|
||||
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
|
||||
{
|
||||
markceiling = true;
|
||||
markceiling = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2478,7 +2462,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
worldtopslope >>= 4;
|
||||
worldbottomslope >>= 4;
|
||||
|
||||
if (linedef->special == HORIZONSPECIAL) { // HORIZON LINES
|
||||
if (horizonline) { // HORIZON LINES
|
||||
topstep = bottomstep = 0;
|
||||
topfrac = bottomfrac = (centeryfrac>>4);
|
||||
topfrac++; // Prevent 1px HOM
|
||||
|
@ -2579,7 +2563,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
{
|
||||
ffloor[i].f_pos >>= 4;
|
||||
ffloor[i].f_pos_slope >>= 4;
|
||||
if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too.
|
||||
if (horizonline) // Horizon lines extend FOFs in contact with them too.
|
||||
{
|
||||
ffloor[i].f_step = 0;
|
||||
ffloor[i].f_frac = (centeryfrac>>4);
|
||||
|
|
Loading…
Reference in a new issue