diff --git a/src/r_data.c b/src/r_data.c
index a21ba49ae9c3ae83efc88cf7376fb50af96a3a35..f9088a8d5d93a861d76c8abe0e5071d3fecd876b 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -404,6 +404,17 @@ void R_LoadTextures(void)
 	// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
 	for (w = 0, numtextures = 0; w < numwadfiles; w++)
 	{
+		// Count the textures from TEXTURES lumps
+
+		texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
+		while (texturesLumpPos != INT16_MAX)
+		{
+			numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
+			texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
+		}
+
+		// Count single-patch textures
+
 		if (wadfiles[w]->type == RET_PK3)
 		{
 			texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
@@ -411,30 +422,34 @@ void R_LoadTextures(void)
 		}
 		else
 		{
-			texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
+			texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
 			texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
 		}
 
-		texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
-		while (texturesLumpPos != INT16_MAX)
-		{
-			numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
-			texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
-		}
+		if (texstart == INT16_MAX || texend == INT16_MAX)
+			continue;
+
+		texstart++; // Do not count the first marker
 
-		// Add all the textures between TX_START and TX_END
-		if (texstart != INT16_MAX && texend != INT16_MAX)
+		// PK3s have subfolders, so we can't just make a simple sum
+		if (wadfiles[w]->type == RET_PK3)
 		{
-			numtextures += (UINT32)(texend - texstart);
+			for (j = texstart; j < texend; j++)
+			{
+				if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
+					numtextures++;
+			}
 		}
-
-		// If no textures found by this point, bomb out
-		if (!numtextures && w == (numwadfiles - 1))
+		else // Add all the textures between TX_START and TX_END
 		{
-			I_Error("No textures detected in any WADs!\n");
+			numtextures += (UINT32)(texend - texstart);
 		}
 	}
 
+	// If no textures found by this point, bomb out
+	if (!numtextures)
+		I_Error("No textures detected in any WADs!\n");
+
 	// Allocate memory and initialize to 0 for all the textures we are initialising.
 	// There are actually 5 buffers allocated in one for convenience.
 	textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
@@ -469,7 +484,7 @@ void R_LoadTextures(void)
 		}
 		else
 		{
-			texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
+			texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
 			texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
 			texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
 			if (texturesLumpPos != INT16_MAX)
@@ -479,9 +494,16 @@ void R_LoadTextures(void)
 		if (texstart == INT16_MAX || texend == INT16_MAX)
 			continue;
 
+		texstart++; // Do not count the first marker
+
 		// Work through each lump between the markers in the WAD.
-		for (j = 0; j < (texend - texstart); i++, j++)
+		for (j = 0; j < (texend - texstart); j++)
 		{
+			if (wadfiles[w]->type == RET_PK3)
+			{
+				if (W_IsLumpFolder((UINT16)w, texstart + j)) // Check if lump is a folder
+					continue; // If it is then SKIP IT
+			}
 			patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE);
 
 			// Then, check the lump directly to see if it's a texture SOC,
@@ -520,6 +542,7 @@ void R_LoadTextures(void)
 				texturewidthmask[i] = k - 1;
 				textureheight[i] = texture->height << FRACBITS;
 			}
+			i++;
 		}
 	}
 }
diff --git a/src/w_wad.c b/src/w_wad.c
index 8d96449f1cbd3c64b4c31c9e066d4529de1eb001..e063378109f75720be4525e815f9b9f5c990d6f1 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -1153,6 +1153,22 @@ boolean W_IsLumpWad(lumpnum_t lumpnum)
 	return false; // WADs should never be inside non-PK3s as far as SRB2 is concerned
 }
 
+//
+// W_IsLumpFolder
+// Is the lump a folder? (in a PK3 obviously)
+//
+boolean W_IsLumpFolder(UINT16 wad, UINT16 lump)
+{
+	if (wadfiles[wad]->type == RET_PK3)
+	{
+		const char *name = wadfiles[wad]->lumpinfo[lump].name2;
+
+		return (name[strlen(name)-1] == '/'); // folders end in '/'
+	}
+
+	return false; // non-PK3s don't have folders
+}
+
 #ifdef HAVE_ZLIB
 /* report a zlib or i/o error */
 void zerr(int ret)
diff --git a/src/w_wad.h b/src/w_wad.h
index e2e17740f76fc24ed7d02a60fc5f854824888296..87566c3ee8c103d33d554199d520cee4a501c91b 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -154,6 +154,7 @@ size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);
 size_t W_LumpLength(lumpnum_t lumpnum);
 
 boolean W_IsLumpWad(lumpnum_t lumpnum); // for loading maps from WADs in PK3s
+boolean W_IsLumpFolder(UINT16 wad, UINT16 lump); // for detecting folder "lumps"
 
 #ifdef HAVE_ZLIB
 void zerr(int ret); // zlib error checking