diff --git a/src/r_draw.h b/src/r_draw.h
index 9cde3cf54f4421233ba517996ceee173067a42fe..5780cc62c26d68a124fa5b6dff942bc01e9406a1 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -172,8 +172,6 @@ void R_DrawTranslucentColumn_8(void);
 void R_DrawDropShadowColumn_8(void);
 void R_DrawTranslatedColumn_8(void);
 void R_DrawTranslatedTranslucentColumn_8(void);
-void R_Draw2sMultiPatchColumn_8(void);
-void R_Draw2sMultiPatchTranslucentColumn_8(void);
 void R_DrawFogColumn_8(void);
 void R_DrawColumnShadowed_8(void);
 
diff --git a/src/r_draw8.c b/src/r_draw8.c
index fe7d321dfcf1a1a1c0aa6aabc8ba5169c445acdf..87545f41836761421f2cdf8694c07c88f6815612 100644
--- a/src/r_draw8.c
+++ b/src/r_draw8.c
@@ -105,199 +105,6 @@ void R_DrawColumn_8(void)
 	}
 }
 
-void R_Draw2sMultiPatchColumn_8(void)
-{
-	INT32 count;
-	register UINT8 *dest;
-	register fixed_t frac;
-	fixed_t fracstep;
-
-	count = dc_yh - dc_yl;
-
-	if (count < 0) // Zero length, column does not exceed a pixel.
-		return;
-
-#ifdef RANGECHECK
-	if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
-		return;
-#endif
-
-	// Framebuffer destination address.
-	// Use ylookup LUT to avoid multiply with ScreenWidth.
-	// Use columnofs LUT for subwindows?
-
-	//dest = ylookup[dc_yl] + columnofs[dc_x];
-	dest = &topleft[dc_yl*vid.width + dc_x];
-
-	count++;
-
-	// Determine scaling, which is the only mapping to be done.
-	fracstep = dc_iscale;
-	//frac = dc_texturemid + (dc_yl - centery)*fracstep;
-	frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
-
-	// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
-	// This is as fast as it gets.
-	{
-		register const UINT8 *source = dc_source;
-		register const lighttable_t *colormap = dc_colormap;
-		register INT32 heightmask = dc_texheight-1;
-		register UINT8 val;
-		if (dc_texheight & heightmask)   // not a power of 2 -- killough
-		{
-			heightmask++;
-			heightmask <<= FRACBITS;
-
-			if (frac < 0)
-				while ((frac += heightmask) <  0);
-			else
-				while (frac >= heightmask)
-					frac -= heightmask;
-
-			do
-			{
-				// Re-map color indices from wall texture column
-				//  using a lighting/special effects LUT.
-				// heightmask is the Tutti-Frutti fix
-				val = source[frac>>FRACBITS];
-
-				if (val != TRANSPARENTPIXEL)
-					*dest = colormap[val];
-
-				dest += vid.width;
-
-				// Avoid overflow.
-				if (fracstep > 0x7FFFFFFF - frac)
-					frac += fracstep - heightmask;
-				else
-					frac += fracstep;
-
-				while (frac >= heightmask)
-					frac -= heightmask;
-			} while (--count);
-		}
-		else
-		{
-			while ((count -= 2) >= 0) // texture height is a power of 2
-			{
-				val = source[(frac>>FRACBITS) & heightmask];
-				if (val != TRANSPARENTPIXEL)
-					*dest = colormap[val];
-				dest += vid.width;
-				frac += fracstep;
-				val = source[(frac>>FRACBITS) & heightmask];
-				if (val != TRANSPARENTPIXEL)
-					*dest = colormap[val];
-				dest += vid.width;
-				frac += fracstep;
-			}
-			if (count & 1)
-			{
-				val = source[(frac>>FRACBITS) & heightmask];
-				if (val != TRANSPARENTPIXEL)
-					*dest = colormap[val];
-			}
-		}
-	}
-}
-
-void R_Draw2sMultiPatchTranslucentColumn_8(void)
-{
-	INT32 count;
-	register UINT8 *dest;
-	register fixed_t frac;
-	fixed_t fracstep;
-
-	count = dc_yh - dc_yl;
-
-	if (count < 0) // Zero length, column does not exceed a pixel.
-		return;
-
-#ifdef RANGECHECK
-	if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
-		return;
-#endif
-
-	// Framebuffer destination address.
-	// Use ylookup LUT to avoid multiply with ScreenWidth.
-	// Use columnofs LUT for subwindows?
-
-	//dest = ylookup[dc_yl] + columnofs[dc_x];
-	dest = &topleft[dc_yl*vid.width + dc_x];
-
-	count++;
-
-	// Determine scaling, which is the only mapping to be done.
-	fracstep = dc_iscale;
-	//frac = dc_texturemid + (dc_yl - centery)*fracstep;
-	frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
-
-	// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
-	// This is as fast as it gets.
-	{
-		register const UINT8 *source = dc_source;
-		register const UINT8 *transmap = dc_transmap;
-		register const lighttable_t *colormap = dc_colormap;
-		register INT32 heightmask = dc_texheight-1;
-		register UINT8 val;
-		if (dc_texheight & heightmask)   // not a power of 2 -- killough
-		{
-			heightmask++;
-			heightmask <<= FRACBITS;
-
-			if (frac < 0)
-				while ((frac += heightmask) <  0);
-			else
-				while (frac >= heightmask)
-					frac -= heightmask;
-
-			do
-			{
-				// Re-map color indices from wall texture column
-				//  using a lighting/special effects LUT.
-				// heightmask is the Tutti-Frutti fix
-				val = source[frac>>FRACBITS];
-
-				if (val != TRANSPARENTPIXEL)
-					*dest = *(transmap + (colormap[val]<<8) + (*dest));
-
-				dest += vid.width;
-
-				// Avoid overflow.
-				if (fracstep > 0x7FFFFFFF - frac)
-					frac += fracstep - heightmask;
-				else
-					frac += fracstep;
-
-				while (frac >= heightmask)
-					frac -= heightmask;
-			} while (--count);
-		}
-		else
-		{
-			while ((count -= 2) >= 0) // texture height is a power of 2
-			{
-				val = source[(frac>>FRACBITS) & heightmask];
-				if (val != TRANSPARENTPIXEL)
-					*dest = *(transmap + (colormap[val]<<8) + (*dest));
-				dest += vid.width;
-				frac += fracstep;
-				val = source[(frac>>FRACBITS) & heightmask];
-				if (val != TRANSPARENTPIXEL)
-					*dest = *(transmap + (colormap[val]<<8) + (*dest));
-				dest += vid.width;
-				frac += fracstep;
-			}
-			if (count & 1)
-			{
-				val = source[(frac>>FRACBITS) & heightmask];
-				if (val != TRANSPARENTPIXEL)
-					*dest = *(transmap + (colormap[val]<<8) + (*dest));
-			}
-		}
-	}
-}
-
 /**	\brief The R_DrawShadeColumn_8 function
 	Experiment to make software go faster. Taken from the Boom source
 */
diff --git a/src/r_picformats.c b/src/r_picformats.c
index d4cc9ee4d4219499d715f6b1f596db04f735b95a..7c12949fbcd7788d34a89b2da892725acc604f6c 100644
--- a/src/r_picformats.c
+++ b/src/r_picformats.c
@@ -873,13 +873,15 @@ void *Picture_TextureToFlat(size_t texnum)
 	desttop = converted;
 	deststop = desttop + flatsize;
 
-	if (!texture->holes)
+	for (size_t col = 0; col < (size_t)texture->width; col++, desttop++)
 	{
-		for (size_t col = 0; col < (size_t)texture->width; col++, desttop++)
+		column_t *column = (column_t *)R_GetColumn(texnum, col);
+		for (unsigned i = 0; i < column->num_posts; i++)
 		{
-			source = R_GetColumn(texnum, col)->pixels;
-			dest = desttop;
-			for (size_t ofs = 0; dest < deststop && ofs < (size_t)texture->height; ofs++)
+			post_t *post = &column->posts[i];
+			dest = desttop + (post->topdelta * texture->width);
+			source = column->pixels + post->data_offset;
+			for (size_t ofs = 0; dest < deststop && ofs < post->length; ofs++)
 			{
 				if (source[ofs] != TRANSPARENTPIXEL)
 					*dest = source[ofs];
@@ -887,25 +889,6 @@ void *Picture_TextureToFlat(size_t texnum)
 			}
 		}
 	}
-	else
-	{
-		for (size_t col = 0; col < (size_t)texture->width; col++, desttop++)
-		{
-			column_t *column = (column_t *)R_GetColumn(texnum, col);
-			for (unsigned i = 0; i < column->num_posts; i++)
-			{
-				post_t *post = &column->posts[i];
-				dest = desttop + (post->topdelta * texture->width);
-				source = column->pixels + post->data_offset;
-				for (size_t ofs = 0; dest < deststop && ofs < post->length; ofs++)
-				{
-					if (source[ofs] != TRANSPARENTPIXEL)
-						*dest = source[ofs];
-					dest += texture->width;
-				}
-			}
-		}
-	}
 
 	return converted;
 }
diff --git a/src/r_segs.c b/src/r_segs.c
index 8dc3beec68f07c8469292b9918bbeda89b87a295..35750f9dcf780e8e4c89ba7433e7302ea959a39e 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -96,46 +96,6 @@ void R_ClearSegTables(void)
 // R_RenderMaskedSegRange
 // ==========================================================================
 
-// If we have a multi-patch texture on a 2sided wall (rare) then we draw
-//  it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this
-//  way we don't have to store extra post_t info with each column for
-//  multi-patch textures. They are not normally needed as multi-patch
-//  textures don't have holes in it. At least not for now.
-
-static void R_Render2sidedMultiPatchColumn(column_t *column)
-{
-	INT32 bottomscreen = sprtopscreen + spryscale * lengthcol;
-
-	dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
-	dc_yh = (bottomscreen-1)>>FRACBITS;
-
-	if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
-	{
-		dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
-		dc_yh = (windowbottom - 1)>>FRACBITS;
-	}
-
-	if (dc_yh >= mfloorclip[dc_x])
-		dc_yh =  mfloorclip[dc_x] - 1;
-	if (dc_yl <= mceilingclip[dc_x])
-		dc_yl =  mceilingclip[dc_x] + 1;
-
-	if (dc_yl >= vid.height || dc_yh < 0)
-		return;
-
-	if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
-	{
-		dc_source = column->pixels;
-
-		if (colfunc == colfuncs[BASEDRAWFUNC])
-			(colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])();
-		else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
-			(colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])();
-		else
-			colfunc();
-	}
-}
-
 transnum_t R_GetLinedefTransTable(fixed_t alpha)
 {
 	return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
@@ -211,26 +171,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
 	rw_scalestep = scalestep;
 	spryscale = scale1 + (x1 - ds->x1)*rw_scalestep;
 
-	// Texture must be cached before setting colfunc_2s,
-	// otherwise texture[texnum]->holes may be false when it shouldn't be
+	// Texture must be cached
 	R_CheckTextureCache(texnum);
-	// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
-	// are not stored per-column with post info in SRB2
-	if (textures[texnum]->holes)
-	{
-		if (textures[texnum]->flip & 2) // vertically flipped?
-		{
-			colfunc_2s = R_DrawFlippedMaskedColumn;
-			lengthcol = textures[texnum]->height;
-		}
-		else
-			colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
-	}
-	else
+
+	if (textures[texnum]->flip & 2) // vertically flipped?
 	{
-		colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
+		colfunc_2s = R_DrawFlippedMaskedColumn;
 		lengthcol = textures[texnum]->height;
 	}
+	else
+		colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
 
 	// Setup lighting based on the presence/lack-of 3D floors.
 	dc_numlights = 0;
@@ -784,26 +734,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 
 	dc_texturemid += offsetvalue;
 
-	// Texture must be cached before setting colfunc_2s,
-	// otherwise texture[texnum]->holes may be false when it shouldn't be
+	// Texture must be cached
 	R_CheckTextureCache(texnum);
-	//faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
-	//     are not stored per-column with post info anymore in Doom Legacy
-	if (textures[texnum]->holes)
-	{
-		if (textures[texnum]->flip & 2) // vertically flipped?
-		{
-			colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
-			lengthcol = textures[texnum]->height;
-		}
-		else
-			colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
-	}
-	else
+
+	if (textures[texnum]->flip & 2) // vertically flipped?
 	{
-		colfunc_2s = R_Render2sidedMultiPatchColumn;        //render multipatch with no holes (no post_t info)
+		colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
 		lengthcol = textures[texnum]->height;
 	}
+	else
+		colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
 
 	// Set heights according to plane, or slope, whichever
 	{
diff --git a/src/r_textures.c b/src/r_textures.c
index 01f4a3234c99b4c014c682bc12cb4189231660b2..d27995e8fbc044fe1b5eaa43f966c124fbb2afdf 100644
--- a/src/r_textures.c
+++ b/src/r_textures.c
@@ -326,7 +326,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
 		// If the patch uses transparency, we have to save it this way.
 		if (holey)
 		{
-			texture->holes = true;
 			texture->flip = patch->flip;
 
 			Patch_CalcDataSizes(realpatch, &total_pixels, &total_posts);
@@ -342,7 +341,10 @@ UINT8 *R_GenerateTexture(size_t texnum)
 
 			texturecolumns[texnum] = columns;
 
-			Patch_MakeColumns(realpatch, texture->width, texture->width, blocktex, columns, posts, texture->flip);
+			// Handles flipping as well.
+			// we can't as easily flip the patch vertically sadly though,
+			//  we have wait until the texture itself is drawn to do that
+			Patch_MakeColumns(realpatch, texture->width, texture->width, blocktex, columns, posts, patch->flip & 1);
 
 			goto done;
 		}
@@ -352,7 +354,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
 
 	// multi-patch textures (or 'composite')
 	multipatch:
-	texture->holes = true;
 	texture->flip = 0;
 
 	// To make things easier, I just allocate WxH always
@@ -787,7 +788,6 @@ Rloadflats (INT32 i, INT32 w)
 
 			texture->type = TEXTURETYPE_FLAT;
 			texture->patchcount = 1;
-			texture->holes = false;
 			texture->flip = 0;
 
 			// Allocate information for the texture's patches.
@@ -888,7 +888,6 @@ Rloadtextures (INT32 i, INT32 w)
 
 			texture->type = TEXTURETYPE_SINGLEPATCH;
 			texture->patchcount = 1;
-			texture->holes = false;
 			texture->flip = 0;
 
 			// Allocate information for the texture's patches.
diff --git a/src/r_textures.h b/src/r_textures.h
index ea53efa440f11b64a5b9e78710032a2611d1a36e..eb68ec09f21d4fe8d847b048ac12ba9bd3a1817d 100644
--- a/src/r_textures.h
+++ b/src/r_textures.h
@@ -53,9 +53,8 @@ typedef struct
 	// Keep name for switch changing, etc.
 	char name[8];
 	UINT32 hash;
-	UINT8 type; // TEXTURETYPE_
+	UINT8 type; // TEXTURETYPE_*
 	INT16 width, height;
-	boolean holes;
 	UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
 	void *flat; // The texture, as a flat.
 
diff --git a/src/screen.c b/src/screen.c
index ca59b251dce1f6f1371af433b010a18b4304e621..76f546402ef38e0a4882221945ff602de73aadf9 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -116,8 +116,6 @@ void SCR_SetDrawFuncs(void)
 		colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
 		colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8;
 		colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8;
-		colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8;
-		colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8;
 		colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8;
 
 		spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8;
diff --git a/src/screen.h b/src/screen.h
index e4c1006c35b79a7f9948f818c0a3b03edf84c558..64d92b9d3ef99cf3c4e066ddc5cc9e57edd94afd 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -126,8 +126,6 @@ enum
 	COLDRAWFUNC_SHADE,
 	COLDRAWFUNC_SHADOWED,
 	COLDRAWFUNC_TRANSTRANS,
-	COLDRAWFUNC_TWOSMULTIPATCH,
-	COLDRAWFUNC_TWOSMULTIPATCHTRANS,
 	COLDRAWFUNC_FOG,
 
 	COLDRAWFUNC_MAX