diff --git a/src/dehacked.c b/src/dehacked.c
index 20f835981f2e980b86770d0dd8e0eb5ef28ee8ad..920e5eec325d02b6efa600b39e32eb0dcdc25a00 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -2778,7 +2778,7 @@ static void readpatch(MYFILE *f, const char *name, UINT16 wad)
 	char *word2;
 	char *tmp;
 	INT32 i = 0, j = 0, value;
-	texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX};
+	texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX, 0};
 
 	// Jump to the texture this patch belongs to, which,
 	// coincidentally, is always the last one on the buffer cache.
diff --git a/src/doomdef.h b/src/doomdef.h
index 410e740faeed04c8b874a5acac3137abf2b389dc..d0ac3a676156230464f4c6dbc691979f63b13743 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -407,6 +407,7 @@ void M_StartupLocale(void);
 extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL;
 char *va(const char *format, ...) FUNCPRINTF;
 char *M_GetToken(const char *inputString);
+void M_UnGetToken(void);
 char *sizeu1(size_t num);
 char *sizeu2(size_t num);
 char *sizeu3(size_t num);
diff --git a/src/m_misc.c b/src/m_misc.c
index cfe73d88fa60cad5f1d5c9bb93ea82f47eec5f30..d6ab40196694df21a9150ce799d596f89498b159 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -1617,6 +1617,11 @@ INT32 axtoi(const char *hexStg)
 	return intValue;
 }
 
+// Token parser variables
+
+static UINT32 oldendPos = 0; // old value of endPos, used by M_UnGetToken
+static UINT32 endPos = 0; // now external to M_GetToken, but still static
+
 /** Token parser for TEXTURES, ANIMDEFS, and potentially other lumps later down the line.
   * Was originally R_GetTexturesToken when I was coding up the TEXTURES parser, until I realized I needed it for ANIMDEFS too.
   * Parses up to the next whitespace character or comma. When finding the start of the next token, whitespace is skipped.
@@ -1631,7 +1636,7 @@ char *M_GetToken(const char *inputString)
 {
 	static const char *stringToUse = NULL; // Populated if inputString != NULL; used otherwise
 	static UINT32 startPos = 0;
-	static UINT32 endPos = 0;
+//	static UINT32 endPos = 0;
 	static UINT32 stringLength = 0;
 	static UINT8 inComment = 0; // 0 = not in comment, 1 = // Single-line, 2 = /* Multi-line */
 	char *texturesToken = NULL;
@@ -1641,12 +1646,12 @@ char *M_GetToken(const char *inputString)
 	{
 		stringToUse = inputString;
 		startPos = 0;
-		endPos = 0;
+		oldendPos = endPos = 0;
 		stringLength = strlen(inputString);
 	}
 	else
 	{
-		startPos = endPos;
+		startPos = oldendPos = endPos;
 	}
 	if (stringToUse == NULL)
 		return NULL;
@@ -1777,6 +1782,16 @@ char *M_GetToken(const char *inputString)
 	return texturesToken;
 }
 
+/** Undoes the last M_GetToken call
+  * The current position along the string being parsed is reset to the last saved position.
+  * This exists mostly because of R_ParseTexture/R_ParsePatch honestly, but could be useful elsewhere?
+  * -Monster Iestyn (22/10/16)
+ */
+void M_UnGetToken(void)
+{
+	endPos = oldendPos;
+}
+
 /** Count bits in a number.
   */
 UINT8 M_CountBits(UINT32 num, UINT8 size)
diff --git a/src/r_data.c b/src/r_data.c
index cb5cf3591486abc8ca14b7cc5caf656021e55e54..5c3d06649464d3524a974df699928797fab0f9e7 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -502,6 +502,7 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
 	char *patchName = NULL;
 	INT16 patchXPos;
 	INT16 patchYPos;
+	UINT8 flip = 0;
 	texpatch_t *resultPatch = NULL;
 	lumpnum_t patchLumpNum;
 
@@ -598,6 +599,47 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
 	}
 	Z_Free(texturesToken);
 
+	// Patch parameters block (OPTIONAL)
+	// added by Monster Iestyn (22/10/16)
+
+	// Left Curly Brace
+	texturesToken = M_GetToken(NULL);
+	if (texturesToken == NULL)
+		; // move on and ignore, R_ParseTextures will deal with this
+	else
+	{
+		if (strcmp(texturesToken,"{")==0)
+		{
+			Z_Free(texturesToken);
+			texturesToken = M_GetToken(NULL);
+			if (texturesToken == NULL)
+			{
+				I_Error("Error parsing TEXTURES lump: Unexpected end of file where patch \"%s\"'s parameters should be",patchName);
+			}
+			while (strcmp(texturesToken,"}")!=0)
+			{
+				if (stricmp(texturesToken, "FLIPX")==0)
+					flip |= 1;
+				else if (stricmp(texturesToken, "FLIPY")==0)
+					flip |= 2;
+				Z_Free(texturesToken);
+
+				texturesToken = M_GetToken(NULL);
+				if (texturesToken == NULL)
+				{
+					I_Error("Error parsing TEXTURES lump: Unexpected end of file where patch \"%s\"'s parameters or right curly brace should be",patchName);
+				}
+			}
+		}
+		else
+		{
+			 // this is not what we wanted...
+			 // undo last read so R_ParseTextures can re-get the token for its own purposes
+			M_UnGetToken();
+		}
+		Z_Free(texturesToken);
+	}
+
 	if (actuallyLoadPatch == true)
 	{
 		// Check lump exists
@@ -608,6 +650,7 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
 		resultPatch->originy = patchYPos;
 		resultPatch->lump = patchLumpNum & 65535;
 		resultPatch->wad = patchLumpNum>>16;
+		resultPatch->flip = flip;
 		// Clean up a little after ourselves
 		Z_Free(patchName);
 		// Then return it
diff --git a/src/r_data.h b/src/r_data.h
index 69a2882af52da27a55f2dca8a43a4006c8a66554..1384ecac0c4c79174a25bdf84b8ed663a0449c22 100644
--- a/src/r_data.h
+++ b/src/r_data.h
@@ -31,6 +31,7 @@ typedef struct
 	// Block origin (always UL), which has already accounted for the internal origin of the patch.
 	INT16 originx, originy;
 	UINT16 wad, lump;
+	UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
 } texpatch_t;
 
 // A maptexturedef_t describes a rectangular texture,