diff --git a/source/core/automap.cpp b/source/core/automap.cpp
index 725f0cf5b..e9eeb076b 100644
--- a/source/core/automap.cpp
+++ b/source/core/automap.cpp
@@ -61,8 +61,8 @@ int follow_x = INT_MAX, follow_y = INT_MAX, follow_a = INT_MAX;
 static int gZoom = 768;
 bool automapping;
 bool gFullMap;
-FixedBitArray<MAXSECTORS> show2dsector;
-FixedBitArray<MAXWALLS> show2dwall;
+BitArray show2dsector;
+BitArray show2dwall;
 static int x_min_bound = INT_MAX, y_min_bound, x_max_bound, y_max_bound;
 
 CVAR(Color, am_twosidedcolor, 0xaaaaaa, CVAR_ARCHIVE)
@@ -268,8 +268,8 @@ void SerializeAutomap(FSerializer& arc)
 		arc("automapping", automapping)
 			("fullmap", gFullMap)
 			// Only store what's needed. Unfortunately for sprites it is not that easy
-			.SerializeMemory("mappedsectors", show2dsector.Storage(), (numsectors + 7) / 8)
-			.SerializeMemory("mappedwalls", show2dwall.Storage(), (numwalls + 7) / 8)
+			.SerializeMemory("mappedsectors", show2dsector.Storage().Data(), (numsectors + 7) / 8)
+			.SerializeMemory("mappedwalls", show2dwall.Storage().Data(), (numwalls + 7) / 8)
 			.EndObject();
 	}
 }
diff --git a/source/core/automap.h b/source/core/automap.h
index ad8731440..9e6bbd63a 100644
--- a/source/core/automap.h
+++ b/source/core/automap.h
@@ -10,8 +10,8 @@ struct event_t;
 
 extern bool automapping;
 extern bool gFullMap;
-extern FixedBitArray<MAXSECTORS> show2dsector;
-extern FixedBitArray<MAXWALLS> show2dwall;
+extern BitArray show2dsector;
+extern BitArray show2dwall;
 
 void SerializeAutomap(FSerializer& arc);
 void ClearAutomap();
diff --git a/source/core/interpolate.cpp b/source/core/interpolate.cpp
index 93c48da03..08b81acce 100644
--- a/source/core/interpolate.cpp
+++ b/source/core/interpolate.cpp
@@ -184,9 +184,9 @@ void setsectinterpolate(int sectnum)
 	{
 		StartInterpolation(&wal, Interp_Wall_X);
 		StartInterpolation(&wal, Interp_Wall_Y);
-		auto nwal = wal.nextWall();
-		if (nwal)
+		if (wal.twoSided())
 		{
+			auto nwal = wal.nextWall();
 			StartInterpolation(nwal, Interp_Wall_X);
 			StartInterpolation(nwal, Interp_Wall_Y);
 			nwal = nwal->point2Wall();
@@ -204,7 +204,7 @@ void clearsectinterpolate(int sectnum)
 	{
 		StopInterpolation(&wal, Interp_Wall_X);
 		StopInterpolation(&wal, Interp_Wall_Y);
-		if (wal.nextwall >= 0)
+		if (wal.twoSided())
 		{
 			StopInterpolation(wal.nextWall(), Interp_Wall_X);
 			StopInterpolation(wal.nextWall(), Interp_Wall_Y);
diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp
index 9120e1008..40091897e 100644
--- a/source/core/maploader.cpp
+++ b/source/core/maploader.cpp
@@ -411,6 +411,9 @@ void allocateMapArrays(int numsprites)
 	ClearInterpolations();
 
 
+	show2dsector.Resize(numsectors);
+	show2dwall.Resize(numwalls);
+
 	mapDataArena.FreeAll();
 	sector.Resize(numsectors);
 	memset(sector.Data(), 0, sizeof(sectortype) * numsectors);
diff --git a/source/core/rendering/scene/hw_bunchdrawer.cpp b/source/core/rendering/scene/hw_bunchdrawer.cpp
index b5b9bef28..616f2f26b 100644
--- a/source/core/rendering/scene/hw_bunchdrawer.cpp
+++ b/source/core/rendering/scene/hw_bunchdrawer.cpp
@@ -76,6 +76,8 @@ void BunchDrawer::Init(HWDrawInfo *_di, Clipper* c, vec2_t& view, binangle a1, b
 	}
 	memset(sectionstartang, -1, sizeof(sectionstartang));
 	memset(sectionendang, -1, sizeof(sectionendang));
+	gotwall.Resize(numwalls);
+	blockwall.Resize(numwalls);
 }
 
 //==========================================================================
diff --git a/source/core/rendering/scene/hw_bunchdrawer.h b/source/core/rendering/scene/hw_bunchdrawer.h
index 1a12bf9b1..96c481fed 100644
--- a/source/core/rendering/scene/hw_bunchdrawer.h
+++ b/source/core/rendering/scene/hw_bunchdrawer.h
@@ -29,8 +29,8 @@ class BunchDrawer
     float gcosang, gsinang;
     FixedBitArray<MAXSECTORS> gotsector;
     FixedBitArray<MAXSECTORS*5/4> gotsection2;
-    FixedBitArray<MAXWALLS> gotwall;
-    FixedBitArray<MAXWALLS> blockwall;
+    BitArray gotwall;
+    BitArray blockwall;
     binangle ang1, ang2, angrange;
 
     int sectionstartang[MAXSECTORS*5/4], sectionendang[MAXSECTORS*5/4];
diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp
index c45d6c7b5..fcea482cd 100644
--- a/source/games/blood/src/actor.cpp
+++ b/source/games/blood/src/actor.cpp
@@ -3851,7 +3851,7 @@ void actHitcodeToData(int a1, HITINFO* pHitInfo, DBloodActor** pActor, walltype*
 	case 0:
 	case 4:
 		nWall = pHitInfo->hitwall;
-		if (nWall >= 0 && nWall < kMaxWalls) pWall = &wall[nWall];
+		if (validWallIndex(nWall)) pWall = &wall[nWall];
 		break;
 	default:
 		break;
@@ -6818,7 +6818,7 @@ bool actCheckRespawn(DBloodActor* actor)
 
 bool actCanSplatWall(int nWall)
 {
-	assert(nWall >= 0 && nWall < kMaxWalls);
+	assert(validWallIndex(nWall));
 	walltype* pWall = &wall[nWall];
 	if (pWall->cstat & 16384) return 0;
 	if (pWall->cstat & 32768) return 0;
@@ -6895,7 +6895,7 @@ void actFireVector(DBloodActor* shooter, int a2, int a3, int a4, int a5, int a6,
 		case 0:
 		{
 			int nWall = gHitInfo.hitwall;
-			assert(nWall >= 0 && nWall < kMaxWalls);
+			assert(validWallIndex(nWall));
 			auto pWall = &wall[nWall];
 			nSurf = surfType[pWall->picnum];
 			if (actCanSplatWall(nWall))
@@ -6920,7 +6920,7 @@ void actFireVector(DBloodActor* shooter, int a2, int a3, int a4, int a5, int a6,
 		case 4:
 		{
 			int nWall = gHitInfo.hitwall;
-			assert(nWall >= 0 && nWall < kMaxWalls);
+			assert(validWallIndex(nWall));
 			auto pWall = &wall[nWall];
 			nSurf = surfType[pWall->overpicnum];
 			if (pWall->hasX())
diff --git a/source/games/blood/src/common_game.h b/source/games/blood/src/common_game.h
index 2919bbb30..b2ec64dc3 100644
--- a/source/games/blood/src/common_game.h
+++ b/source/games/blood/src/common_game.h
@@ -35,8 +35,6 @@ void QuitGame(void);
 
 enum
 {
-    kMaxSectors = MAXSECTORS,
-    kMaxWalls = MAXWALLS,
     kMaxSprites = MAXSPRITES,
 
     kMaxTiles = MAXTILES,
diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp
index fa2879a1b..d51fd5f68 100644
--- a/source/games/blood/src/db.cpp
+++ b/source/games/blood/src/db.cpp
@@ -145,7 +145,7 @@ void RemoveSpriteStat(int nSprite)
 
 void qinitspritelists(void) // Replace
 {
-    for (int i = 0; i <= kMaxSectors; i++)
+    for (int i = 0; i <= MAXSECTORS; i++)
     {
         headspritesect[i] = -1;
     }
diff --git a/source/games/blood/src/gameutil.cpp b/source/games/blood/src/gameutil.cpp
index 35e08c026..98aac4e26 100644
--- a/source/games/blood/src/gameutil.cpp
+++ b/source/games/blood/src/gameutil.cpp
@@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 BEGIN_BLD_NS
 
-POINT2D baseWall[kMaxWalls];
 HITINFO gHitInfo;
 
 bool FindSector(int nX, int nY, int nZ, int *nSector)
@@ -299,7 +298,7 @@ int GetWallAngle(walltype* pWall)
 
 void GetWallNormal(int nWall, int *pX, int *pY)
 {
-    assert(nWall >= 0 && nWall < kMaxWalls);
+    assert(validWallIndex(nWall));
     int nWall2 = wall[nWall].point2;
     int dX = -(wall[nWall2].y - wall[nWall].y);
     dX >>= 4;
diff --git a/source/games/blood/src/gameutil.h b/source/games/blood/src/gameutil.h
index 4af5192c7..42c551823 100644
--- a/source/games/blood/src/gameutil.h
+++ b/source/games/blood/src/gameutil.h
@@ -42,7 +42,6 @@ struct HITINFO {
     void set(hitdata_t* hit);
 };
 
-extern POINT2D baseWall[kMaxWalls];
 extern HITINFO gHitInfo;
 
 enum {
diff --git a/source/games/blood/src/seq.cpp b/source/games/blood/src/seq.cpp
index dce6f65c2..9e5ffc735 100644
--- a/source/games/blood/src/seq.cpp
+++ b/source/games/blood/src/seq.cpp
@@ -716,7 +716,7 @@ void seqProcess(int nTicks)
 
 						else if (pInst->type == SS_MASKED)
 						{
-							assert(index >= 0 && index < kMaxWalls);
+							assert(validWallIndex(index));
 							auto pWall = &wall[index];
 							pWall->cstat &= ~(8 + 16 + 32);
 							if (pWall->twoSided())
diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp
index 12b488176..cfc32090f 100644
--- a/source/games/blood/src/triggers.cpp
+++ b/source/games/blood/src/triggers.cpp
@@ -827,8 +827,8 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7
     {
         for (int i = 0; i < pSector->wallnum; nWall++, i++)
         {
-            x = baseWall[nWall].x;
-            y = baseWall[nWall].y;
+            x = wall[nWall].baseWall.x;
+            y = wall[nWall].baseWall.y;
             if (vbp)
                 RotatePoint((int*)&x, (int*)&y, vbp, a4, a5);
             DragPoint(nWall, x+vc-a4, y+v8-a5);
@@ -839,8 +839,8 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7
         for (int i = 0; i < pSector->wallnum; nWall++, i++)
         {
             int v10 = wall[nWall].point2;
-            x = baseWall[nWall].x;
-            y = baseWall[nWall].y;
+            x = wall[nWall].baseWall.x;
+            y = wall[nWall].baseWall.y;
             if (wall[nWall].cstat&16384)
             {
                 if (vbp)
@@ -848,8 +848,8 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7
                 DragPoint(nWall, x+vc-a4, y+v8-a5);
                 if ((wall[v10].cstat&49152) == 0)
                 {
-                    x = baseWall[v10].x;
-                    y = baseWall[v10].y;
+                    x = wall[v10].baseWall.x;
+                    y = wall[v10].baseWall.y;
                     if (vbp)
                         RotatePoint((int*)&x, (int*)&y, vbp, a4, a5);
                     DragPoint(v10, x+vc-a4, y+v8-a5);
@@ -863,8 +863,8 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7
                 DragPoint(nWall, x-(vc-a4), y-(v8-a5));
                 if ((wall[v10].cstat&49152) == 0)
                 {
-                    x = baseWall[v10].x;
-                    y = baseWall[v10].y;
+                    x = wall[v10].baseWall.x;
+                    y = wall[v10].baseWall.y;
                     if (vbp)
                         RotatePoint((int*)&x, (int*)&y, -vbp, a4, a5);
                     DragPoint(v10, x-(vc-a4), y-(v8-a5));
@@ -1997,8 +1997,8 @@ void trInit(void)
     gBusyCount = 0;
     for (int i = 0; i < numwalls; i++)
     {
-        baseWall[i].x = wall[i].x;
-        baseWall[i].y = wall[i].y;
+        wall[i].baseWall.x = wall[i].x;
+        wall[i].baseWall.y = wall[i].y;
     }
     BloodLinearSpriteIterator it;
     while (auto actor = it.Next())
@@ -2053,8 +2053,8 @@ void trInit(void)
                 TranslateSector(i, 0, -65536, pSprite1->x, pSprite1->y, pSprite1->x, pSprite1->y, pSprite1->ang, pSprite2->x, pSprite2->y, pSprite2->ang, pSector->type == kSectorSlide);
                 for (int j = 0; j < pSector->wallnum; j++)
                 {
-                    baseWall[pSector->wallptr+j].x = wall[pSector->wallptr+j].x;
-                    baseWall[pSector->wallptr+j].y = wall[pSector->wallptr+j].y;
+                    wall[pSector->wallptr + j].baseWall.x = wall[pSector->wallptr+j].x;
+                    wall[pSector->wallptr + j].baseWall.y = wall[pSector->wallptr+j].y;
                 }
                 BloodSectIterator it(i);
                 while (auto actor = it.Next())
@@ -2072,8 +2072,8 @@ void trInit(void)
                 TranslateSector(i, 0, -65536, pSprite1->x, pSprite1->y, pSprite1->x, pSprite1->y, 0, pSprite1->x, pSprite1->y, pSprite1->ang, pSector->type == kSectorRotate);
                 for (int j = 0; j < pSector->wallnum; j++)
                 {
-                    baseWall[pSector->wallptr+j].x = wall[pSector->wallptr+j].x;
-                    baseWall[pSector->wallptr+j].y = wall[pSector->wallptr+j].y;
+                    wall[pSector->wallptr + j].baseWall.x = wall[pSector->wallptr + j].x;
+                    wall[pSector->wallptr + j].baseWall.y = wall[pSector->wallptr + j].y;
                 }
                 BloodSectIterator it(i);
                 while (auto actor = it.Next())
diff --git a/source/games/exhumed/src/engine.h b/source/games/exhumed/src/engine.h
index 0a1f63048..0549a4172 100644
--- a/source/games/exhumed/src/engine.h
+++ b/source/games/exhumed/src/engine.h
@@ -26,8 +26,6 @@ enum
 {
 	kStatIgnited = 404,
 	kMaxSprites = 4096,
-	kMaxSectors = 1024,
-	kMaxWalls   = 8192,
 	kMaxVoxels	= 4096,
 	kMaxPalookups = 256,
 	kMaxStatus   = 1024,
diff --git a/source/games/exhumed/src/lighting.cpp b/source/games/exhumed/src/lighting.cpp
index e24e4c788..5f6f69b53 100644
--- a/source/games/exhumed/src/lighting.cpp
+++ b/source/games/exhumed/src/lighting.cpp
@@ -423,7 +423,7 @@ void UndoFlashes()
 
                 case 1:
                 {
-                    assert(nIndex >= 0 && nIndex < kMaxWalls);
+                    assert(validWallIndex(nIndex));
 
                     pShade = &wall[nIndex].shade;
                     break;