diff --git a/src/p_mobj.c b/src/p_mobj.c index f7ad7616d..de2c3a72c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12822,28 +12822,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean skyboxviewpnts[tag] = mobj; break; } - case MT_PORTALREFPOINT: - { - size_t i; - for (i = 0; i < numsectors; i++) - { - sector_t *targetsec = §ors[i]; - for (int j = 0; j < targetsec->tags.count; j++) - { - if ((mthing->extrainfo == targetsec->tags.tags[j]) && (GETSECSPECIAL(targetsec->special, 3) == 1)) - { - // origin - if (targetsec == mobj->subsector->sector) - targetsec->portals[1] = mobj; - // target - else - targetsec->portals[0] = mobj; - break; - } - } - } - } - break; case MT_EGGSTATUE: if (mthing->args[1]) { diff --git a/src/p_setup.c b/src/p_setup.c index 51c14e147..c590bba4f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -978,6 +978,13 @@ static void P_LoadVertices(UINT8 *data) } } +static void InitializeSectorPortal(sectorportal_t *secportal) +{ + secportal->target = NULL; + secportal->viewpoint.x = secportal->viewpoint.y = secportal->viewpoint.z = 0; + secportal->viewpoint.angle = 0; +} + static void P_InitializeSector(sector_t *ss) { memset(&ss->soundorg, 0, sizeof(ss->soundorg)); @@ -989,10 +996,11 @@ static void P_InitializeSector(sector_t *ss) ss->floordata = NULL; ss->ceilingdata = NULL; ss->lightingdata = NULL; - ss->portals[0] = NULL; - ss->portals[1] = NULL; ss->fadecolormapdata = NULL; + InitializeSectorPortal(&ss->portal_plane_floor); + InitializeSectorPortal(&ss->portal_plane_ceiling); + ss->heightsec = -1; ss->camsec = -1; diff --git a/src/p_spec.c b/src/p_spec.c index 28ecc60f4..4c34aaf05 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6186,6 +6186,38 @@ fixed_t P_GetSectorGravityFactor(sector_t *sec) return sec->gravity; } +static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector, INT32 viewpoint_tag) +{ + secportal->target = target_sector; + secportal->viewpoint.x = target_sector->soundorg.x; + secportal->viewpoint.y = target_sector->soundorg.y; + secportal->viewpoint.z = target_sector->ceilingheight; + secportal->viewpoint.angle = 0; + + if (viewpoint_tag <= 0) + return; + + for (thinker_t *th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mobj_t *mo = (mobj_t *)th; + + if (mo->type != MT_PORTALREFPOINT || mo->spawnpoint == NULL) + continue; + + if (!Tag_Find(&mo->spawnpoint->tags, viewpoint_tag)) + continue; + + secportal->viewpoint.x = mo->x; + secportal->viewpoint.y = mo->y; + secportal->viewpoint.z = mo->z; + secportal->viewpoint.angle = mo->angle; + return; + } +} + /** After the map has loaded, scans for specials that spawn 3Dfloors and * thinkers. * @@ -6351,6 +6383,33 @@ 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 6: // Sector portal + { + INT32 s1, s2; + TAG_ITER_SECTORS(lines[i].args[0], s1) // Target sector tag + { + TAG_ITER_SECTORS(lines[i].args[1], s2) // Sector tag to make a portal to + { + sector_t *target_sector = §ors[s2]; + boolean floor, ceiling; + + if (lines[i].args[2] == TMP_BOTH) + floor = ceiling = true; + else + { + floor = lines[i].args[2] == TMP_FLOOR; + ceiling = lines[i].args[2] == TMP_CEILING; + } + + if (floor) + SetSectorPortal(§ors[s1].portal_plane_floor, target_sector, lines[i].args[3]); + if (ceiling) + SetSectorPortal(§ors[s1].portal_plane_ceiling, target_sector, lines[i].args[3]); + } + } + break; + } + case 7: // Flat alignment - redone by toast { // Set calculated offsets such that line's v1 is the apparent origin diff --git a/src/r_bsp.c b/src/r_bsp.c index 70a9dbd94..5c9aa3ff9 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -909,7 +909,7 @@ static void R_Subsector(size_t num) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope); + frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope, frontsector->portal_plane_floor.target != NULL ? &frontsector->portal_plane_floor : NULL); } else floorplane = NULL; @@ -920,7 +920,7 @@ static void R_Subsector(size_t num) { ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle, - ceilingcolormap, NULL, NULL, frontsector->c_slope); + ceilingcolormap, NULL, NULL, frontsector->c_slope, frontsector->portal_plane_ceiling.target != NULL ? &frontsector->portal_plane_ceiling : NULL); } else ceilingplane = NULL; @@ -963,7 +963,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope); + *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, NULL); ffloor[numffloors].slope = *rover->b_slope; @@ -992,7 +992,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *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; @@ -1036,12 +1036,11 @@ static void R_Subsector(size_t num) (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floorxoffset, polysec->flooryoffset, 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++; } @@ -1059,12 +1058,11 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(polysec, polysec->ceilingheight, polysec->ceilingpic, (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceilingxoffset, polysec->ceilingyoffset, 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++; } diff --git a/src/r_defs.h b/src/r_defs.h index 61f9eaa4e..d9fe6193d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -208,6 +208,15 @@ typedef enum BT_STRONG, } busttype_e; +typedef struct sectorportal_s +{ + struct sector_s *target; + struct { + fixed_t x, y, z; + angle_t angle; + } viewpoint; +} sectorportal_t; + typedef struct ffloor_s { fixed_t *topheight; @@ -495,8 +504,9 @@ typedef struct sector_s // colormap structure extracolormap_t *spawn_extra_colormap; - // floor portals - mobj_t *portals[2]; + // portals + sectorportal_t portal_plane_floor; + sectorportal_t portal_plane_ceiling; } sector_t; // diff --git a/src/r_plane.c b/src/r_plane.c index a24ea9d28..5cd791023 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -392,7 +392,7 @@ static visplane_t *new_visplane(unsigned hash) // visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, 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; @@ -451,7 +451,8 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz && check->viewangle == viewangle && check->plangle == plangle - && check->slope == slope) + && check->slope == slope + && check->portalsector == portalsector) { return check; } @@ -479,6 +480,7 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li check->viewangle = viewangle; check->plangle = plangle; check->sector = sector; + check->portalsector = portalsector; check->polyobj = polyobj; check->slope = slope; @@ -558,6 +560,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) 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; diff --git a/src/r_plane.h b/src/r_plane.h index a3ae84f65..e33267798 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -54,6 +54,7 @@ typedef struct visplane_s struct ffloor_s *ffloor; polyobj_t *polyobj; pslope_t *slope; + sectorportal_t *portalsector; } visplane_t; extern visplane_t *visplanes[MAXVISPLANES]; @@ -77,7 +78,7 @@ void R_ClearFFloorClips (void); void R_DrawPlanes(void); visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); + 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); diff --git a/src/r_portal.c b/src/r_portal.c index 1a2b905f9..b4328a56e 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -309,41 +309,38 @@ void Portal_AddSkybox (const visplane_t* plane) portal->clipline = -1; } -/** Creates a floor portal out of a visplane. +/** Creates a sector portal out of a visplane. * * Mostly the same as Portal_AddSkybox. */ -void Portal_AddFloorPortal (const visplane_t* plane) +void Portal_AddSectorPortal (const visplane_t* plane) { INT16 start, end; - portal_t* portal; - sector_t *portalsector = plane->sector; - mobj_t *portalmobj = portalsector->portals[0]; - mobj_t *refmobj = portalsector->portals[1]; - fixed_t refx, refy; + sector_t *source = plane->sector; + sectorportal_t *target = plane->portalsector; if (TrimVisplaneBounds(plane, &start, &end)) return; - portal = Portal_Add(start, end); + portal_t* portal = Portal_Add(start, end); Portal_ClipVisplane(plane, portal); - if ((refmobj != NULL) && !(P_MobjWasRemoved(refmobj))) + fixed_t refx = source->soundorg.x - viewx; + fixed_t refy = source->soundorg.y - viewy; + + if (target->viewpoint.angle) { - refx = (refmobj->x - viewx); - refy = (refmobj->y - viewy); - } - else - { - refx = (portalsector->soundorg.x - viewx); - refy = (portalsector->soundorg.y - viewy); + fixed_t x = refx, y = refy; + angle_t ang = target->viewpoint.angle >> ANGLETOFINESHIFT; + refx = FixedMul(x, FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); + refy = FixedMul(x, FINESINE(ang)) + FixedMul(y, FINECOSINE(ang)); } - portal->viewx = portalmobj->x - refx; - portal->viewy = portalmobj->y - refy; - portal->viewz = portalmobj->z + viewz; - portal->viewangle = viewangle + portalmobj->angle; + portal->viewx = target->viewpoint.x - refx; + portal->viewy = target->viewpoint.y - refy; + portal->viewz = target->viewpoint.z + viewz; + portal->viewangle = target->viewpoint.angle + viewangle; portal->clipline = -1; } @@ -354,16 +351,12 @@ void Portal_AddFloorPortal (const visplane_t* plane) void Portal_AddSkyboxPortals (void) { 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) { - // true if added a portal for this visplane - boolean addedportal = false; - boolean floorportalpresent = (pl->sector->portals[0] != NULL && !P_MobjWasRemoved(pl->sector->portals[0])); + boolean added_portal = false; // skybox portal if (pl->picnum == skyflatnum) @@ -371,29 +364,24 @@ void Portal_AddSkyboxPortals (void) if (cv_skybox.value && skyboxmo[0]) { Portal_AddSkybox(pl); - addedportal = true; + added_portal = true; } } + // floor portal - else if (floorportalpresent) + if (pl->portalsector && pl->portalsector->target && floorportalrender < cv_maxportals.value) { - if (floorportalrender < cv_maxportals.value) - { - Portal_AddFloorPortal(pl); - floorportalrender++; - addedportal = true; - } + Portal_AddSectorPortal(pl); + floorportalrender++; + added_portal = true; } // don't render this visplane anymore - if (addedportal) + if (added_portal) { pl->minx = 0; pl->maxx = -1; - count++; } } } - - CONS_Debug(DBG_RENDER, "Skybox portals: %d\n", count); } diff --git a/src/r_portal.h b/src/r_portal.h index 14b49f289..6e2a6dedb 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -54,7 +54,7 @@ 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_AddFloorPortal (const visplane_t* plane); +void Portal_AddSectorPortal (const visplane_t* plane); void Portal_ClipRange (portal_t* portal); void Portal_ClipApply (const portal_t* portal);