From ff5d53e54d309aef952543ab1c1d2b0e593b3d74 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 24 Aug 2023 16:04:31 -0300 Subject: [PATCH] Serialize sector portals --- src/hardware/hw_main.c | 52 +--------------- src/p_saveg.c | 131 ++++++++++++++++++++++++++++++++++------- src/p_spec.c | 4 ++ src/r_bsp.c | 115 ++++++++++++++++++------------------ src/r_bsp.h | 1 + src/r_defs.h | 3 +- src/r_portal.c | 2 +- 7 files changed, 178 insertions(+), 130 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 30f9c4073..5b8f1178d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -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 = §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; diff --git a/src/p_saveg.c b/src/p_saveg.c index faecd1377..b3ac59e81 100644 --- a/src/p_saveg.c +++ b/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,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(§ors[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(); } diff --git a/src/p_spec.c b/src/p_spec.c index e76968b8a..d6b7b18b6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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; } diff --git a/src/r_bsp.c b/src/r_bsp.c index 0486cd699..91b4fdbc0 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -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 = §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; - } -} - 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 = §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 // diff --git a/src/r_bsp.h b/src/r_bsp.h index 3effb916a..44ddd0b1b 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -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 diff --git a/src/r_defs.h b/src/r_defs.h index dee15975f..b6ea8d6e5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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 diff --git a/src/r_portal.c b/src/r_portal.c index e4af45f9f..327821b9d 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -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)