diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c
index 138301d014f2cbed0744dd284e21587319b06ff9..631aa056b66dcdb78f90f9953236ecff83374dff 100644
--- a/src/hardware/hw_cache.c
+++ b/src/hardware/hw_cache.c
@@ -516,13 +516,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
 		{
 			// Dummy variables.
 			INT32 pngwidth, pngheight;
-			realpatch = (softwarepatch_t *)Picture_PNGConvert(pdata, PICFMT_PATCH, &pngwidth, &pngheight, NULL, NULL, lumplength, NULL, 0);
+			realpatch = (softwarepatch_t *)Picture_PNGConvert(pdata, PICFMT_DOOMPATCH, &pngwidth, &pngheight, NULL, NULL, lumplength, NULL, 0);
 		}
 		else
 #endif
 #ifdef WALLFLATS
 		if (texture->type == TEXTURETYPE_FLAT)
-			realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
+			realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
 		else
 #endif
 		{
diff --git a/src/p_setup.c b/src/p_setup.c
index 5e0b0304bb33273bf9455b216f3f4be39b65549b..78f78f0c8e9d3c18409417c338e8e2ad4d9d955f 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -549,7 +549,7 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
 
 	lumpnum_t    flatnum;
 	int       texturenum;
-	patch_t   *flatpatch;
+	UINT8     *flatpatch;
 	size_t    lumplength;
 
 	size_t i;
@@ -609,7 +609,7 @@ flatfound:
 		/* This could be a flat, patch, or PNG. */
 		flatpatch = W_CacheLumpNum(flatnum, PU_CACHE);
 		lumplength = W_LumpLength(flatnum);
-		if (Picture_CheckIfPatch(flatpatch, lumplength))
+		if (Picture_CheckIfDoomPatch((softwarepatch_t *)flatpatch, lumplength))
 			levelflat->type = LEVELFLAT_PATCH;
 		else
 		{
diff --git a/src/r_patch.c b/src/r_patch.c
index e70d0cb7cc918f525e0869ba4441e1f3a55fcb74..281523fd284516d0927fad1d981bf425a36d5d7e 100644
--- a/src/r_patch.c
+++ b/src/r_patch.c
@@ -57,9 +57,6 @@ patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
 		M_Memcpy(patch->columns, ((UINT8 *)source + LONG(source->columnofs[0])), colsize);
 	}
 
-	if (patch->hardware)
-		I_Error("wtf?\n");
-
 	return patch;
 }
 
diff --git a/src/r_picformats.c b/src/r_picformats.c
index e351466c9219bbf4c721ff8d23279e60dfb9623d..d42d36a002c353083c0410b64a3d6748bc02cdf1 100644
--- a/src/r_picformats.c
+++ b/src/r_picformats.c
@@ -118,7 +118,7 @@ void *Picture_PatchConvert(
 	UINT8 *imgptr = imgbuf;
 	UINT8 *colpointers, *startofspan;
 	size_t size = 0;
-	softwarepatch_t *inpatch = NULL;
+	patch_t *inpatch = NULL;
 	INT32 inbpp = Picture_FormatBPP(informat);
 
 	(void)insize; // ignore
@@ -140,10 +140,21 @@ void *Picture_PatchConvert(
 	if (Picture_IsPatchFormat(informat))
 	{
 		inpatch = (patch_t *)picture;
-		inwidth = SHORT(inpatch->width);
-		inheight = SHORT(inpatch->height);
-		inleftoffset = SHORT(inpatch->leftoffset);
-		intopoffset = SHORT(inpatch->topoffset);
+		if (Picture_IsDoomPatchFormat(informat))
+		{
+			softwarepatch_t *doompatch = (softwarepatch_t *)picture;
+			inwidth = SHORT(doompatch->width);
+			inheight = SHORT(doompatch->height);
+			inleftoffset = SHORT(doompatch->leftoffset);
+			intopoffset = SHORT(doompatch->topoffset);
+		}
+		else
+		{
+			inwidth = inpatch->width;
+			inheight = inpatch->height;
+			inleftoffset = inpatch->leftoffset;
+			intopoffset = inpatch->topoffset;
+		}
 	}
 
 	// Write image size and offset
@@ -273,6 +284,7 @@ void *Picture_PatchConvert(
 			switch (outformat)
 			{
 				case PICFMT_PATCH32:
+				case PICFMT_DOOMPATCH32:
 				{
 					if (inbpp == PICDEPTH_32BPP)
 					{
@@ -292,6 +304,7 @@ void *Picture_PatchConvert(
 					break;
 				}
 				case PICFMT_PATCH16:
+				case PICFMT_DOOMPATCH16:
 					if (inbpp == PICDEPTH_32BPP)
 					{
 						RGBA_t in = *(RGBA_t *)input;
@@ -338,7 +351,18 @@ void *Picture_PatchConvert(
 
 	if (outsize != NULL)
 		*outsize = size;
-	return img;
+
+	if (Picture_IsInternalPatchFormat(outformat))
+	{
+		patch_t *converted = Patch_Create((softwarepatch_t *)img, size, NULL);
+#ifdef HWRENDER
+		Patch_CreateGL(converted);
+#endif
+		Z_Free(img);
+		return converted;
+	}
+	else
+		return img;
 }
 
 /** Converts a picture to a flat.
@@ -389,8 +413,17 @@ void *Picture_FlatConvert(
 	if (Picture_IsPatchFormat(informat))
 	{
 		inpatch = (patch_t *)picture;
-		inwidth = SHORT(inpatch->width);
-		inheight = SHORT(inpatch->height);
+		if (Picture_IsDoomPatchFormat(informat))
+		{
+			softwarepatch_t *doompatch = ((softwarepatch_t *)picture);
+			inwidth = SHORT(doompatch->width);
+			inheight = SHORT(doompatch->height);
+		}
+		else
+		{
+			inwidth = inpatch->width;
+			inheight = inpatch->height;
+		}
 	}
 
 	size = (inwidth * inheight) * (outbpp / 8);
@@ -501,22 +534,25 @@ void *Picture_GetPatchPixel(
 	UINT8 *s8 = NULL;
 	UINT16 *s16 = NULL;
 	UINT32 *s32 = NULL;
+	softwarepatch_t *doompatch = (softwarepatch_t *)patch;
+	INT16 width;
 
 	if (patch == NULL)
 		I_Error("Picture_GetPatchPixel: patch == NULL");
 
-	if (x >= 0 && x < SHORT(patch->width))
+	width = (Picture_IsDoomPatchFormat(informat) ? patch->width : SHORT(patch->width));
+
+	if (x >= 0 && x < width)
 	{
+		INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
 		INT32 topdelta, prevdelta = -1;
-		INT32 colofs = 0;
-
-		if (flags & PICFLAGS_XFLIP)
-			colofs = LONG(patch->columnofs[(SHORT(patch->width)-1)-x]);
-		else
-			colofs = LONG(patch->columnofs[x]);
+		INT32 colofs = (Picture_IsDoomPatchFormat(informat) ? LONG(patch->columnofs[colx]) : patch->columnofs[colx]);
 
 		// Column offsets are pointers so no casting required
-		column = (column_t *)((UINT8 *)patch + colofs);
+		if (Picture_IsDoomPatchFormat(informat))
+			column = (column_t *)((UINT8 *)doompatch + colofs);
+		else
+			column = (column_t *)((UINT8 *)patch->columns + colofs);
 
 		while (column->topdelta != 0xff)
 		{
@@ -525,25 +561,25 @@ void *Picture_GetPatchPixel(
 				topdelta += prevdelta;
 			prevdelta = topdelta;
 			s8 = (UINT8 *)(column) + 3;
-			if (informat == PICFMT_PATCH32)
+			if (Picture_FormatBPP(informat) == PICDEPTH_32BPP)
 				s32 = (UINT32 *)s8;
-			else if (informat == PICFMT_PATCH16)
+			else if (Picture_FormatBPP(informat) == PICDEPTH_16BPP)
 				s16 = (UINT16 *)s8;
 			for (ofs = 0; ofs < column->length; ofs++)
 			{
 				if ((topdelta + ofs) == y)
 				{
-					if (informat == PICFMT_PATCH32)
+					if (Picture_FormatBPP(informat) == PICDEPTH_32BPP)
 						return &s32[ofs];
-					else if (informat == PICFMT_PATCH16)
+					else if (Picture_FormatBPP(informat) == PICDEPTH_16BPP)
 						return &s16[ofs];
-					else // PICFMT_PATCH
+					else // PICDEPTH_8BPP
 						return &s8[ofs];
 				}
 			}
-			if (informat == PICFMT_PATCH32)
+			if (Picture_FormatBPP(informat) == PICDEPTH_32BPP)
 				column = (column_t *)((UINT32 *)column + column->length);
-			else if (informat == PICFMT_PATCH16)
+			else if (Picture_FormatBPP(informat) == PICDEPTH_16BPP)
 				column = (column_t *)((UINT16 *)column + column->length);
 			else
 				column = (column_t *)((UINT8 *)column + column->length);
@@ -566,15 +602,18 @@ INT32 Picture_FormatBPP(pictureformat_t format)
 	{
 		case PICFMT_PATCH32:
 		case PICFMT_FLAT32:
+		case PICFMT_DOOMPATCH32:
 		case PICFMT_PNG:
 			bpp = PICDEPTH_32BPP;
 			break;
 		case PICFMT_PATCH16:
 		case PICFMT_FLAT16:
+		case PICFMT_DOOMPATCH16:
 			bpp = PICDEPTH_16BPP;
 			break;
 		case PICFMT_PATCH:
 		case PICFMT_FLAT:
+		case PICFMT_DOOMPATCH:
 			bpp = PICDEPTH_8BPP;
 			break;
 		default:
@@ -590,7 +629,43 @@ INT32 Picture_FormatBPP(pictureformat_t format)
   */
 boolean Picture_IsPatchFormat(pictureformat_t format)
 {
-	return (format == PICFMT_PATCH || format == PICFMT_PATCH16 || format == PICFMT_PATCH32);
+	return (Picture_IsInternalPatchFormat(format) || Picture_IsDoomPatchFormat(format));
+}
+
+/** Checks if the specified picture format is an internal patch.
+  *
+  * \param format Input picture format.
+  * \return True if the picture format is an internal patch, false if not.
+  */
+boolean Picture_IsInternalPatchFormat(pictureformat_t format)
+{
+	switch (format)
+	{
+		case PICFMT_PATCH:
+		case PICFMT_PATCH16:
+		case PICFMT_PATCH32:
+			return true;
+		default:
+			return false;
+	}
+}
+
+/** Checks if the specified picture format is a Doom patch.
+  *
+  * \param format Input picture format.
+  * \return True if the picture format is a Doom patch, false if not.
+  */
+boolean Picture_IsDoomPatchFormat(pictureformat_t format)
+{
+	switch (format)
+	{
+		case PICFMT_DOOMPATCH:
+		case PICFMT_DOOMPATCH16:
+		case PICFMT_DOOMPATCH32:
+			return true;
+		default:
+			return false;
+	}
 }
 
 /** Checks if the specified picture format is a flat.
@@ -604,13 +679,13 @@ boolean Picture_IsFlatFormat(pictureformat_t format)
 }
 
 /** Returns true if the lump is a valid Doom patch.
-  * PICFMT_PATCH only, I think??
+  * PICFMT_DOOMPATCH only.
   *
   * \param patch Input patch.
   * \param picture Input patch size.
   * \return True if the input patch is valid.
   */
-boolean Picture_CheckIfPatch(softwarepatch_t *patch, size_t size)
+boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size)
 {
 	INT16 width, height;
 	boolean result;
@@ -1461,7 +1536,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 {
 	INT32 angle;
 	patch_t *patch, *newpatch;
-	softwarepatch_t *swpatch;
 	UINT16 *rawdst;
 	size_t size;
 	pictureflags_t bflip = (flip) ? PICFLAGS_XFLIP : 0;
@@ -1598,32 +1672,19 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 			}
 
 			// make patch
-			swpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT16, rawdst, PICFMT_PATCH, 0, &size, newwidth, newheight, 0, 0, 0);
+			newpatch = (patch_t *)Picture_Convert(PICFMT_FLAT16, rawdst, PICFMT_PATCH, 0, &size, newwidth, newheight, 0, 0, 0);
 			{
-				swpatch->leftoffset = (swpatch->width / 2) + (leftoffset - px);
-				swpatch->topoffset = (swpatch->height / 2) + (patch->topoffset - py);
+				newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px);
+				newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py);
 			}
 
 			//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
 			if (rendermode != render_none) // not for psprite
-				swpatch->topoffset += FEETADJUST>>FRACBITS;
+				newpatch->topoffset += FEETADJUST>>FRACBITS;
 
 			// P_PrecacheLevel
 			if (devparm) spritememory += size;
 
-			// convert everything to little-endian, for big-endian support
-			swpatch->width = SHORT(swpatch->width);
-			swpatch->height = SHORT(swpatch->height);
-			swpatch->leftoffset = SHORT(swpatch->leftoffset);
-			swpatch->topoffset = SHORT(swpatch->topoffset);
-
-			newpatch = Patch_Create(swpatch, size, NULL);
-
-#ifdef HWRENDER
-			if (rendermode == render_opengl)
-				Patch_CreateGL(newpatch);
-#endif
-
 			sprframe->rotsprite.patch[rot][angle] = newpatch;
 
 			// free rotated image data
@@ -1632,10 +1693,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
 
 		// This rotation is cached now
 		sprframe->rotsprite.cached |= (1<<rot);
-
-		// free image data
-		Z_Free(patch);
-		Z_Free(swpatch);
 	}
 #undef SPRITE_XCENTER
 #undef SPRITE_YCENTER
diff --git a/src/r_picformats.h b/src/r_picformats.h
index d7f86245059b3ca005a3f844981ac0744e308b68..f303b9e3d928f092da75d2530fe3fa20202fd0c6 100644
--- a/src/r_picformats.h
+++ b/src/r_picformats.h
@@ -24,6 +24,7 @@ typedef enum
 	// Doom formats
 	PICFMT_PATCH,
 	PICFMT_FLAT,
+	PICFMT_DOOMPATCH,
 
 	// PNG
 	PICFMT_PNG,
@@ -31,10 +32,12 @@ typedef enum
 	// 16bpp
 	PICFMT_PATCH16,
 	PICFMT_FLAT16,
+	PICFMT_DOOMPATCH16,
 
 	// 32bpp
 	PICFMT_PATCH32,
-	PICFMT_FLAT32
+	PICFMT_FLAT32,
+	PICFMT_DOOMPATCH32
 } pictureformat_t;
 
 typedef enum
@@ -76,8 +79,10 @@ void *Picture_TextureToFlat(size_t trickytex);
 
 INT32 Picture_FormatBPP(pictureformat_t format);
 boolean Picture_IsPatchFormat(pictureformat_t format);
+boolean Picture_IsInternalPatchFormat(pictureformat_t format);
+boolean Picture_IsDoomPatchFormat(pictureformat_t format);
 boolean Picture_IsFlatFormat(pictureformat_t format);
-boolean Picture_CheckIfPatch(softwarepatch_t *patch, size_t size);
+boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size);
 
 // Structs
 typedef enum
@@ -126,7 +131,6 @@ void R_FreeRotSprite(spritedef_t *spritedef);
 void R_FreeSkinRotSprite(size_t skinnum);
 extern fixed_t rollcosang[ROTANGLES];
 extern fixed_t rollsinang[ROTANGLES];
-void R_FreeAllRotSprite(void);
 #endif
 
 #endif // __R_PICFORMATS__
diff --git a/src/r_textures.c b/src/r_textures.c
index f0d3021f0b8001113d2c093ccb36222560438db1..a226afa891712f5057ada8403c39ac76657ba612 100644
--- a/src/r_textures.c
+++ b/src/r_textures.c
@@ -401,13 +401,13 @@ UINT8 *R_GenerateTexture(size_t texnum)
 		{
 			// Dummy variables.
 			INT32 pngwidth, pngheight;
-			realpatch = (softwarepatch_t *)Picture_PNGConvert((UINT8 *)realpatch, PICFMT_PATCH, &pngwidth, &pngheight, NULL, NULL, lumplength, NULL, 0);
+			realpatch = (softwarepatch_t *)Picture_PNGConvert((UINT8 *)realpatch, PICFMT_DOOMPATCH, &pngwidth, &pngheight, NULL, NULL, lumplength, NULL, 0);
 		}
 		else
 #endif
 #ifdef WALLFLATS
 		if (texture->type == TEXTURETYPE_FLAT)
-			realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
+			realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
 		else
 #endif
 		{
@@ -608,7 +608,7 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
 				levelflat->height = ds_flatheight = SHORT(patch->height);
 
 				levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL);
-				converted = Picture_FlatConvert(PICFMT_PATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, patch->topoffset, patch->leftoffset, 0);
+				converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, patch->topoffset, patch->leftoffset, 0);
 				M_Memcpy(levelflat->picture, converted, size);
 				Z_Free(converted);
 			}
diff --git a/src/r_things.c b/src/r_things.c
index 9b32a6d5f85983869c15452eb8bc2cf76fb66f7e..8bbf21b547cd2bb8b4e6c4241748f33f53afec11 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -286,7 +286,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
 					// Dummy variables.
 					INT32 pngwidth, pngheight;
 					INT16 topoffset, leftoffset;
-					patch_t *converted = (patch_t *)Picture_PNGConvert((UINT8 *)png, PICFMT_PATCH, &pngwidth, &pngheight, &topoffset, &leftoffset, len, NULL, 0);
+					patch_t *converted = (patch_t *)Picture_PNGConvert((UINT8 *)png, PICFMT_DOOMPATCH, &pngwidth, &pngheight, &topoffset, &leftoffset, len, NULL, 0);
 					M_Memcpy(&patch, converted, sizeof(INT16)*4); // only copy the header because that's all we need
 					Z_Free(converted);
 				}
diff --git a/src/w_wad.c b/src/w_wad.c
index 21004e6e865dfa5b81a2803f69e90b09ad9009bb..1a1e08da92b67e2c4417ddab15585b126dce5324 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -1684,7 +1684,7 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
 		{
 			size_t newlen;
 			INT32 pngwidth, pngheight; // Dummy variables.
-			void *converted = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_PATCH, &pngwidth, &pngheight, NULL, NULL, len, &newlen, 0);
+			void *converted = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, &pngwidth, &pngheight, NULL, NULL, len, &newlen, 0);
 			ptr = Z_Malloc(newlen, PU_STATIC, NULL);
 			M_Memcpy(ptr, converted, newlen);
 			Z_Free(converted);