From 9d877f75e3380a0ccf9ea45f7c1f8bcd5a781f9c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 8 Mar 2016 14:35:36 +0100 Subject: [PATCH 1/3] - second part of last commit. This file was accidentally unselected. --- src/d_iwad.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 68020dcec5..1fc63e03d3 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -381,13 +381,15 @@ int FIWadManager::CheckIWAD (const char *doomwaddir, WadStuff *wads) // //========================================================================== +static bool havepicked = false; + int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, const char *zdoom_wad) { TArray wads; TArray foundwads; const char *iwadparm = Args->CheckValue ("-iwad"); - size_t numwads; int pickwad; + size_t numwads; size_t i; bool iwadparmfound = false; FString custwad; @@ -536,26 +538,29 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, { for (i = 0; i < numwads; ++i) { - FString basename = ExtractFileBase (wads[i].Path); - if (stricmp (basename, defaultiwad) == 0) + FString basename = ExtractFileBase(wads[i].Path); + if (stricmp(basename, defaultiwad) == 0) { defiwad = (int)i; break; } } } - pickwad = I_PickIWad (&wads[0], (int)numwads, queryiwad, defiwad); - if (pickwad >= 0) + if (!havepicked) // just use the first IWAD if the restart doesn't have a -iwad parameter. We cannot open the picker in fullscreen mode. { - // The newly selected IWAD becomes the new default - FString basename = ExtractFileBase (wads[pickwad].Path); - defaultiwad = basename; + pickwad = I_PickIWad(&wads[0], (int)numwads, queryiwad, defiwad); + if (pickwad >= 0) + { + // The newly selected IWAD becomes the new default + FString basename = ExtractFileBase(wads[pickwad].Path); + defaultiwad = basename; + } + if (pickwad < 0) + exit(0); + havepicked = true; } } - if (pickwad < 0) - exit (0); - // zdoom.pk3 must always be the first file loaded and the IWAD second. wadfiles.Clear(); D_AddFile (wadfiles, zdoom_wad); From 899389e6a4ea3ef0d351be98c303a520928dbb07 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 8 Mar 2016 14:41:37 +0100 Subject: [PATCH 2/3] - link actors into blockmap through linked line portals. Links through sector portals are not done because nearly all the checks can be performed without doing this so if it works without there's no need to add more processing time. Will have to see if there's cases left where such a link is needed and if so, whether there's better options to do it. For line portals such links are necessary to have proper collision detection with actors that are currently transitioning the portal. --- src/actor.h | 2 +- src/p_map.cpp | 2 +- src/p_maputl.cpp | 85 +++++++++++++++++-------------- src/p_mobj.cpp | 2 +- src/portal.cpp | 22 +++++++- src/thingdef/thingdef_codeptr.cpp | 4 +- 6 files changed, 71 insertions(+), 46 deletions(-) diff --git a/src/actor.h b/src/actor.h index 6ff2a6576a..d91299ce37 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1167,7 +1167,7 @@ private: bool FixMapthingPos(); public: - void LinkToWorld (bool spawningmapthing=false, FPortalGroupArray *groups = NULL, sector_t *sector = NULL); + void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL); void UnlinkFromWorld (); void AdjustFloorClip (); void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false); diff --git a/src/p_map.cpp b/src/p_map.cpp index e3ab370d00..8174d8e772 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -5250,7 +5250,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo double bombdistancefloat = 1.f / (double)(bombdistance - fulldamagedistance); double bombdamagefloat = (double)bombdamage; - FPortalGroupArray grouplist; + FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistfix, bombspot->height + bombdistfix*2, bombdistfix); FMultiBlockThingsIterator::CheckResult cres; diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 20fe996a55..b9d682e6e1 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -435,7 +435,7 @@ bool AActor::FixMapthingPos() // //========================================================================== -void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sector_t *sector) +void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) { if (spawningmapthing && (flags4 & MF4_FIXMAPTHINGPOS) && sector == NULL) { @@ -457,7 +457,7 @@ void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sect Sector = sector; subsector = R_PointInSubsector(X(), Y()); // this is from the rendering nodes, not the gameplay nodes! - if ( !(flags & MF_NOSECTOR) ) + if (!(flags & MF_NOSECTOR)) { // invisible things don't go into the sector links // killough 8/11/98: simpler scheme using pointer-to-pointer prev @@ -482,51 +482,60 @@ void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sect // When a node is deleted, its sector links (the links starting // at sector_t->touching_thinglist) are broken. When a node is // added, new sector links are created. - P_CreateSecNodeList (this, X(), Y()); + P_CreateSecNodeList(this, X(), Y()); touching_sectorlist = sector_list; // Attach to thing sector_list = NULL; // clear for next time - } + } + - // link into blockmap (inert things don't need to be in the blockmap) - if ( !(flags & MF_NOBLOCKMAP) ) + if (!(flags & MF_NOBLOCKMAP)) { - int x1 = GetSafeBlockX(X() - radius - bmaporgx); - int x2 = GetSafeBlockX(X() + radius - bmaporgx); - int y1 = GetSafeBlockY(Y() - radius - bmaporgy); - int y2 = GetSafeBlockY(Y() + radius - bmaporgy); + FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); - if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0) - { // thing is off the map - BlockNode = NULL; - } - else - { // [RH] Link into every block this actor touches, not just the center one - FBlockNode **alink = &this->BlockNode; - x1 = MAX (0, x1); - y1 = MAX (0, y1); - x2 = MIN (bmapwidth - 1, x2); - y2 = MIN (bmapheight - 1, y2); - for (int y = y1; y <= y2; ++y) - { - for (int x = x1; x <= x2; ++x) + P_CollectConnectedGroups(Sector->PortalGroup, Pos(), Top(), radius, check); + + for (int i = -1; i < (int)check.Size(); i++) + { + fixedvec3 pos = i==-1? Pos() : PosRelative(check[i]); + + int x1 = GetSafeBlockX(pos.x - radius - bmaporgx); + int x2 = GetSafeBlockX(pos.x + radius - bmaporgx); + int y1 = GetSafeBlockY(pos.y - radius - bmaporgy); + int y2 = GetSafeBlockY(pos.y + radius - bmaporgy); + + if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0) + { // thing is off the map + BlockNode = NULL; + } + else + { // [RH] Link into every block this actor touches, not just the center one + FBlockNode **alink = &this->BlockNode; + x1 = MAX(0, x1); + y1 = MAX(0, y1); + x2 = MIN(bmapwidth - 1, x2); + y2 = MIN(bmapheight - 1, y2); + for (int y = y1; y <= y2; ++y) { - FBlockNode **link = &blocklinks[y*bmapwidth + x]; - FBlockNode *node = FBlockNode::Create (this, x, y, this->Sector->PortalGroup); - - // Link in to block - if ((node->NextActor = *link) != NULL) + for (int x = x1; x <= x2; ++x) { - (*link)->PrevActor = &node->NextActor; - } - node->PrevActor = link; - *link = node; + FBlockNode **link = &blocklinks[y*bmapwidth + x]; + FBlockNode *node = FBlockNode::Create(this, x, y, this->Sector->PortalGroup); - // Link in to actor - node->PrevBlock = alink; - node->NextBlock = NULL; - (*alink) = node; - alink = &node->NextBlock; + // Link in to block + if ((node->NextActor = *link) != NULL) + { + (*link)->PrevActor = &node->NextActor; + } + node->PrevActor = link; + *link = node; + + // Link in to actor + node->PrevBlock = alink; + node->NextBlock = NULL; + (*alink) = node; + alink = &node->NextBlock; + } } } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a9e23c2a8c..87fe34837f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -456,7 +456,7 @@ void AActor::Serialize (FArchive &arc) if (arc.IsLoading ()) { touching_sectorlist = NULL; - LinkToWorld (false, NULL, Sector); + LinkToWorld (false, Sector); AddToHash (); SetShade (fillcolor); if (player) diff --git a/src/portal.cpp b/src/portal.cpp index a6446a82b6..63dfeafe6b 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -1107,7 +1107,25 @@ void P_CreateLinkedPortals() } } } - //BuildBlockmap(); + if (linkedPortals.Size() > 0) + { + // We need to relink all actors that may touch a linked line portal + TThinkerIterator it; + AActor *actor; + while ((actor = it.Next())) + { + if (!(actor->flags & MF_NOBLOCKMAP)) + { + FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); + P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check); + if (check.Size() > 0) + { + actor->UnlinkFromWorld(); + actor->LinkToWorld(); + } + } + } + } } @@ -1208,7 +1226,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat retval = true; } - if (out.method == FPortalGroupArray::PGA_Full3d) + if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals) { groupsToCheck.Clear(); groupsToCheck.Push(startgroup); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 4cdf31747b..0720599019 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5024,9 +5024,7 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis { self->UnlinkFromWorld (); self->flags |= MF_NOBLOCKMAP; - // the following 4 lines are for future-proofing this for both interpolation overhaul and line portals. - // For portals we need to calculate the destination including the portal offset - // and for interpolation we need to set the performed movement explicitly, because SetXY cannot do that. + // We need to do portal offsetting here explicitly, because SetXY cannot do that. newX -= self->X(); newY -= self->Y(); self->SetXY(self->Vec2Offset(newX, newY)); From 209b495e10faf02d851f634882176eb07de25498 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 8 Mar 2016 16:28:11 +0200 Subject: [PATCH 3/3] Fixed potential crash in DeHackEd loading The patch content was destructed and then accessed when loading DeHackEd file of old/unsupported version Do not print the whole patch content to console but only a filename --- src/d_dehacked.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index e1a86b8fca..8c456517e6 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2505,9 +2505,9 @@ static bool DoDehPatch() { if (PatchFile[25] < '3') { + Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", PatchName); delete[] PatchName; delete[] PatchFile; - Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", PatchFile); return false; } // fix for broken WolfenDoom patches which contain \0 characters in some places.