diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp
index da506602c..d7ad75b65 100644
--- a/src/swrenderer/line/r_line.cpp
+++ b/src/swrenderer/line/r_line.cpp
@@ -373,7 +373,11 @@ namespace swrenderer
 		if (clip3d->fake3D & FAKE3D_FAKEMASK) draw_segment->fake = 1;
 		else draw_segment->fake = 0;
 
-		draw_segment->sprtopclip = draw_segment->sprbottomclip = draw_segment->maskedtexturecol = draw_segment->bkup = draw_segment->swall = -1;
+		draw_segment->sprtopclip = nullptr;
+		draw_segment->sprbottomclip = nullptr;
+		draw_segment->maskedtexturecol = nullptr;
+		draw_segment->bkup = nullptr;
+		draw_segment->swall = nullptr;
 
 		if (rw_markportal)
 		{
@@ -381,10 +385,10 @@ namespace swrenderer
 		}
 		else if (backsector == NULL)
 		{
-			draw_segment->sprtopclip = R_NewOpening(stop - start);
-			draw_segment->sprbottomclip = R_NewOpening(stop - start);
-			fillshort(openings + draw_segment->sprtopclip, stop - start, viewheight);
-			memset(openings + draw_segment->sprbottomclip, -1, (stop - start) * sizeof(short));
+			draw_segment->sprtopclip = RenderMemory::AllocMemory<short>(stop - start);
+			draw_segment->sprbottomclip = RenderMemory::AllocMemory<short>(stop - start);
+			fillshort(draw_segment->sprtopclip, stop - start, viewheight);
+			memset(draw_segment->sprbottomclip, -1, (stop - start) * sizeof(short));
 			draw_segment->silhouette = SIL_BOTH;
 		}
 		else
@@ -415,14 +419,14 @@ namespace swrenderer
 			{
 				if (doorclosed || (rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2))
 				{
-					draw_segment->sprbottomclip = R_NewOpening(stop - start);
-					memset(openings + draw_segment->sprbottomclip, -1, (stop - start) * sizeof(short));
+					draw_segment->sprbottomclip = RenderMemory::AllocMemory<short>(stop - start);
+					memset(draw_segment->sprbottomclip, -1, (stop - start) * sizeof(short));
 					draw_segment->silhouette |= SIL_BOTTOM;
 				}
 				if (doorclosed || (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2))
 				{						// killough 1/17/98, 2/8/98
-					draw_segment->sprtopclip = R_NewOpening(stop - start);
-					fillshort(openings + draw_segment->sprtopclip, stop - start, viewheight);
+					draw_segment->sprtopclip = RenderMemory::AllocMemory<short>(stop - start);
+					fillshort(draw_segment->sprtopclip, stop - start, viewheight);
 					draw_segment->silhouette |= SIL_TOP;
 				}
 			}
@@ -461,8 +465,8 @@ namespace swrenderer
 					maskedtexture = true;
 
 					// kg3D - backup for mid and fake walls
-					draw_segment->bkup = R_NewOpening(stop - start);
-					memcpy(openings + draw_segment->bkup, &RenderOpaquePass::Instance()->ceilingclip[start], sizeof(short)*(stop - start));
+					draw_segment->bkup = RenderMemory::AllocMemory<short>(stop - start);
+					memcpy(draw_segment->bkup, &RenderOpaquePass::Instance()->ceilingclip[start], sizeof(short)*(stop - start));
 
 					draw_segment->bFogBoundary = IsFogBoundary(frontsector, backsector);
 					if (sidedef->GetTexture(side_t::mid).isValid() || draw_segment->bFakeBoundary)
@@ -470,12 +474,11 @@ namespace swrenderer
 						if (sidedef->GetTexture(side_t::mid).isValid())
 							draw_segment->bFakeBoundary |= 4; // it is also mid texture
 
-															  // note: This should never have used the openings array to store its data!
-						draw_segment->maskedtexturecol = R_NewOpening((stop - start) * 2);
-						draw_segment->swall = R_NewOpening((stop - start) * 2);
+						draw_segment->maskedtexturecol = RenderMemory::AllocMemory<fixed_t>(stop - start);
+						draw_segment->swall = RenderMemory::AllocMemory<float>(stop - start);
 
-						lwal = (fixed_t *)(openings + draw_segment->maskedtexturecol);
-						swal = (float *)(openings + draw_segment->swall);
+						lwal = draw_segment->maskedtexturecol;
+						swal = draw_segment->swall;
 						FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true);
 						double yscale = pic->Scale.Y * sidedef->GetTextureYScale(side_t::mid);
 						fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
@@ -491,7 +494,7 @@ namespace swrenderer
 							*swal++ = swall[i];
 						}
 
-						double istart = *((float *)(openings + draw_segment->swall)) * yscale;
+						double istart = draw_segment->swall[0] * yscale;
 						double iend = *(swal - 1) * yscale;
 #if 0
 						///This was for avoiding overflow when using fixed point. It might not be needed anymore.
@@ -530,7 +533,7 @@ namespace swrenderer
 						draw_segment->shade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, curline->frontsector->lightlevel) + R_ActualExtraLight(foggy));
 					}
 
-					if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != -1)
+					if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
 					{
 						size_t drawsegnum = draw_segment - drawsegs;
 						InterestingDrawsegs.Push(drawsegnum);
@@ -571,16 +574,16 @@ namespace swrenderer
 		}
 
 		// save sprite clipping info
-		if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == -1)
+		if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == nullptr)
 		{
-			draw_segment->sprtopclip = R_NewOpening(stop - start);
-			memcpy(openings + draw_segment->sprtopclip, &RenderOpaquePass::Instance()->ceilingclip[start], sizeof(short)*(stop - start));
+			draw_segment->sprtopclip = RenderMemory::AllocMemory<short>(stop - start);
+			memcpy(draw_segment->sprtopclip, &RenderOpaquePass::Instance()->ceilingclip[start], sizeof(short)*(stop - start));
 		}
 
-		if (((draw_segment->silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->sprbottomclip == -1)
+		if (((draw_segment->silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->sprbottomclip == nullptr)
 		{
-			draw_segment->sprbottomclip = R_NewOpening(stop - start);
-			memcpy(openings + draw_segment->sprbottomclip, &RenderOpaquePass::Instance()->floorclip[start], sizeof(short)*(stop - start));
+			draw_segment->sprbottomclip = RenderMemory::AllocMemory<short>(stop - start);
+			memcpy(draw_segment->sprbottomclip, &RenderOpaquePass::Instance()->floorclip[start], sizeof(short)*(stop - start));
 		}
 
 		if (maskedtexture && curline->sidedef->GetTexture(side_t::mid).isValid())
@@ -604,9 +607,9 @@ namespace swrenderer
 			pds.x2 = draw_segment->x2;
 			pds.len = pds.x2 - pds.x1;
 			pds.ceilingclip.Resize(pds.len);
-			memcpy(&pds.ceilingclip[0], openings + draw_segment->sprtopclip, pds.len * sizeof(*openings));
+			memcpy(&pds.ceilingclip[0], draw_segment->sprtopclip, pds.len * sizeof(short));
 			pds.floorclip.Resize(pds.len);
-			memcpy(&pds.floorclip[0], openings + draw_segment->sprbottomclip, pds.len * sizeof(*openings));
+			memcpy(&pds.floorclip[0], draw_segment->sprbottomclip, pds.len * sizeof(short));
 
 			for (int i = 0; i < pds.x2 - pds.x1; i++)
 			{
diff --git a/src/swrenderer/r_memory.cpp b/src/swrenderer/r_memory.cpp
index b4faa44cd..5b102c09b 100644
--- a/src/swrenderer/r_memory.cpp
+++ b/src/swrenderer/r_memory.cpp
@@ -33,46 +33,6 @@
 
 namespace swrenderer
 {
-	short *openings;
-
-	namespace
-	{
-		size_t maxopenings;
-		ptrdiff_t lastopening;
-	}
-
-	ptrdiff_t R_NewOpening(ptrdiff_t len)
-	{
-		ptrdiff_t res = lastopening;
-		len = (len + 1) & ~1;	// only return DWORD aligned addresses because some code stores fixed_t's and floats in openings... 
-		lastopening += len;
-		if ((size_t)lastopening > maxopenings)
-		{
-			do
-				maxopenings = maxopenings ? maxopenings * 2 : 16384;
-			while ((size_t)lastopening > maxopenings);
-			openings = (short *)M_Realloc(openings, maxopenings * sizeof(*openings));
-			DPrintf(DMSG_NOTIFY, "MaxOpenings increased to %zu\n", maxopenings);
-		}
-		return res;
-	}
-
-	void R_FreeOpenings()
-	{
-		lastopening = 0;
-	}
-
-	void R_DeinitOpenings()
-	{
-		if (openings != nullptr)
-		{
-			M_Free(openings);
-			openings = nullptr;
-		}
-	}
-
-	/////////////////////////////////////////////////////////////////////////
-	
 	void *RenderMemory::AllocBytes(int size)
 	{
 		size = (size + 15) / 16 * 16; // 16-byte align
diff --git a/src/swrenderer/r_memory.h b/src/swrenderer/r_memory.h
index 0bf86f2cd..dcd00a7a8 100644
--- a/src/swrenderer/r_memory.h
+++ b/src/swrenderer/r_memory.h
@@ -17,14 +17,6 @@
 
 namespace swrenderer
 {
-	struct visplane_light;
-
-	extern short *openings;
-
-	ptrdiff_t R_NewOpening(ptrdiff_t len);
-	void R_FreeOpenings();
-	void R_DeinitOpenings();
-	
 	// Memory needed for the duration of a frame rendering
 	class RenderMemory
 	{
diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp
index 308390c7c..fbe1ad915 100644
--- a/src/swrenderer/scene/r_portal.cpp
+++ b/src/swrenderer/scene/r_portal.cpp
@@ -209,15 +209,16 @@ namespace swrenderer
 			draw_segment->x1 = pl->left;
 			draw_segment->x2 = pl->right;
 			draw_segment->silhouette = SIL_BOTH;
-			draw_segment->sprbottomclip = R_NewOpening(pl->right - pl->left);
-			draw_segment->sprtopclip = R_NewOpening(pl->right - pl->left);
-			draw_segment->maskedtexturecol = ds_p->swall = -1;
+			draw_segment->sprbottomclip = RenderMemory::AllocMemory<short>(pl->right - pl->left);
+			draw_segment->sprtopclip = RenderMemory::AllocMemory<short>(pl->right - pl->left);
+			draw_segment->maskedtexturecol = nullptr;
+			draw_segment->swall = nullptr;
 			draw_segment->bFogBoundary = false;
 			draw_segment->curline = nullptr;
 			draw_segment->fake = 0;
 			draw_segment->foggy = false;
-			memcpy(openings + draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short));
-			memcpy(openings + draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short));
+			memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short));
+			memcpy(draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short));
 
 			VisibleSpriteList::firstvissprite = VisibleSpriteList::vissprite_p;
 			firstdrawseg = draw_segment;
diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp
index 71740aefc..f33c5fa7c 100644
--- a/src/swrenderer/scene/r_scene.cpp
+++ b/src/swrenderer/scene/r_scene.cpp
@@ -138,7 +138,6 @@ namespace swrenderer
 
 		// opening / clipping determination
 		RenderOpaquePass::Instance()->ClearClip();
-		R_FreeOpenings();
 
 		NetUpdate();
 
@@ -274,7 +273,6 @@ namespace swrenderer
 		RenderTranslucentPass::Deinit();
 		VisiblePlaneList::Instance()->Deinit();
 		Clip3DFloors::Instance()->Cleanup();
-		R_DeinitOpenings();
 		R_FreeDrawSegs();
 	}
 
diff --git a/src/swrenderer/scene/r_translucent_pass.cpp b/src/swrenderer/scene/r_translucent_pass.cpp
index 1d46cb831..1490b9dfa 100644
--- a/src/swrenderer/scene/r_translucent_pass.cpp
+++ b/src/swrenderer/scene/r_translucent_pass.cpp
@@ -402,7 +402,7 @@ namespace swrenderer
 			if (ds->fake) continue;
 			// determine if the drawseg obscures the sprite
 			if (ds->x1 >= x2 || ds->x2 <= x1 ||
-				(!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == -1 &&
+				(!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == nullptr &&
 					!ds->bFogBoundary))
 			{
 				// does not cover sprite
@@ -435,7 +435,7 @@ namespace swrenderer
 
 				// seg is behind sprite, so draw the mid texture if it has one
 				if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here
-					(ds->maskedtexturecol != -1 || ds->bFogBoundary))
+					(ds->maskedtexturecol != nullptr || ds->bFogBoundary))
 					R_RenderMaskedSegRange(ds, r1, r2);
 
 				continue;
@@ -449,7 +449,7 @@ namespace swrenderer
 			if (ds->silhouette & SIL_BOTTOM) //bottom sil
 			{
 				clip1 = clipbot + r1;
-				clip2 = openings + ds->sprbottomclip + r1 - ds->x1;
+				clip2 = ds->sprbottomclip + r1 - ds->x1;
 				i = r2 - r1;
 				do
 				{
@@ -463,7 +463,7 @@ namespace swrenderer
 			if (ds->silhouette & SIL_TOP)   // top sil
 			{
 				clip1 = cliptop + r1;
-				clip2 = openings + ds->sprtopclip + r1 - ds->x1;
+				clip2 = ds->sprtopclip + r1 - ds->x1;
 				i = r2 - r1;
 				do
 				{
@@ -555,7 +555,7 @@ namespace swrenderer
 				continue;
 			// kg3D - no fake segs
 			if (ds->fake) continue;
-			if (ds->maskedtexturecol != -1 || ds->bFogBoundary)
+			if (ds->maskedtexturecol != nullptr || ds->bFogBoundary)
 			{
 				R_RenderMaskedSegRange(ds, ds->x1, ds->x2);
 			}
diff --git a/src/swrenderer/segments/r_drawsegment.cpp b/src/swrenderer/segments/r_drawsegment.cpp
index 68f54b05f..160290068 100644
--- a/src/swrenderer/segments/r_drawsegment.cpp
+++ b/src/swrenderer/segments/r_drawsegment.cpp
@@ -196,15 +196,15 @@ namespace swrenderer
 			}
 		}
 
-		short *mfloorclip = openings + ds->sprbottomclip - ds->x1;
-		short *mceilingclip = openings + ds->sprtopclip - ds->x1;
+		short *mfloorclip = ds->sprbottomclip - ds->x1;
+		short *mceilingclip = ds->sprtopclip - ds->x1;
 		double spryscale;
 
 		// [RH] Draw fog partition
 		if (ds->bFogBoundary)
 		{
 			RenderFogBoundary::Render(x1, x2, mceilingclip, mfloorclip, wallshade, rw_light, rw_lightstep, basecolormap);
-			if (ds->maskedtexturecol == -1)
+			if (ds->maskedtexturecol == nullptr)
 			{
 				goto clearfog;
 			}
@@ -214,9 +214,9 @@ namespace swrenderer
 			goto clearfog;
 		}
 
-		MaskedSWall = (float *)(openings + ds->swall) - ds->x1;
+		MaskedSWall = ds->swall - ds->x1;
 		MaskedScaleY = ds->yscale;
-		maskedtexturecol = (fixed_t *)(openings + ds->maskedtexturecol) - ds->x1;
+		maskedtexturecol = ds->maskedtexturecol - ds->x1;
 		spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
 		rw_scalestep = ds->iscalestep;
 
@@ -437,13 +437,13 @@ namespace swrenderer
 			{
 				if (!wrap)
 				{
-					assert(ds->bkup >= 0);
-					memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2 - ds->x1) * 2);
+					assert(ds->bkup != nullptr);
+					memcpy(ds->sprtopclip, ds->bkup, (ds->x2 - ds->x1) * 2);
 				}
 			}
 			else
 			{
-				fillshort(openings + ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
+				fillshort(ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
 			}
 		}
 		return;
@@ -466,11 +466,11 @@ namespace swrenderer
 		rw_lightstep = ds->lightstep;
 		rw_light = ds->light + (x1 - ds->x1) * rw_lightstep;
 
-		short *mfloorclip = openings + ds->sprbottomclip - ds->x1;
-		short *mceilingclip = openings + ds->sprtopclip - ds->x1;
+		short *mfloorclip = ds->sprbottomclip - ds->x1;
+		short *mceilingclip = ds->sprtopclip - ds->x1;
 
 		//double spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
-		float *MaskedSWall = (float *)(openings + ds->swall) - ds->x1;
+		float *MaskedSWall = ds->swall - ds->x1;
 
 		// find positioning
 		side_t *scaledside;
diff --git a/src/swrenderer/segments/r_drawsegment.h b/src/swrenderer/segments/r_drawsegment.h
index 5533ec430..28d1df8d5 100644
--- a/src/swrenderer/segments/r_drawsegment.h
+++ b/src/swrenderer/segments/r_drawsegment.h
@@ -35,11 +35,11 @@ namespace swrenderer
 		bool foggy;
 
 		// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
-		ptrdiff_t sprtopclip; // type short
-		ptrdiff_t sprbottomclip; // type short
-		ptrdiff_t maskedtexturecol; // type short
-		ptrdiff_t swall; // type float
-		ptrdiff_t bkup; // sprtopclip backup, for mid and fake textures
+		short *sprtopclip;
+		short *sprbottomclip;
+		fixed_t *maskedtexturecol;
+		float *swall;
+		short *bkup; // sprtopclip backup, for mid and fake textures
 		
 		FWallTmapVals tmapvals;
 		
diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp
index 203401ec4..9e17b95c8 100644
--- a/src/swrenderer/things/r_decal.cpp
+++ b/src/swrenderer/things/r_decal.cpp
@@ -182,8 +182,8 @@ namespace swrenderer
 			}
 			else
 			{
-				mceilingclip = openings + clipper->sprtopclip - clipper->x1;
-				mfloorclip = openings + clipper->sprbottomclip - clipper->x1;
+				mceilingclip = clipper->sprtopclip - clipper->x1;
+				mfloorclip = clipper->sprbottomclip - clipper->x1;
 			}
 			break;
 
@@ -201,8 +201,8 @@ namespace swrenderer
 			{
 				goto done;
 			}
-			mceilingclip = openings + clipper->sprtopclip - clipper->x1;
-			mfloorclip = openings + clipper->sprbottomclip - clipper->x1;
+			mceilingclip = clipper->sprtopclip - clipper->x1;
+			mfloorclip = clipper->sprbottomclip - clipper->x1;
 			break;
 
 		case RF_CLIPLOWER: