Serialize sector portals

This commit is contained in:
Lactozilla 2023-08-24 16:04:31 -03:00
parent 6303e37fbe
commit ff5d53e54d
7 changed files with 178 additions and 130 deletions

View file

@ -2927,64 +2927,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 = &sectors[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;

View file

@ -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,20 +852,22 @@ 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
#define SD_DAMAGETYPE 0x01
#define SD_TRIGGERTAG 0x02
#define SD_TRIGGERER 0x04
#define SD_GRAVITY 0x08
#define SD_DAMAGETYPE 0x01
#define SD_TRIGGERTAG 0x02
#define SD_TRIGGERER 0x04
#define SD_GRAVITY 0x08
#define SD_FLOORPORTAL 0x10
#define SD_CEILPORTAL 0x20
#define LD_FLAG 0x01
#define LD_SPECIAL 0x02
@ -1064,6 +1065,10 @@ static void ArchiveSectors(void)
diff4 |= SD_TRIGGERER;
if (ss->gravity != spawnss->gravity)
diff4 |= SD_GRAVITY;
if (ss->portal_floor != spawnss->portal_floor)
diff4 |= SD_FLOORPORTAL;
if (ss->portal_ceiling != spawnss->portal_ceiling)
diff4 |= SD_CEILPORTAL;
if (ss->ffloors && CheckFFloorDiff(ss))
diff |= SD_FFLOORS;
@ -1145,6 +1150,10 @@ static void ArchiveSectors(void)
WRITEUINT8(save_p, ss->triggerer);
if (diff4 & SD_GRAVITY)
WRITEFIXED(save_p, ss->gravity);
if (diff4 & SD_FLOORPORTAL)
WRITEUINT32(save_p, ss->portal_floor);
if (diff4 & SD_CEILPORTAL)
WRITEUINT32(save_p, ss->portal_ceiling);
if (diff & SD_FFLOORS)
ArchiveFFloors(ss);
}
@ -1265,6 +1274,10 @@ static void UnArchiveSectors(void)
sectors[i].triggerer = READUINT8(save_p);
if (diff4 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p);
if (diff4 & SD_FLOORPORTAL)
sectors[i].portal_floor = READUINT32(save_p);
if (diff4 & SD_CEILPORTAL)
sectors[i].portal_ceiling = READUINT32(save_p);
if (diff & SD_FFLOORS)
UnArchiveFFloors(&sectors[i]);
@ -4735,6 +4748,82 @@ 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);
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);
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;
@ -4821,6 +4910,7 @@ void P_SaveNetGame(boolean resending)
P_NetArchiveSpecials();
P_NetArchiveColormaps();
P_NetArchiveWaypoints();
P_NetArchiveSectorPortals();
}
LUA_Archive();
@ -4861,6 +4951,7 @@ boolean P_LoadNetGame(boolean reloading)
P_NetUnArchiveSpecials();
P_NetUnArchiveColormaps();
P_NetUnArchiveWaypoints();
P_NetUnArchiveSectorPortals();
P_RelinkPointers();
P_FinishMobjs();
}

View file

@ -6209,6 +6209,8 @@ UINT32 P_NewSectorPortal(void)
secportals = Z_Realloc(secportals, secportalcapacity * sizeof(sectorportal_t), PU_LEVEL, NULL);
}
secportals[i].type = SECPORTAL_NONE;
return (UINT32)i;
}
@ -6536,11 +6538,13 @@ void P_SpawnSpecials(boolean fromnetsave)
{
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(lines[i].frontsector);
floorportal->type = type;
floorportal->sector = lines[i].frontsector;
}
if (ceiling)
{
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(lines[i].frontsector);
ceilportal->type = type;
ceilportal->sector = lines[i].frontsector;
}
break;
}

View file

@ -847,51 +847,6 @@ static void R_AddPolyObjects(subsector_t *sub)
drawseg_t *firstseg;
static 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 = &sectors[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;
}
}
static void R_Subsector(size_t num)
{
INT32 count, floorlightlevel, ceilinglightlevel, light;
@ -1098,18 +1053,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;
@ -1120,7 +1075,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++;
@ -1128,6 +1082,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 = &sectors[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
//

View file

@ -57,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

View file

@ -216,7 +216,8 @@ typedef enum
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_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

View file

@ -373,7 +373,7 @@ void Portal_AddSectorPortal (const visplane_t* plane)
case SECPORTAL_PLANE:
case SECPORTAL_HORIZON:
portal->is_horizon = true;
portal->horizon_sector = plane->sector;
portal->horizon_sector = secportal->sector;
x = plane->sector->soundorg.x;
y = plane->sector->soundorg.y;
if (secportal->type == SECPORTAL_PLANE)