diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e8c9c31820c3ba1fcf46691cff5f4476df98220c..7a6e7871ad55b2a019b5809877ebda167d8d5e8b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -123,7 +123,7 @@ set(SRB2_CORE_RENDER_SOURCES
 	r_sky.c
 	r_splats.c
 	r_things.c
-	r_patch.c
+	r_picformats.c
 	r_portal.c
 
 	r_bsp.h
@@ -138,7 +138,7 @@ set(SRB2_CORE_RENDER_SOURCES
 	r_splats.h
 	r_state.h
 	r_things.h
-	r_patch.h
+	r_picformats.h
 	r_portal.h
 )
 
diff --git a/src/Makefile b/src/Makefile
index c30c236de33ce104c592d319c2b03f5d7daa3df7..282ff8f4f92bd06fd0da247836c9ed2184ebe0bd 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -471,7 +471,7 @@ OBJS:=$(i_main_o) \
 		$(OBJDIR)/r_sky.o    \
 		$(OBJDIR)/r_splats.o \
 		$(OBJDIR)/r_things.o \
-		$(OBJDIR)/r_patch.o \
+		$(OBJDIR)/r_picformats.o \
 		$(OBJDIR)/r_portal.o \
 		$(OBJDIR)/screen.o   \
 		$(OBJDIR)/v_video.o  \
diff --git a/src/dehacked.c b/src/dehacked.c
index 78be8b0b3cd7be63a0dcf8d5ae8ee851570ea375..81690cde994fb7aef56c5873452c7b92a98788f8 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -29,7 +29,7 @@
 #include "p_setup.h"
 #include "r_data.h"
 #include "r_draw.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "r_sky.h"
 #include "fastcmp.h"
 #include "lua_script.h"
diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c
index c47833187b1af03f7308d3844fbcce51baa22bd0..90310a92ff0385310df1a595082ea560a324d8a4 100644
--- a/src/hardware/hw_cache.c
+++ b/src/hardware/hw_cache.c
@@ -30,7 +30,7 @@
 #include "../z_zone.h"
 #include "../v_video.h"
 #include "../r_draw.h"
-#include "../r_patch.h"
+#include "../r_picformats.h"
 #include "../p_setup.h"
 
 // Values set after a call to HWR_ResizeBlock()
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index e8d16c092b93abcc78accf9975eaada6a7f4688e..23e52d19b83d1f4dee0f64faef38edd13f074f5a 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -30,7 +30,7 @@
 #include "../p_local.h"
 #include "../p_setup.h"
 #include "../r_local.h"
-#include "../r_patch.h"
+#include "../r_picformats.h"
 #include "../r_bsp.h"
 #include "../d_clisrv.h"
 #include "../w_wad.h"
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index b617a7a14d5885c45ddcac5a22c854733991680d..39c385102f3f4bfd433ffd054fbc534360f3c880 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -18,7 +18,7 @@
 #include "p_mobj.h"
 #include "p_local.h"
 #include "z_zone.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "r_things.h"
 #include "doomstat.h" // luabanks[]
 
diff --git a/src/p_setup.c b/src/p_setup.c
index 42a6438a0f46996927ce5ec723bf51a06b6ff072..eca5413b48fa0854ddb4e208edf5f92c33d380c8 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -28,7 +28,7 @@
 
 #include "r_data.h"
 #include "r_things.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "r_sky.h"
 #include "r_draw.h"
 
@@ -574,6 +574,8 @@ Ploadflat (levelflat_t *levelflat, const char *flatname)
 
 	lumpnum_t    flatnum;
 	int       texturenum;
+	patch_t   *flatpatch;
+	size_t    lumplength;
 
 	size_t i;
 
@@ -635,7 +637,9 @@ texturefound:
 	{
 flatfound:
 		/* This could be a flat, patch, or PNG. */
-		if (R_CheckIfPatch(flatnum))
+		flatpatch = W_CacheLumpNum(flatnum, PU_STATIC);
+		lumplength = W_LumpLength(flatnum);
+		if (R_CheckIfPatch(flatpatch, lumplength))
 			levelflat->type = LEVELFLAT_PATCH;
 		else
 		{
@@ -644,8 +648,10 @@ flatfound:
 			Only need eight bytes for PNG headers.
 			FIXME: Put this elsewhere.
 			*/
+			if (flatpatch)
+				Z_Free(flatpatch);
 			W_ReadLumpHeader(flatnum, buffer, 8, 0);
-			if (R_IsLumpPNG(buffer, W_LumpLength(flatnum)))
+			if (R_IsLumpPNG(buffer, lumplength))
 				levelflat->type = LEVELFLAT_PNG;
 			else
 #endif/*NO_PNG_LUMPS*/
diff --git a/src/r_data.c b/src/r_data.c
index 986b65deaca333a80d059d72f7875fd6c575116b..14c04f15e32e93797e758efebb2ee361ab95bcfc 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -19,7 +19,7 @@
 #include "p_local.h"
 #include "m_misc.h"
 #include "r_data.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "w_wad.h"
 #include "z_zone.h"
 #include "p_setup.h" // levelflats
diff --git a/src/r_patch.c b/src/r_picformats.c
similarity index 67%
rename from src/r_patch.c
rename to src/r_picformats.c
index 18dfe523a9c4f80d1b39ed65414c9101e63dd14a..8e229c4a6ea4def0226dbc07a855459a718c17b3 100644
--- a/src/r_patch.c
+++ b/src/r_picformats.c
@@ -2,23 +2,24 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 2005-2009 by Andrey "entryway" Budko.
-// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos.
-// Copyright (C) 2019      by Sonic Team Junior.
+// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos.
+// Copyright (C) 2019-2020 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
 // See the 'LICENSE' file for more details.
 //-----------------------------------------------------------------------------
-/// \file  r_patch.c
-/// \brief Patch generation.
+/// \file  r_picformats.c
+/// \brief Picture generation.
 
 #include "byteptr.h"
 #include "dehacked.h"
 #include "i_video.h"
 #include "r_data.h"
 #include "r_draw.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "r_things.h"
+#include "v_video.h"
 #include "z_zone.h"
 #include "w_wad.h"
 
@@ -52,29 +53,549 @@ static unsigned char imgbuf[1<<26];
 fixed_t cosang2rad[ROTANGLES];
 fixed_t sinang2rad[ROTANGLES];
 
-//
-// R_CheckIfPatch
-//
-// Returns true if the lump is a valid patch.
-//
-boolean R_CheckIfPatch(lumpnum_t lump)
+/** Converts a picture between two formats.
+  *
+  * \param informat Input picture format.
+  * \param picture Input picture data.
+  * \param outformat Output picture format.
+  * \param insize Input picture size.
+  * \param outsize Output picture size.
+  * \param inwidth Input picture width.
+  * \param inheight Input picture height.
+  * \param inleftoffset Input picture left offset, for patches.
+  * \param intopoffset Input picture top offset, for patches.
+  * \param flags Input picture flags.
+  * \return A pointer to the converted picture.
+  */
+void *Picture_Convert(
+	pictureformat_t informat, void *picture, pictureformat_t outformat,
+	size_t insize, size_t *outsize,
+	INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
+	pictureflags_t flags)
+{
+	if (informat == outformat) // wut?
+		I_Error("Picture_Convert: input and output formats are the same!");
+
+	if (Picture_IsPatchFormat(outformat))
+		return Picture_PatchConvert(informat, picture, outformat, insize, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
+	else if (Picture_IsFlatFormat(outformat))
+		return Picture_FlatConvert(informat, picture, outformat, insize, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
+	else
+		I_Error("Picture_Convert: unsupported input format!");
+
+	return NULL;
+}
+
+/** Converts a picture to a patch.
+  *
+  * \param informat Input picture format.
+  * \param picture Input picture data.
+  * \param outformat Output picture format.
+  * \param insize Input picture size.
+  * \param outsize Output picture size.
+  * \param inwidth Input picture width.
+  * \param inheight Input picture height.
+  * \param inleftoffset Input picture left offset, for patches.
+  * \param intopoffset Input picture top offset, for patches.
+  * \param flags Input picture flags.
+  * \return A pointer to the converted picture.
+  */
+void *Picture_PatchConvert(
+	pictureformat_t informat, void *picture, pictureformat_t outformat,
+	size_t insize, size_t *outsize,
+	INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
+	pictureflags_t flags)
+{
+	UINT32 x, y;
+	UINT8 *img;
+	UINT8 *imgptr = imgbuf;
+	UINT8 *colpointers, *startofspan;
+	size_t size = 0;
+	patch_t *inpatch = NULL;
+	INT32 inbpp = Picture_FormatBPP(informat);
+
+	if (informat == outformat)
+		I_Error("Picture_PatchConvert: input and output formats are the same!");
+
+	if (!inbpp)
+		I_Error("Picture_PatchConvert: unknown input bits per pixel?!");
+
+	(void)insize; // ignore
+
+	// If it's a patch, you can just figure out
+	// the dimensions from the header.
+	if (Picture_IsPatchFormat(informat))
+	{
+		inpatch = (patch_t *)picture;
+		inwidth = SHORT(inpatch->width);
+		inheight = SHORT(inpatch->height);
+		inleftoffset = SHORT(inpatch->leftoffset);
+		intopoffset = SHORT(inpatch->topoffset);
+	}
+
+	// Write image size and offset
+	WRITEINT16(imgptr, inwidth);
+	WRITEINT16(imgptr, inheight);
+	WRITEINT16(imgptr, inleftoffset);
+	WRITEINT16(imgptr, intopoffset);
+
+	// Leave placeholder to column pointers
+	colpointers = imgptr;
+	imgptr += inwidth*4;
+
+	// Write columns
+	for (x = 0; x < inwidth; x++)
+	{
+		int lastStartY = 0;
+		int spanSize = 0;
+		startofspan = NULL;
+
+		// Write column pointer
+		WRITEINT32(colpointers, imgptr - imgbuf);
+
+		// Write pixels
+		for (y = 0; y < inheight; y++)
+		{
+			void *input = NULL;
+			boolean opaque = false;
+
+			// Read pixel
+			if (Picture_IsPatchFormat(informat))
+				input = Picture_GetPatchPixel(inpatch, informat, x, y, flags);
+			else if (Picture_IsFlatFormat(informat))
+			{
+				size_t offs = ((y * inwidth) + x);
+				switch (informat)
+				{
+					case PICFMT_FLAT32:
+						input = picture + (offs * 4);
+						break;
+					case PICFMT_FLAT16:
+						input = picture + (offs * 2);
+						break;
+					case PICFMT_FLAT:
+						input = picture + offs;
+						break;
+					default:
+						I_Error("Picture_PatchConvert: unsupported flat input format!");
+						break;
+				}
+			}
+			else
+				I_Error("Picture_PatchConvert: unsupported input format!");
+
+			// Determine opacity
+			if (input != NULL)
+			{
+				UINT8 alpha = 0xFF;
+				if (inbpp == 32)
+				{
+					RGBA_t px = *(RGBA_t *)input;
+					alpha = px.s.alpha;
+				}
+				else if (inbpp == 16)
+				{
+					UINT16 px = *(UINT16 *)input;
+					alpha = (px & 0xFF00) >> 8;
+				}
+				else if (inbpp == 8)
+				{
+					UINT8 px = *(UINT8 *)input;
+					if (px == TRANSPARENTPIXEL)
+						alpha = 0;
+				}
+				opaque = (alpha > 1);
+			}
+
+			// End span if we have a transparent pixel
+			if (!opaque)
+			{
+				if (startofspan)
+					WRITEUINT8(imgptr, 0);
+				startofspan = NULL;
+				continue;
+			}
+
+			// Start new column if we need to
+			if (!startofspan || spanSize == 255)
+			{
+				int writeY = y;
+
+				// If we reached the span size limit, finish the previous span
+				if (startofspan)
+					WRITEUINT8(imgptr, 0);
+
+				if (y > 254)
+				{
+					// Make sure we're aligned to 254
+					if (lastStartY < 254)
+					{
+						WRITEUINT8(imgptr, 254);
+						WRITEUINT8(imgptr, 0);
+						imgptr += 2;
+						lastStartY = 254;
+					}
+
+					// Write stopgap empty spans if needed
+					writeY = y - lastStartY;
+
+					while (writeY > 254)
+					{
+						WRITEUINT8(imgptr, 254);
+						WRITEUINT8(imgptr, 0);
+						imgptr += 2;
+						writeY -= 254;
+					}
+				}
+
+				startofspan = imgptr;
+				WRITEUINT8(imgptr, writeY);
+				imgptr += 2;
+				spanSize = 0;
+
+				lastStartY = y;
+			}
+
+			// Write the pixel
+			switch (outformat)
+			{
+				case PICFMT_PATCH32:
+				{
+					if (inbpp == 32)
+					{
+						RGBA_t out = *(RGBA_t *)input;
+						WRITEUINT32(imgptr, out.rgba);
+					}
+					else if (inbpp == 16)
+					{
+						RGBA_t out = pMasterPalette[*((UINT16 *)input) & 0xFF];
+						WRITEUINT32(imgptr, out.rgba);
+					}
+					else // PICFMT_PATCH
+					{
+						RGBA_t out = pMasterPalette[*((UINT8 *)input) & 0xFF];
+						WRITEUINT32(imgptr, out.rgba);
+					}
+					break;
+				}
+				case PICFMT_PATCH16:
+					if (inbpp == 32)
+					{
+						RGBA_t in = *(RGBA_t *)input;
+						UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
+						WRITEUINT16(imgptr, (0xFF00 | out));
+					}
+					else if (inbpp == 16)
+						WRITEUINT16(imgptr, *(UINT16 *)input);
+					else // PICFMT_PATCH
+						WRITEUINT16(imgptr, (0xFF00 | (*(UINT8 *)input)));
+					break;
+				default: // PICFMT_PATCH
+				{
+					if (inbpp == 32)
+					{
+						RGBA_t in = *(RGBA_t *)input;
+						UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
+						WRITEUINT8(imgptr, out);
+					}
+					else if (inbpp == 16)
+					{
+						UINT16 out = *(UINT16 *)input;
+						WRITEUINT8(imgptr, (out & 0xFF));
+					}
+					else // PICFMT_PATCH
+						WRITEUINT8(imgptr, *(UINT8 *)input);
+					break;
+				}
+			}
+
+			spanSize++;
+			startofspan[1] = spanSize;
+		}
+
+		if (startofspan)
+			WRITEUINT8(imgptr, 0);
+
+		WRITEUINT8(imgptr, 0xFF);
+	}
+
+	size = imgptr-imgbuf;
+	img = Z_Malloc(size, PU_STATIC, NULL);
+	memcpy(img, imgbuf, size);
+
+	if (outsize != NULL)
+		*outsize = size;
+	return img;
+}
+
+/** Converts a picture to a flat.
+  *
+  * \param informat Input picture format.
+  * \param picture Input picture data.
+  * \param outformat Output picture format.
+  * \param insize Input picture size.
+  * \param outsize Output picture size.
+  * \param inwidth Input picture width.
+  * \param inheight Input picture height.
+  * \param inleftoffset Input picture left offset, for patches.
+  * \param intopoffset Input picture top offset, for patches.
+  * \param flags Input picture flags.
+  * \return A pointer to the converted picture.
+  */
+void *Picture_FlatConvert(
+	pictureformat_t informat, void *picture, pictureformat_t outformat,
+	size_t insize, size_t *outsize,
+	INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
+	pictureflags_t flags)
 {
+	void *outflat;
+	patch_t *inpatch = NULL;
+	INT32 inbpp = Picture_FormatBPP(informat);
+	INT32 outbpp = Picture_FormatBPP(outformat);
+	INT32 x, y;
 	size_t size;
+
+	if (informat == outformat)
+		I_Error("Picture_FlatConvert: input and output formats are the same!");
+
+	if (!inbpp)
+		I_Error("Picture_FlatConvert: unknown input bits per pixel?!");
+	if (!outbpp)
+		I_Error("Picture_FlatConvert: unknown output bits per pixel?!");
+
+	// If it's a patch, you can just figure out
+	// the dimensions from the header.
+	if (Picture_IsPatchFormat(informat))
+	{
+		inpatch = (patch_t *)picture;
+		inwidth = SHORT(inpatch->width);
+		inheight = SHORT(inpatch->height);
+		inleftoffset = SHORT(inpatch->leftoffset);
+		intopoffset = SHORT(inpatch->topoffset);
+	}
+
+	size = (inwidth * inheight) * (outbpp / 8);
+	outflat = Z_Calloc(size, PU_STATIC, NULL);
+	if (outsize)
+		*outsize = size;
+
+	// Set transparency
+	if (outbpp == 8)
+		memset(outflat, TRANSPARENTPIXEL, size);
+
+	for (y = 0; y < inheight; y++)
+		for (x = 0; x < inwidth; x++)
+		{
+			void *input;
+			size_t offs = ((y * inwidth) + x);
+
+			// Read pixel
+			if (Picture_IsPatchFormat(informat))
+				input = Picture_GetPatchPixel(inpatch, informat, x, y, flags);
+			else if (Picture_IsFlatFormat(informat))
+				input = picture + (offs * (inbpp / 8));
+			else
+				I_Error("Picture_FlatConvert: unsupported input format!");
+
+			if (!input)
+				continue;
+
+			switch (outformat)
+			{
+				case PICFMT_FLAT32:
+				{
+					UINT32 *f32 = (UINT32 *)outflat;
+					if (inbpp == 32)
+					{
+						RGBA_t out = *(RGBA_t *)input;
+						f32[offs] = out.rgba;
+					}
+					else if (inbpp == 16)
+					{
+						RGBA_t out = pMasterPalette[*((UINT16 *)input) & 0xFF];
+						f32[offs] = out.rgba;
+					}
+					else // PICFMT_PATCH
+					{
+						RGBA_t out = pMasterPalette[*((UINT8 *)input) & 0xFF];
+						f32[offs] = out.rgba;
+					}
+					break;
+				}
+				case PICFMT_FLAT16:
+				{
+					UINT16 *f16 = (UINT16 *)outflat;
+					if (inbpp == 32)
+					{
+						RGBA_t in = *(RGBA_t *)input;
+						UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
+						f16[offs] = (0xFF00 | out);
+					}
+					else if (inbpp == 16)
+						f16[offs] = *(UINT16 *)input;
+					else // PICFMT_PATCH
+						f16[offs] = (0xFF00 | *((UINT8 *)input));
+					break;
+				}
+				case PICFMT_FLAT:
+				{
+					UINT8 *f8 = (UINT8 *)outflat;
+					if (inbpp == 32)
+					{
+						RGBA_t in = *(RGBA_t *)input;
+						UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
+						f8[offs] = out;
+					}
+					else if (inbpp == 16)
+					{
+						UINT16 out = *(UINT16 *)input;
+						f8[offs] = (out & 0xFF);
+					}
+					else // PICFMT_PATCH
+						f8[offs] = *(UINT8 *)input;
+					break;
+				}
+				default:
+					I_Error("Picture_FlatConvert: unsupported output format!");
+			}
+		}
+
+	return outflat;
+}
+
+/** Returns a pixel from a patch.
+  *
+  * \param patch Input patch.
+  * \param informat Input picture format.
+  * \param x Pixel X position.
+  * \param y Pixel Y position.
+  * \param flags Input picture flags.
+  * \return A pointer to a pixel in the patch. Returns NULL if not opaque.
+  */
+void *Picture_GetPatchPixel(
+	patch_t *patch, pictureformat_t informat,
+	INT32 x, INT32 y,
+	pictureflags_t flags)
+{
+	fixed_t ofs;
+	column_t *column;
+	UINT8 *s8;
+	UINT16 *s16;
+	UINT32 *s32;
+
+	if (patch == NULL)
+		I_Error("Picture_GetPatchPixel: patch == NULL");
+
+	if (x >= 0 && x < SHORT(patch->width))
+	{
+		INT32 topdelta, prevdelta = -1;
+		INT32 columnofs = 0;
+
+		if (flags & PICFLAGS_XFLIP)
+			columnofs = LONG(patch->columnofs[(SHORT(patch->width)-1)-x]);
+		else
+			columnofs = LONG(patch->columnofs[x]);
+
+		// Column offsets are pointers so no casting required
+		column = (column_t *)((UINT8 *)patch + columnofs);
+
+		while (column->topdelta != 0xff)
+		{
+			topdelta = column->topdelta;
+			if (topdelta <= prevdelta)
+				topdelta += prevdelta;
+			prevdelta = topdelta;
+			s8 = (UINT8 *)(column) + 3;
+			if (informat == PICFMT_PATCH32)
+				s32 = (UINT32 *)s8;
+			else if (informat == PICFMT_PATCH16)
+				s16 = (UINT16 *)s8;
+			for (ofs = 0; ofs < column->length; ofs++)
+			{
+				if ((topdelta + ofs) == y)
+				{
+					if (informat == PICFMT_PATCH32)
+						return (s32 + ofs);
+					else if (informat == PICFMT_PATCH16)
+						return (s16 + ofs);
+					else // PICFMT_PATCH
+						return (s8 + ofs);
+				}
+			}
+			column = (column_t *)((UINT8 *)column + column->length + 4);
+		}
+	}
+
+	return NULL;
+}
+
+/** Returns the amount of bits per pixel in the specified picture format.
+  *
+  * \param format Input picture format.
+  * \return The bits per pixel amount of the picture format.
+  */
+INT32 Picture_FormatBPP(pictureformat_t format)
+{
+	INT32 bpp = 0;
+	switch (format)
+	{
+		case PICFMT_PATCH32:
+		case PICFMT_FLAT32:
+		case PICFMT_PNG:
+			bpp = 32;
+			break;
+		case PICFMT_PATCH16:
+		case PICFMT_FLAT16:
+			bpp = 16;
+			break;
+		case PICFMT_PATCH:
+		case PICFMT_FLAT:
+			bpp = 8;
+			break;
+		default:
+			break;
+	}
+	return bpp;
+}
+
+/** Checks if the specified picture format is a patch.
+  *
+  * \param format Input picture format.
+  * \return True if the picture format is a patch, false if not.
+  */
+boolean Picture_IsPatchFormat(pictureformat_t format)
+{
+	return (format == PICFMT_PATCH || format == PICFMT_PATCH16 || format == PICFMT_PATCH32);
+}
+
+/** Checks if the specified picture format is a flat.
+  *
+  * \param format Input picture format.
+  * \return True if the picture format is a flat, false if not.
+  */
+boolean Picture_IsFlatFormat(pictureformat_t format)
+{
+	return (format == PICFMT_FLAT || format == PICFMT_FLAT16 || format == PICFMT_FLAT32);
+}
+
+/** Returns true if the lump is a valid patch.
+  * PICFMT_PATCH only, I think??
+  *
+  * \param patch Input patch.
+  * \param picture Input patch size.
+  * \return True if the input patch is valid.
+  */
+boolean R_CheckIfPatch(patch_t *patch, size_t size)
+{
 	INT16 width, height;
-	patch_t *patch;
 	boolean result;
 
-	size = W_LumpLength(lump);
-
 	// minimum length of a valid Doom patch
 	if (size < 13)
 		return false;
 
-	patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC);
-
 	width = SHORT(patch->width);
 	height = SHORT(patch->height);
-
 	result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < (INT16)(size / 4));
 
 	if (result)
@@ -168,36 +689,10 @@ void R_TextureToFlat(size_t tex, UINT8 *flat)
 //
 void R_PatchToFlat(patch_t *patch, UINT8 *flat)
 {
-	fixed_t col, ofs;
-	column_t *column;
-	UINT8 *desttop, *dest, *deststop;
-	UINT8 *source;
-
-	desttop = flat;
-	deststop = desttop + (SHORT(patch->width) * SHORT(patch->height));
-
-	for (col = 0; col < SHORT(patch->width); col++, desttop++)
-	{
-		INT32 topdelta, prevdelta = -1;
-		column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col]));
-
-		while (column->topdelta != 0xff)
-		{
-			topdelta = column->topdelta;
-			if (topdelta <= prevdelta)
-				topdelta += prevdelta;
-			prevdelta = topdelta;
-
-			dest = desttop + (topdelta * SHORT(patch->width));
-			source = (UINT8 *)(column) + 3;
-			for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
-			{
-				*dest = source[ofs];
-				dest += SHORT(patch->width);
-			}
-			column = (column_t *)((UINT8 *)column + column->length + 4);
-		}
-	}
+	size_t outsize = 0;
+	UINT8 *converted = Picture_FlatConvert(PICFMT_PATCH, patch, PICFMT_FLAT, 0, &outsize, 0, 0, 0, 0, 0);
+	M_Memcpy(flat, converted, outsize);
+	Z_Free(converted);
 }
 
 //
@@ -207,34 +702,10 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat)
 //
 void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip)
 {
-	fixed_t col, ofs;
-	column_t *column;
-	UINT16 *desttop, *dest, *deststop;
-	UINT8 *source;
-
-	desttop = raw;
-	deststop = desttop + (SHORT(patch->width) * SHORT(patch->height));
-
-	for (col = 0; col < SHORT(patch->width); col++, desttop++)
-	{
-		INT32 topdelta, prevdelta = -1;
-		column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-col) : col]));
-		while (column->topdelta != 0xff)
-		{
-			topdelta = column->topdelta;
-			if (topdelta <= prevdelta)
-				topdelta += prevdelta;
-			prevdelta = topdelta;
-			dest = desttop + (topdelta * SHORT(patch->width));
-			source = (UINT8 *)(column) + 3;
-			for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
-			{
-				*dest = source[ofs];
-				dest += SHORT(patch->width);
-			}
-			column = (column_t *)((UINT8 *)column + column->length + 4);
-		}
-	}
+	size_t outsize = 0;
+	UINT16 *converted = Picture_FlatConvert(PICFMT_PATCH, patch, PICFMT_FLAT16, 0, &outsize, 0, 0, 0, 0, (flip) ? PICFLAGS_XFLIP : 0);
+	M_Memcpy(raw, converted, outsize);
+	Z_Free(converted);
 }
 
 //
@@ -244,108 +715,8 @@ void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip)
 //
 patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency)
 {
-	UINT32 x, y;
-	UINT8 *img;
-	UINT8 *imgptr = imgbuf;
-	UINT8 *colpointers, *startofspan;
-	size_t size = 0;
-
-	// Write image size and offset
-	WRITEINT16(imgptr, width);
-	WRITEINT16(imgptr, height);
-	WRITEINT16(imgptr, leftoffset);
-	WRITEINT16(imgptr, topoffset);
-
-	// Leave placeholder to column pointers
-	colpointers = imgptr;
-	imgptr += width*4;
-
-	// Write columns
-	for (x = 0; x < width; x++)
-	{
-		int lastStartY = 0;
-		int spanSize = 0;
-		startofspan = NULL;
-
-		// Write column pointer
-		WRITEINT32(colpointers, imgptr - imgbuf);
-
-		// Write pixels
-		for (y = 0; y < height; y++)
-		{
-			UINT8 paletteIndex = raw[((y * width) + x)];
-			boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
-
-			// End span if we have a transparent pixel
-			if (!opaque)
-			{
-				if (startofspan)
-					WRITEUINT8(imgptr, 0);
-				startofspan = NULL;
-				continue;
-			}
-
-			// Start new column if we need to
-			if (!startofspan || spanSize == 255)
-			{
-				int writeY = y;
-
-				// If we reached the span size limit, finish the previous span
-				if (startofspan)
-					WRITEUINT8(imgptr, 0);
-
-				if (y > 254)
-				{
-					// Make sure we're aligned to 254
-					if (lastStartY < 254)
-					{
-						WRITEUINT8(imgptr, 254);
-						WRITEUINT8(imgptr, 0);
-						imgptr += 2;
-						lastStartY = 254;
-					}
-
-					// Write stopgap empty spans if needed
-					writeY = y - lastStartY;
-
-					while (writeY > 254)
-					{
-						WRITEUINT8(imgptr, 254);
-						WRITEUINT8(imgptr, 0);
-						imgptr += 2;
-						writeY -= 254;
-					}
-				}
-
-				startofspan = imgptr;
-				WRITEUINT8(imgptr, writeY);
-				imgptr += 2;
-				spanSize = 0;
-
-				lastStartY = y;
-			}
-
-			// Write the pixel
-			WRITEUINT8(imgptr, paletteIndex);
-			spanSize++;
-			startofspan[1] = spanSize;
-		}
-
-		if (startofspan)
-			WRITEUINT8(imgptr, 0);
-
-		WRITEUINT8(imgptr, 0xFF);
-	}
-
-	size = imgptr-imgbuf;
-	img = Z_Malloc(size, PU_STATIC, NULL);
-	memcpy(img, imgbuf, size);
-
-	Z_Free(raw);
-
-	if (destsize != NULL)
-		*destsize = size;
-	return (patch_t *)img;
+	(void)transparency;
+	return (patch_t *)Picture_Convert(PICFMT_FLAT, raw, PICFMT_PATCH, 0, destsize, width, height, leftoffset, topoffset, 0);
 }
 
 //
@@ -355,107 +726,7 @@ patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffse
 //
 patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *size)
 {
-	UINT32 x, y;
-	UINT8 *img;
-	UINT8 *imgptr = imgbuf;
-	UINT8 *colpointers, *startofspan;
-
-	if (!raw)
-		return NULL;
-
-	// Write image size and offset
-	WRITEINT16(imgptr, width);
-	WRITEINT16(imgptr, height);
-	// no offsets
-	WRITEINT16(imgptr, 0);
-	WRITEINT16(imgptr, 0);
-
-	// Leave placeholder to column pointers
-	colpointers = imgptr;
-	imgptr += width*4;
-
-	// Write columns
-	for (x = 0; x < width; x++)
-	{
-		int lastStartY = 0;
-		int spanSize = 0;
-		startofspan = NULL;
-
-		// Write column pointer
-		WRITEINT32(colpointers, imgptr - imgbuf);
-
-		// Write pixels
-		for (y = 0; y < height; y++)
-		{
-			UINT16 pixel = raw[((y * width) + x)];
-			UINT8 paletteIndex = (pixel & 0xFF);
-			UINT8 opaque = (pixel != 0xFF00); // If 1, we have a pixel
-
-			// End span if we have a transparent pixel
-			if (!opaque)
-			{
-				if (startofspan)
-					WRITEUINT8(imgptr, 0);
-				startofspan = NULL;
-				continue;
-			}
-
-			// Start new column if we need to
-			if (!startofspan || spanSize == 255)
-			{
-				int writeY = y;
-
-				// If we reached the span size limit, finish the previous span
-				if (startofspan)
-					WRITEUINT8(imgptr, 0);
-
-				if (y > 254)
-				{
-					// Make sure we're aligned to 254
-					if (lastStartY < 254)
-					{
-						WRITEUINT8(imgptr, 254);
-						WRITEUINT8(imgptr, 0);
-						imgptr += 2;
-						lastStartY = 254;
-					}
-
-					// Write stopgap empty spans if needed
-					writeY = y - lastStartY;
-
-					while (writeY > 254)
-					{
-						WRITEUINT8(imgptr, 254);
-						WRITEUINT8(imgptr, 0);
-						imgptr += 2;
-						writeY -= 254;
-					}
-				}
-
-				startofspan = imgptr;
-				WRITEUINT8(imgptr, writeY);
-				imgptr += 2;
-				spanSize = 0;
-
-				lastStartY = y;
-			}
-
-			// Write the pixel
-			WRITEUINT8(imgptr, paletteIndex);
-			spanSize++;
-			startofspan[1] = spanSize;
-		}
-
-		if (startofspan)
-			WRITEUINT8(imgptr, 0);
-
-		WRITEUINT8(imgptr, 0xFF);
-	}
-
-	*size = imgptr-imgbuf;
-	img = Z_Malloc(*size, PU_STATIC, NULL);
-	memcpy(img, imgbuf, *size);
-	return (patch_t *)img;
+	return (patch_t *)Picture_Convert(PICFMT_FLAT16, raw, PICFMT_PATCH, 0, size, width, height, 0, 0, 0);
 }
 
 //
@@ -649,19 +920,24 @@ static png_bytep *PNG_Read(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoff
 }
 
 // Convert a PNG to a raw image.
-static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
+static void *PNG_Convert(const UINT8 *png, INT32 outbpp, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
 {
-	UINT8 *flat;
+	void *flat;
 	png_uint_32 x, y;
 	png_bytep *row_pointers = PNG_Read(png, w, h, topoffset, leftoffset, size);
 	png_uint_32 width = *w, height = *h;
 
+	if (!outbpp)
+		I_Error("PNG_Convert: unknown output bits per pixel?!");
+
 	if (!row_pointers)
-		I_Error("PNG_RawConvert: conversion failed");
+		I_Error("PNG_Convert: conversion failed!");
+
+	// Convert the image
+	flat = Z_Malloc((width * height) * (outbpp / 8), PU_STATIC, NULL);
+	if (outbpp == 8)
+		memset(flat, TRANSPARENTPIXEL, (width * height));
 
-	// Convert the image to 8bpp
-	flat = Z_Malloc(width * height, PU_LEVEL, NULL);
-	memset(flat, TRANSPARENTPIXEL, width * height);
 	for (y = 0; y < height; y++)
 	{
 		png_bytep row = row_pointers[y];
@@ -669,7 +945,36 @@ static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topo
 		{
 			png_bytep px = &(row[x * 4]);
 			if ((UINT8)px[3])
-				flat[((y * width) + x)] = NearestColor((UINT8)px[0], (UINT8)px[1], (UINT8)px[2]);
+			{
+				UINT8 red = (UINT8)px[0];
+				UINT8 green = (UINT8)px[1];
+				UINT8 blue = (UINT8)px[2];
+				UINT8 alpha = (UINT8)px[3];
+				if (outbpp == 32)
+				{
+					UINT32 *outflat = (UINT32 *)flat;
+					RGBA_t out;
+					out.s.red = red;
+					out.s.green = green;
+					out.s.blue = blue;
+					out.s.alpha = alpha;
+					outflat[((y * width) + x)] = out.rgba;
+				}
+				else
+				{
+					UINT8 palidx = NearestColor(red, green, blue);
+					if (outbpp == 16)
+					{
+						UINT16 *outflat = (UINT16 *)flat;
+						outflat[((y * width) + x)] = (alpha << 8) | palidx;
+					}
+					else // 8bpp
+					{
+						UINT8 *outflat = (UINT8 *)flat;
+						outflat[((y * width) + x)] = palidx;
+					}
+				}
+			}
 		}
 	}
 	free(row_pointers);
@@ -684,7 +989,7 @@ static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topo
 //
 UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size)
 {
-	return PNG_RawConvert(png, width, height, NULL, NULL, size);
+	return PNG_Convert(png, 8, width, height, NULL, NULL, size);
 }
 
 //
@@ -696,12 +1001,16 @@ patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean t
 {
 	UINT16 width, height;
 	INT16 topoffset = 0, leftoffset = 0;
-	UINT8 *raw = PNG_RawConvert(png, &width, &height, &topoffset, &leftoffset, size);
+	UINT8 *raw = PNG_Convert(png, 32, &width, &height, &topoffset, &leftoffset, size);
+	patch_t *output;
 
+	(void)transparency;
 	if (!raw)
 		I_Error("R_PNGToPatch: conversion failed");
 
-	return R_FlatToPatch(raw, width, height, leftoffset, topoffset, destsize, transparency);
+	output = Picture_Convert(PICFMT_FLAT32, raw, PICFMT_PATCH, 0, destsize, width, height, leftoffset, topoffset, 0);
+	Z_Free(raw);
+	return output;
 }
 
 //
@@ -1110,13 +1419,12 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps)
 //
 void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip)
 {
-	UINT32 i;
 	INT32 angle;
 	patch_t *patch;
 	patch_t *newpatch;
-	UINT16 *rawsrc, *rawdst;
-	size_t size, size2;
-	INT32 bflip = (flip != 0x00);
+	UINT16 *rawdst;
+	size_t size;
+	pictureflags_t bflip = (flip) ? PICFLAGS_XFLIP : 0;
 
 #define SPRITE_XCENTER (leftoffset)
 #define SPRITE_YCENTER (height / 2)
@@ -1130,14 +1438,18 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 		INT32 width, height, leftoffset;
 		fixed_t ca, sa;
 		lumpnum_t lump = sprframe->lumppat[rot];
+		size_t lumplength;
 
 		if (lump == LUMPERROR)
 			return;
+
+		patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC);
+		lumplength = W_LumpLength(lump);
+
 		// Because there's something wrong with SPR_DFLM, I guess
-		if (!R_CheckIfPatch(lump))
+		if (!R_CheckIfPatch(patch, lumplength))
 			return;
 
-		patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC);
 		width = patch->width;
 		height = patch->height;
 		leftoffset = patch->leftoffset;
@@ -1160,16 +1472,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 			leftoffset = width - leftoffset;
 		}
 
-		// Draw the sprite to a temporary buffer.
-		size = (width*height);
-		rawsrc = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL);
-
-		// can't memset here
-		for (i = 0; i < size; i++)
-			rawsrc[i] = 0xFF00;
-
-		R_PatchToFlat_16bpp(patch, rawsrc, bflip);
-
 		// Don't cache angle = 0
 		for (angle = 1; angle < ROTANGLES; angle++)
 		{
@@ -1237,17 +1539,12 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 #undef BOUNDARYADJUST
 			}
 
-			size2 = (newwidth * newheight);
-			if (!size2)
-				size2 = size;
-
-			rawdst = Z_Malloc(size2 * sizeof(UINT16), PU_STATIC, NULL);
-
-			// can't memset here
-			for (i = 0; i < size2; i++)
-				rawdst[i] = 0xFF00;
-
 			// Draw the rotated sprite to a temporary buffer.
+			size = (newwidth * newheight);
+			if (!size)
+				size = (width * height);
+			rawdst = Z_Calloc(size * sizeof(UINT16), PU_STATIC, NULL);
+
 			for (dy = 0; dy < newheight; dy++)
 			{
 				for (dx = 0; dx < newwidth; dx++)
@@ -1259,7 +1556,11 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 					sx >>= FRACBITS;
 					sy >>= FRACBITS;
 					if (sx >= 0 && sy >= 0 && sx < width && sy < height)
-						rawdst[(dy*newwidth)+dx] = rawsrc[(sy*width)+sx];
+					{
+						void *input = Picture_GetPatchPixel(patch, PICFMT_PATCH, sx, sy, bflip);
+						if (input != NULL)
+							rawdst[(dy*newwidth)+dx] = *(UINT16 *)input;
+					}
 				}
 			}
 
@@ -1296,7 +1597,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 		sprframe->rotsprite.cached[rot] = true;
 
 		// free image data
-		Z_Free(rawsrc);
 		Z_Free(patch);
 	}
 #undef SPRITE_XCENTER
diff --git a/src/r_patch.h b/src/r_picformats.h
similarity index 62%
rename from src/r_patch.h
rename to src/r_picformats.h
index 53d306b8870e42adfed06e2004d24d87af9f4e8f..cdc64a6740b7d85fdc649658f9104f43b9b03dfc 100644
--- a/src/r_patch.h
+++ b/src/r_picformats.h
@@ -1,14 +1,14 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
-// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos.
-// Copyright (C) 2019      by Sonic Team Junior.
+// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos.
+// Copyright (C) 2019-2020 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
 // See the 'LICENSE' file for more details.
 //-----------------------------------------------------------------------------
-/// \file  r_patch.h
+/// \file  r_picformats.h
 /// \brief Patch generation.
 
 #ifndef __R_PATCH__
@@ -17,6 +17,57 @@
 #include "r_defs.h"
 #include "doomdef.h"
 
+typedef enum
+{
+	PICFMT_NONE = 0,
+
+	// Doom formats
+	PICFMT_PATCH,
+	PICFMT_FLAT,
+
+	// PNG
+	PICFMT_PNG,
+
+	// 16bpp
+	PICFMT_PATCH16,
+	PICFMT_FLAT16,
+
+	// 32bpp
+	PICFMT_PATCH32,
+	PICFMT_FLAT32
+} pictureformat_t;
+
+typedef enum
+{
+	PICFLAGS_XFLIP = 1,
+	PICFLAGS_YFLIP = 1<<1
+} pictureflags_t;
+
+void *Picture_Convert(
+	pictureformat_t informat, void *picture, pictureformat_t outformat,
+	size_t insize, size_t *outsize,
+	INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
+	pictureflags_t flags);
+
+void *Picture_PatchConvert(
+	pictureformat_t informat, void *picture, pictureformat_t outformat,
+	size_t insize, size_t *outsize,
+	INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
+	pictureflags_t flags);
+void *Picture_FlatConvert(
+	pictureformat_t informat, void *picture, pictureformat_t outformat,
+	size_t insize, size_t *outsize,
+	INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
+	pictureflags_t flags);
+void *Picture_GetPatchPixel(
+	patch_t *patch, pictureformat_t informat,
+	INT32 x, INT32 y,
+	pictureflags_t flags);
+
+INT32 Picture_FormatBPP(pictureformat_t format);
+boolean Picture_IsPatchFormat(pictureformat_t format);
+boolean Picture_IsFlatFormat(pictureformat_t format);
+
 // Structs
 #ifdef ROTSPRITE
 typedef enum
@@ -42,7 +93,7 @@ typedef struct
 } spriteinfo_t;
 
 // Conversions between patches / flats / textures...
-boolean R_CheckIfPatch(lumpnum_t lump);
+boolean R_CheckIfPatch(patch_t *patch, size_t size);
 void R_TextureToFlat(size_t tex, UINT8 *flat);
 void R_PatchToFlat(patch_t *patch, UINT8 *flat);
 void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip);
diff --git a/src/r_things.c b/src/r_things.c
index 2f01ac7f65ff355ab51e78a266897983e59e7dd1..43b64bf376ef97e28b79dfa81edea6d3e15b9bcc 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -24,7 +24,7 @@
 #include "i_video.h" // rendermode
 #include "i_system.h"
 #include "r_things.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "r_plane.h"
 #include "r_portal.h"
 #include "p_tick.h"
diff --git a/src/r_things.h b/src/r_things.h
index 8e4a543c36067d1101068a86a5d33e779c4cd8cf..706d98c4e9dcd1bfa3a2553ae11fbc59a4074591 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -16,7 +16,7 @@
 
 #include "sounds.h"
 #include "r_plane.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "r_portal.h"
 #include "r_defs.h"
 
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj
index b334f6313614b5890c9b971b07068e7c404b6cec..7efab1bc0adc512334d91962f42f080256f61123 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -281,7 +281,7 @@
     <ClInclude Include="..\r_local.h" />
     <ClInclude Include="..\r_main.h" />
     <ClInclude Include="..\r_plane.h" />
-    <ClInclude Include="..\r_patch.h" />
+    <ClInclude Include="..\r_picformats.h" />
     <ClInclude Include="..\r_portal.h" />
     <ClInclude Include="..\r_segs.h" />
     <ClInclude Include="..\r_sky.h" />
@@ -443,7 +443,7 @@
     </ClCompile>
     <ClCompile Include="..\r_main.c" />
     <ClCompile Include="..\r_plane.c" />
-	<ClCompile Include="..\r_patch.c" />
+	<ClCompile Include="..\r_picformats.c" />
     <ClCompile Include="..\r_portal.c" />
     <ClCompile Include="..\r_segs.c" />
     <ClCompile Include="..\r_sky.c" />
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters
index 3f61e87098fd08e732f7c521435d93fb63ca77f9..97be5ad5f2814a2009a2a5b4161be9cd9f74605c 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj.filters
+++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters
@@ -465,7 +465,7 @@
     <ClInclude Include="..\hardware\hw_clip.h">
       <Filter>Hw_Hardware</Filter>
     </ClInclude>
-    <ClInclude Include="..\r_patch.h">
+    <ClInclude Include="..\r_picformats.h">
       <Filter>R_Rend</Filter>
     </ClInclude>
     <ClInclude Include="..\r_portal.h">
@@ -928,7 +928,7 @@
       <Filter>Hw_Hardware</Filter>
     </ClCompile>
     <ClCompile Include="..\apng.c" />
-    <ClCompile Include="..\r_patch.c">
+    <ClCompile Include="..\r_picformats.c">
       <Filter>R_Rend</Filter>
     </ClCompile>
     <ClCompile Include="..\r_portal.c">
diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj
index 387d65da9074249929ac24044d38942d2cd26f04..91a6aa34891356de2f21cddda0853c8354bd2d5a 100644
--- a/src/win32/Srb2win-vc10.vcxproj
+++ b/src/win32/Srb2win-vc10.vcxproj
@@ -300,7 +300,7 @@
     </ClCompile>
     <ClCompile Include="..\r_main.c" />
     <ClCompile Include="..\r_plane.c" />
-    <ClCompile Include="..\r_patch.c" />
+    <ClCompile Include="..\r_picformats.c" />
     <ClCompile Include="..\r_portal.c" />
     <ClCompile Include="..\r_segs.c" />
     <ClCompile Include="..\r_sky.c" />
@@ -456,7 +456,7 @@
     <ClInclude Include="..\r_local.h" />
     <ClInclude Include="..\r_main.h" />
     <ClInclude Include="..\r_plane.h" />
-	<ClInclude Include="..\r_patch.h" />
+	<ClInclude Include="..\r_picformats.h" />
     <ClInclude Include="..\r_portal.h" />
     <ClInclude Include="..\r_segs.h" />
     <ClInclude Include="..\r_sky.h" />
diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters
index 2f380c47343f8a15be0f02393970086af4b74b40..00040f4a14d6d3ce956cff460db92c2654d01df0 100644
--- a/src/win32/Srb2win-vc10.vcxproj.filters
+++ b/src/win32/Srb2win-vc10.vcxproj.filters
@@ -472,7 +472,7 @@
       <Filter>Hw_Hardware</Filter>
     </ClCompile>
     <ClCompile Include="..\apng.c" />
-    <ClCompile Include="..\r_patch.c">
+    <ClCompile Include="..\r_picformats.c">
       <Filter>R_Rend</Filter>
     </ClCompile>
     <ClCompile Include="..\r_portal.c">
@@ -892,7 +892,7 @@
       <Filter>Hw_Hardware</Filter>
     </ClInclude>
     <ClInclude Include="..\apng.h" />
-    <ClInclude Include="..\r_patch.h">
+    <ClInclude Include="..\r_picformats.h">
       <Filter>R_Rend</Filter>
     </ClInclude>
     <ClInclude Include="..\r_portal.h">
diff --git a/src/z_zone.c b/src/z_zone.c
index 5a0ff638bfd7e09512af622abf46d66565251029..d02717007ea349174b37c281e78a59ed2378a03f 100644
--- a/src/z_zone.c
+++ b/src/z_zone.c
@@ -27,7 +27,7 @@
 
 #include "doomdef.h"
 #include "doomstat.h"
-#include "r_patch.h"
+#include "r_picformats.h"
 #include "i_system.h" // I_GetFreeMem
 #include "i_video.h" // rendermode
 #include "z_zone.h"