diff --git a/src/am_map.cpp b/src/am_map.cpp index 312e4b9018..e621425903 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1831,6 +1831,8 @@ void AM_drawGrid (int color) mline_t ml; double minlen, extx, exty; double minx, miny; + auto bmaporgx = level.blockmap.bmaporgx; + auto bmaporgy = level.blockmap.bmaporgy; // [RH] Calculate a minimum for how long the grid lines should be so that // they cover the screen at any rotation. @@ -1843,12 +1845,12 @@ void AM_drawGrid (int color) // Figure out start of vertical gridlines start = minx - extx; - start = ceil((start - bmaporgx) / MAPBLOCKUNITS) * MAPBLOCKUNITS + bmaporgx; + start = ceil((start - bmaporgx) / FBlockmap::MAPBLOCKUNITS) * FBlockmap::MAPBLOCKUNITS + bmaporgx; end = minx + minlen - extx; // draw vertical gridlines - for (x = start; x < end; x += MAPBLOCKUNITS) + for (x = start; x < end; x += FBlockmap::MAPBLOCKUNITS) { ml.a.x = x; ml.b.x = x; @@ -1864,11 +1866,11 @@ void AM_drawGrid (int color) // Figure out start of horizontal gridlines start = miny - exty; - start = ceil((start - bmaporgy) / MAPBLOCKUNITS) * MAPBLOCKUNITS + bmaporgy; + start = ceil((start - bmaporgy) / FBlockmap::MAPBLOCKUNITS) * FBlockmap::MAPBLOCKUNITS + bmaporgy; end = miny + minlen - exty; // draw horizontal gridlines - for (y=start; y sectorPortals; TArray Zones; + FBlockmap blockmap; + // These are copies of the loaded map data that get used by the savegame code to skip unaltered fields // Without such a mechanism the savegame format would become too slow and large because more than 80-90% are normally still unaltered. TArray loadsectors; diff --git a/src/p_blockmap.h b/src/p_blockmap.h index e6474b4ea2..992f2d223a 100644 --- a/src/p_blockmap.h +++ b/src/p_blockmap.h @@ -22,30 +22,73 @@ struct FBlockNode static FBlockNode *FreeBlocks; }; -extern int* blockmaplump; // offsets in blockmap are from here +// BLOCKMAP +// Created from axis aligned bounding box +// of the map, a rectangular array of +// blocks of size 128x128. +// Used to speed up collision detection +// by spatial subdivision in 2D. +// -extern int* blockmap; -extern int bmapwidth; -extern int bmapheight; // in mapblocks -extern double bmaporgx; -extern double bmaporgy; // origin of block map -extern FBlockNode** blocklinks; // for thing chains - - // mapblocks are used to check movement - // against lines and things -enum +struct FBlockmap { - MAPBLOCKUNITS = 128 + int* blockmaplump; // offsets in blockmap are from here + + int* blockmap; + int bmapwidth; + int bmapheight; // in mapblocks + double bmaporgx; + double bmaporgy; // origin of block map + FBlockNode** blocklinks; // for thing chains + + // mapblocks are used to check movement + // against lines and things + enum + { + MAPBLOCKUNITS = 128 + }; + + inline int GetBlockX(double xpos) + { + return int((xpos - bmaporgx) / MAPBLOCKUNITS); + } + + inline int GetBlockY(double ypos) + { + return int((ypos - bmaporgy) / MAPBLOCKUNITS); + } + + inline bool isValidBlock(int x, int y) const + { + return ((unsigned int)x < (unsigned int)bmapwidth && + (unsigned int)y < (unsigned int)bmapheight); + } + + inline int *GetLines(int x, int y) const + { + // There is an extra entry at the beginning of every block. + // Apparently, id had originally intended for it to be used + // to keep track of things, but the final code does not do that. + int offset = y*bmapwidth + x; + return blockmaplump + *(blockmap + offset) + 1; + } + + bool FBlockmap::VerifyBlockMap(int count); + + void Clear() + { + if (blockmaplump != NULL) + { + delete[] blockmaplump; + blockmaplump = NULL; + } + if (blocklinks != NULL) + { + delete[] blocklinks; + blocklinks = NULL; + } + } + }; -inline int GetBlockX(double xpos) -{ - return int((xpos - bmaporgx) / MAPBLOCKUNITS); -} - -inline int GetBlockY(double ypos) -{ - return int((ypos - bmaporgy) / MAPBLOCKUNITS); -} - #endif diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 91d99791dd..8aed0370e5 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1434,7 +1434,7 @@ AActor *LookForTIDInBlock (AActor *lookee, int index, void *extparams) AActor *link; AActor *other; - for (block = blocklinks[index]; block != NULL; block = block->NextActor) + for (block = level.blockmap.blocklinks[index]; block != NULL; block = block->NextActor) { link = block->Me; @@ -1613,7 +1613,7 @@ AActor *LookForEnemiesInBlock (AActor *lookee, int index, void *extparam) AActor *other; FLookExParams *params = (FLookExParams *)extparam; - for (block = blocklinks[index]; block != NULL; block = block->NextActor) + for (block = level.blockmap.blocklinks[index]; block != NULL; block = block->NextActor) { link = block->Me; diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index ca2f14d10e..fc31d60caa 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -322,16 +322,15 @@ bool AActor::FixMapthingPos() { sector_t *secstart = P_PointInSectorBuggy(X(), Y()); - int blockx = GetBlockX(X()); - int blocky = GetBlockY(Y()); + int blockx = level.blockmap.GetBlockX(X()); + int blocky = level.blockmap.GetBlockY(Y()); bool success = false; - if ((unsigned int)blockx < (unsigned int)bmapwidth && - (unsigned int)blocky < (unsigned int)bmapheight) + if (level.blockmap.isValidBlock(blockx, blocky)) { int *list; - for (list = blockmaplump + blockmap[blocky*bmapwidth + blockx] + 1; *list != -1; ++list) + for (list = level.blockmap.GetLines(blockx, blocky); *list != -1; ++list) { line_t *ldef = &level.lines[*list]; @@ -487,25 +486,25 @@ void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sec { DVector3 pos = i==-1? Pos() : PosRelative(check[i] & ~FPortalGroupArray::FLAT); - int x1 = GetBlockX(pos.X - radius); - int x2 = GetBlockX(pos.X + radius); - int y1 = GetBlockY(pos.Y - radius); - int y2 = GetBlockY(pos.Y + radius); + int x1 = level.blockmap.GetBlockX(pos.X - radius); + int x2 = level.blockmap.GetBlockX(pos.X + radius); + int y1 = level.blockmap.GetBlockY(pos.Y - radius); + int y2 = level.blockmap.GetBlockY(pos.Y + radius); - if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0) + if (x1 >= level.blockmap.bmapwidth || x2 < 0 || y1 >= level.blockmap.bmapheight || y2 < 0) { // thing is off the map } else { // [RH] Link into every block this actor touches, not just the center one x1 = MAX(0, x1); y1 = MAX(0, y1); - x2 = MIN(bmapwidth - 1, x2); - y2 = MIN(bmapheight - 1, y2); + x2 = MIN(level.blockmap.bmapwidth - 1, x2); + y2 = MIN(level.blockmap.bmapheight - 1, y2); for (int y = y1; y <= y2; ++y) { for (int x = x1; x <= x2; ++x) { - FBlockNode **link = &blocklinks[y*bmapwidth + x]; + FBlockNode **link = &level.blockmap.blocklinks[y*level.blockmap.bmapwidth + x]; FBlockNode *node = FBlockNode::Create(this, x, y, this->Sector->PortalGroup); // Link in to block @@ -580,7 +579,7 @@ FBlockNode *FBlockNode::Create (AActor *who, int x, int y, int group) { block = new FBlockNode; } - block->BlockIndex = x + y*bmapwidth; + block->BlockIndex = x + y*level.blockmap.bmapwidth; block->Me = who; block->NextActor = NULL; block->PrevActor = NULL; @@ -624,10 +623,10 @@ FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _m void FBlockLinesIterator::init(const FBoundingBox &box) { validcount++; - maxy = GetBlockY(box.Top()); - miny = GetBlockY(box.Bottom()); - maxx = GetBlockX(box.Right()); - minx = GetBlockX(box.Left()); + maxy = level.blockmap.GetBlockY(box.Top()); + miny = level.blockmap.GetBlockY(box.Bottom()); + maxx = level.blockmap.GetBlockX(box.Right()); + minx = level.blockmap.GetBlockX(box.Left()); Reset(); } @@ -646,16 +645,13 @@ void FBlockLinesIterator::StartBlock(int x, int y) { curx = x; cury = y; - if (x >= 0 && y >= 0 && x < bmapwidth && y = 0 && y >= 0 && x < bmapwidth && y X() >= blockleft && me->X() < blockright && @@ -1618,15 +1614,15 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags, y2 += y1; } - x1 -= bmaporgx; - y1 -= bmaporgy; - xt1 = x1 / MAPBLOCKUNITS; - yt1 = y1 / MAPBLOCKUNITS; + x1 -= level.blockmap.bmaporgx; + y1 -= level.blockmap.bmaporgy; + xt1 = x1 / FBlockmap::MAPBLOCKUNITS; + yt1 = y1 / FBlockmap::MAPBLOCKUNITS; - x2 -= bmaporgx; - y2 -= bmaporgy; - xt2 = x2 / MAPBLOCKUNITS; - yt2 = y2 / MAPBLOCKUNITS; + x2 -= level.blockmap.bmaporgx; + y2 -= level.blockmap.bmaporgy; + xt2 = x2 / FBlockmap::MAPBLOCKUNITS; + yt2 = y2 / FBlockmap::MAPBLOCKUNITS; mapx = xs_FloorToInt(xt1); mapy = xs_FloorToInt(yt1); @@ -1834,7 +1830,7 @@ FPathTraverse::~FPathTraverse() // P_RoughMonsterSearch // // Searches though the surrounding mapblocks for monsters/players -// distance is in MAPBLOCKUNITS +// distance is in FBlockmap::MAPBLOCKUNITS //=========================================================================== AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params) @@ -1849,12 +1845,14 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in int finalStop; int count; AActor *target; + int bmapwidth = level.blockmap.bmapwidth; + int bmapheight = level.blockmap.bmapheight; - startX = GetBlockX(mo->X()); - startY = GetBlockY(mo->Y()); + startX = level.blockmap.GetBlockX(mo->X()); + startY = level.blockmap.GetBlockY(mo->Y()); validcount++; - if (startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight) + if (level.blockmap.isValidBlock(startX, startY)) { if ( (target = check (mo, startY*bmapwidth+startX, params)) ) { // found a target right away @@ -1945,7 +1943,7 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param) FBlockNode *link; - for (link = blocklinks[index]; link != NULL; link = link->NextActor) + for (link = level.blockmap.blocklinks[index]; link != NULL; link = link->NextActor) { if (link->Me != mo) { diff --git a/src/p_secnodes.cpp b/src/p_secnodes.cpp index 346f5ff8e7..f0c7eb32f5 100644 --- a/src/p_secnodes.cpp +++ b/src/p_secnodes.cpp @@ -388,11 +388,11 @@ void AActor::UpdateRenderSectorList() ClearRenderLineList(); if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) { - int bx = GetBlockX(X()); - int by = GetBlockY(Y()); + int bx = level.blockmap.GetBlockX(X()); + int by = level.blockmap.GetBlockY(Y()); FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors // Are there any portals near the actor's position? - if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines) + if (level.blockmap.isValidBlock(bx, by) && PortalBlockmap(bx, by).neighborContainsLines) { // Go through the entire list. In most cases this is faster than setting up a blockmap iterator for (auto &p : linePortals) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index e334a272be..796b557762 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -136,34 +136,6 @@ sidei_t *sidetemp; TArray linemap; -// BLOCKMAP -// Created from axis aligned bounding box -// of the map, a rectangular array of -// blocks of size 256x256. -// Used to speed up collision detection -// by spatial subdivision in 2D. -// -// Blockmap size. -int bmapwidth; -int bmapheight; // size in mapblocks - -int *blockmap; // int for larger maps ([RH] Made int because BOOM does) -int *blockmaplump; // offsets in blockmap are from here - -double bmaporgx; // origin of block map -double bmaporgy; - -FBlockNode** blocklinks; // for thing chains - - -// REJECT -// For fast sight rejection. -// Speeds up enemy AI by skipping detailed -// LineOf Sight calculation. -// Without special effect, this could be -// used as a PVS lookup as well. -// - bool ForceNodeBuild; static void P_AllocateSideDefs (MapData *map, int count); @@ -2868,10 +2840,10 @@ static void P_CreateBlockMap () CreatePackedBlockmap (BlockMap, BlockLists, bmapwidth, bmapheight); delete[] BlockLists; - blockmaplump = new int[BlockMap.Size()]; + level.blockmap.blockmaplump = new int[BlockMap.Size()]; for (unsigned int ii = 0; ii < BlockMap.Size(); ++ii) { - blockmaplump[ii] = BlockMap[ii]; + level.blockmap.blockmaplump[ii] = BlockMap[ii]; } } @@ -2882,7 +2854,7 @@ static void P_CreateBlockMap () // // haleyjd 03/04/10: do verification on validity of blockmap. // -static bool P_VerifyBlockMap(int count) +bool FBlockmap::VerifyBlockMap(int count) { int x, y; int *maxoffs = blockmaplump + count; @@ -2905,7 +2877,7 @@ static bool P_VerifyBlockMap(int count) // check that block offset is in bounds if(blockoffset >= maxoffs) { - Printf(PRINT_HIGH, "P_VerifyBlockMap: block offset overflow\n"); + Printf(PRINT_HIGH, "VerifyBlockMap: block offset overflow\n"); return false; } @@ -2914,7 +2886,7 @@ static bool P_VerifyBlockMap(int count) // check that list offset is in bounds if(offset < 4 || offset >= count) { - Printf(PRINT_HIGH, "P_VerifyBlockMap: list offset overflow\n"); + Printf(PRINT_HIGH, "VerifyBlockMap: list offset overflow\n"); return false; } @@ -2926,7 +2898,7 @@ static bool P_VerifyBlockMap(int count) // we have overflowed the lump? if(tmplist >= maxoffs) { - Printf(PRINT_HIGH, "P_VerifyBlockMap: open blocklist\n"); + Printf(PRINT_HIGH, "VerifyBlockMap: open blocklist\n"); return false; } if(*tmplist == -1) // found -1 @@ -2938,7 +2910,7 @@ static bool P_VerifyBlockMap(int count) // to be on the safe side. if (*list != 0) { - Printf(PRINT_HIGH, "P_VerifyBlockMap: first entry is not 0.\n"); + Printf(PRINT_HIGH, "VerifyBlockMap: first entry is not 0.\n"); return false; } @@ -2947,7 +2919,7 @@ static bool P_VerifyBlockMap(int count) { if((unsigned)*tmplist >= level.lines.Size()) { - Printf(PRINT_HIGH, "P_VerifyBlockMap: index >= numlines\n"); + Printf(PRINT_HIGH, "VerifyBlockMap: index >= numlines\n"); return false; } } @@ -2986,26 +2958,26 @@ void P_LoadBlockMap (MapData * map) int i; count/=2; - blockmaplump = new int[count]; + level.blockmap.blockmaplump = new int[count]; // killough 3/1/98: Expand wad blockmap into larger internal one, // by treating all offsets except -1 as unsigned and zero-extending // them. This potentially doubles the size of blockmaps allowed, // because Doom originally considered the offsets as always signed. - blockmaplump[0] = LittleShort(wadblockmaplump[0]); - blockmaplump[1] = LittleShort(wadblockmaplump[1]); - blockmaplump[2] = (uint32_t)(LittleShort(wadblockmaplump[2])) & 0xffff; - blockmaplump[3] = (uint32_t)(LittleShort(wadblockmaplump[3])) & 0xffff; + level.blockmap.blockmaplump[0] = LittleShort(wadblockmaplump[0]); + level.blockmap.blockmaplump[1] = LittleShort(wadblockmaplump[1]); + level.blockmap.blockmaplump[2] = (uint32_t)(LittleShort(wadblockmaplump[2])) & 0xffff; + level.blockmap.blockmaplump[3] = (uint32_t)(LittleShort(wadblockmaplump[3])) & 0xffff; for (i = 4; i < count; i++) { short t = LittleShort(wadblockmaplump[i]); // killough 3/1/98 - blockmaplump[i] = t == -1 ? (uint32_t)0xffffffff : (uint32_t) t & 0xffff; + level.blockmap.blockmaplump[i] = t == -1 ? (uint32_t)0xffffffff : (uint32_t) t & 0xffff; } delete[] data; - if (!P_VerifyBlockMap(count)) + if (!level.blockmap.VerifyBlockMap(count)) { DPrintf (DMSG_SPAMMY, "Generating BLOCKMAP\n"); P_CreateBlockMap(); @@ -3013,16 +2985,16 @@ void P_LoadBlockMap (MapData * map) } - bmaporgx = blockmaplump[0]; - bmaporgy = blockmaplump[1]; - bmapwidth = blockmaplump[2]; - bmapheight = blockmaplump[3]; + level.blockmap.bmaporgx = level.blockmap.blockmaplump[0]; + level.blockmap.bmaporgy = level.blockmap.blockmaplump[1]; + level.blockmap.bmapwidth = level.blockmap.blockmaplump[2]; + level.blockmap.bmapheight = level.blockmap.blockmaplump[3]; // clear out mobj chains - count = bmapwidth*bmapheight; - blocklinks = new FBlockNode *[count]; - memset (blocklinks, 0, count*sizeof(*blocklinks)); - blockmap = blockmaplump+4; + count = level.blockmap.bmapwidth*level.blockmap.bmapheight; + level.blockmap.blocklinks = new FBlockNode *[count]; + memset (level.blockmap.blocklinks, 0, count*sizeof(*level.blockmap.blocklinks)); + level.blockmap.blockmap = level.blockmap.blockmaplump+4; } // @@ -3432,20 +3404,11 @@ void P_FreeLevelData () level.gamesubsectors.Reset(); level.rejectmatrix.Clear(); level.Zones.Clear(); + level.blockmap.Clear(); - if (blockmaplump != NULL) - { - delete[] blockmaplump; - blockmaplump = NULL; - } - if (blocklinks != NULL) - { - delete[] blocklinks; - blocklinks = NULL; - } if (PolyBlockMap != NULL) { - for (int i = bmapwidth*bmapheight-1; i >= 0; --i) + for (int i = level.blockmap.bmapwidth*level.blockmap.bmapheight-1; i >= 0; --i) { polyblock_t *link = PolyBlockMap[i]; while (link != NULL) diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 238a73ef25..c7e1dea75f 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -470,7 +470,7 @@ int SightCheck::P_SightBlockLinesIterator (int x, int y) unsigned int i; extern polyblock_t **PolyBlockMap; - offset = y*bmapwidth+x; + offset = y*level.blockmap.bmapwidth+x; // if any of the previous blocks may contain a portal we may abort the collection of lines here, but we may not abort the sight check. // (We still try to delay activating this for as long as possible.) @@ -498,9 +498,7 @@ int SightCheck::P_SightBlockLinesIterator (int x, int y) polyLink = polyLink->next; } - offset = *(blockmap + offset); - - for (list = blockmaplump + offset + 1; *list != -1; list++) + for (list = level.blockmap.GetLines(x, y); *list != -1; list++) { if (!P_SightCheckLine (&level.lines[*list])) { @@ -655,15 +653,15 @@ bool SightCheck::P_SightPathTraverse () portals.Push({ 0, topslope, bottomslope, sector_t::floor, lastsector->GetOppositePortalGroup(sector_t::floor) }); } - x1 -= bmaporgx; - y1 -= bmaporgy; - xt1 = x1 / MAPBLOCKUNITS; - yt1 = y1 / MAPBLOCKUNITS; + x1 -= level.blockmap.bmaporgx; + y1 -= level.blockmap.bmaporgy; + xt1 = x1 / FBlockmap::MAPBLOCKUNITS; + yt1 = y1 / FBlockmap::MAPBLOCKUNITS; - x2 -= bmaporgx; - y2 -= bmaporgy; - xt2 = x2 / MAPBLOCKUNITS; - yt2 = y2 / MAPBLOCKUNITS; + x2 -= level.blockmap.bmaporgx; + y2 -= level.blockmap.bmaporgy; + xt2 = x2 / FBlockmap::MAPBLOCKUNITS; + yt2 = y2 / FBlockmap::MAPBLOCKUNITS; mapx = xs_FloorToInt(xt1); mapy = xs_FloorToInt(yt1); @@ -741,7 +739,7 @@ bool SightCheck::P_SightPathTraverse () { // end traversing when reaching the end of the blockmap // an early out is not possible because with portals a trace can easily land outside the map's bounds. - if (mapx < 0 || mapx >= bmapwidth || mapy < 0 || mapy >= bmapheight) + if (level.blockmap.isValidBlock(mapx, mapy)) { break; } diff --git a/src/po_man.cpp b/src/po_man.cpp index 5baa90be60..0a8948b232 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1069,10 +1069,10 @@ void FPolyObj::UnLinkPolyobj () // remove the polyobj from each blockmap section for(j = bbox[BOXBOTTOM]; j <= bbox[BOXTOP]; j++) { - index = j*bmapwidth; + index = j*level.blockmap.bmapwidth; for(i = bbox[BOXLEFT]; i <= bbox[BOXRIGHT]; i++) { - if(i >= 0 && i < bmapwidth && j >= 0 && j < bmapheight) + if(i >= 0 && i < level.blockmap.bmapwidth && j >= 0 && j < level.blockmap.bmapheight) { link = PolyBlockMap[index+i]; while(link != NULL && link->polyobj != this) @@ -1105,13 +1105,15 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) line_t *ld; bool blocked; bool performBlockingThrust; + int bmapwidth = level.blockmap.bmapwidth; + int bmapheight = level.blockmap.bmapheight; ld = sd->linedef; - top = GetBlockY(ld->bbox[BOXTOP]); - bottom = GetBlockY(ld->bbox[BOXBOTTOM]); - left = GetBlockX(ld->bbox[BOXLEFT]); - right = GetBlockX(ld->bbox[BOXRIGHT]); + top = level.blockmap.GetBlockY(ld->bbox[BOXTOP]); + bottom = level.blockmap.GetBlockY(ld->bbox[BOXBOTTOM]); + left = level.blockmap.GetBlockX(ld->bbox[BOXLEFT]); + right = level.blockmap.GetBlockX(ld->bbox[BOXRIGHT]); blocked = false; checker.Clear(); @@ -1129,7 +1131,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) { for (i = left; i <= right; i++) { - for (block = blocklinks[j+i]; block != NULL; block = block->NextActor) + for (block = level.blockmap.blocklinks[j+i]; block != NULL; block = block->NextActor) { mobj = block->Me; for (k = (int)checker.Size()-1; k >= 0; --k) @@ -1230,6 +1232,8 @@ void FPolyObj::LinkPolyobj () { polyblock_t **link; polyblock_t *tempLink; + int bmapwidth = level.blockmap.bmapwidth; + int bmapheight = level.blockmap.bmapheight; // calculate the polyobj bbox Bounds.ClearBox(); @@ -1242,10 +1246,10 @@ void FPolyObj::LinkPolyobj () vt = Sidedefs[i]->linedef->v2; Bounds.AddToBox(vt->fPos()); } - bbox[BOXRIGHT] = GetBlockX(Bounds.Right()); - bbox[BOXLEFT] = GetBlockX(Bounds.Left()); - bbox[BOXTOP] = GetBlockY(Bounds.Top()); - bbox[BOXBOTTOM] = GetBlockY(Bounds.Bottom()); + bbox[BOXRIGHT] = level.blockmap.GetBlockX(Bounds.Right()); + bbox[BOXLEFT] = level.blockmap.GetBlockX(Bounds.Left()); + bbox[BOXTOP] = level.blockmap.GetBlockY(Bounds.Top()); + bbox[BOXBOTTOM] = level.blockmap.GetBlockY(Bounds.Bottom()); // add the polyobj to each blockmap section for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth; j += bmapwidth) @@ -1398,6 +1402,8 @@ void FPolyObj::ClosestPoint(const DVector2 &fpos, DVector2 &out, side_t **side) static void InitBlockMap (void) { int i; + int bmapwidth = level.blockmap.bmapwidth; + int bmapheight = level.blockmap.bmapheight; PolyBlockMap = new polyblock_t *[bmapwidth*bmapheight]; memset (PolyBlockMap, 0, bmapwidth*bmapheight*sizeof(polyblock_t *)); diff --git a/src/portal.cpp b/src/portal.cpp index 15d012416c..1ec92799f4 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -113,14 +113,16 @@ struct FPortalBits static void BuildBlockmap() { + auto bmapwidth = level.blockmap.bmapwidth; + auto bmapheight = level.blockmap.bmapheight; + PortalBlockmap.Clear(); PortalBlockmap.Create(bmapwidth, bmapheight); for (int y = 0; y < bmapheight; y++) { for (int x = 0; x < bmapwidth; x++) { - int offset = y*bmapwidth + x; - int *list = blockmaplump + *(blockmap + offset) + 1; + int *list = level.blockmap.GetLines(x, y); FPortalBlock &block = PortalBlockmap(x, y); while (*list != -1) @@ -165,7 +167,7 @@ static void BuildBlockmap() void FLinePortalTraverse::AddLineIntercepts(int bx, int by) { - if (by < 0 || by >= bmapheight || bx < 0 || bx >= bmapwidth) return; + if (by < 0 || by >= PortalBlockmap.dx || bx < 0 || bx >= PortalBlockmap.dy) return; FPortalBlock &block = PortalBlockmap(bx, by); @@ -743,9 +745,9 @@ DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy) // Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map. if (dx < 128 && dy < 128) { - int blockx = GetBlockX(actx); - int blocky = GetBlockY(acty); - if (blockx < 0 || blocky < 0 || blockx >= bmapwidth || blocky >= bmapheight || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest; + int blockx = level.blockmap.GetBlockX(actx); + int blocky = level.blockmap.GetBlockY(acty); + if (blockx < 0 || blocky < 0 || blockx >= PortalBlockmap.dx || blocky >= PortalBlockmap.dy || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest; } bool repeat;