diff --git a/SRB2.cbp b/SRB2.cbp
index 43696ee2e4b23a9ecf6eafafe51bfeaa834cb154..99a71226467e07aeb3e6f01f01cb99608bea6cf7 100644
--- a/SRB2.cbp
+++ b/SRB2.cbp
@@ -2815,6 +2815,39 @@ HW3SOUND for 3D hardware sound  support
 			<Option target="Debug Mingw64/DirectX" />
 			<Option target="Release Mingw64/DirectX" />
 		</Unit>
+		<Unit filename="src/m_aatree.c">
+			<Option compilerVar="CC" />
+			<Option target="Debug Native/SDL" />
+			<Option target="Release Native/SDL" />
+			<Option target="Debug Mingw/SDL" />
+			<Option target="Release Mingw/SDL" />
+			<Option target="Debug Mingw/DirectX" />
+			<Option target="Release Mingw/DirectX" />
+			<Option target="Debug Any/Dummy" />
+			<Option target="Release Any/Dummy" />
+			<Option target="Debug Linux/SDL" />
+			<Option target="Release Linux/SDL" />
+			<Option target="Debug Mingw64/SDL" />
+			<Option target="Release Mingw64/SDL" />
+			<Option target="Debug Mingw64/DirectX" />
+			<Option target="Release Mingw64/DirectX" />
+		</Unit>
+		<Unit filename="src/m_aatree.h">
+			<Option target="Debug Native/SDL" />
+			<Option target="Release Native/SDL" />
+			<Option target="Debug Mingw/SDL" />
+			<Option target="Release Mingw/SDL" />
+			<Option target="Debug Mingw/DirectX" />
+			<Option target="Release Mingw/DirectX" />
+			<Option target="Debug Any/Dummy" />
+			<Option target="Release Any/Dummy" />
+			<Option target="Debug Linux/SDL" />
+			<Option target="Release Linux/SDL" />
+			<Option target="Debug Mingw64/SDL" />
+			<Option target="Release Mingw64/SDL" />
+			<Option target="Debug Mingw64/DirectX" />
+			<Option target="Release Mingw64/DirectX" />
+		</Unit>
 		<Unit filename="src/m_anigif.c">
 			<Option compilerVar="CC" />
 			<Option target="Debug Native/SDL" />
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 035b4655699bdf4c6d2830d6ab8dc358360948d1..ba354c2899870ccb7d4d850863b6a20ebd618110 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -22,6 +22,7 @@ set(SRB2_CORE_SOURCES
 	i_tcp.c
 	info.c
 	lzf.c
+	m_aatree.c
 	m_anigif.c
 	m_argv.c
 	m_bbox.c
@@ -83,6 +84,7 @@ set(SRB2_CORE_HEADERS
 	info.h
 	keys.h
 	lzf.h
+	m_aatree.h
 	m_anigif.h
 	m_argv.h
 	m_bbox.h
diff --git a/src/Makefile b/src/Makefile
index f7a8c1b85effd05aa269687578e9ec39a085e808..02b136f3e1f790f8268568f66c13fefd892c5265 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -429,6 +429,7 @@ OBJS:=$(i_main_o) \
 		$(OBJDIR)/hu_stuff.o \
 		$(OBJDIR)/y_inter.o  \
 		$(OBJDIR)/st_stuff.o \
+		$(OBJDIR)/m_aatree.o \
 		$(OBJDIR)/m_anigif.o \
 		$(OBJDIR)/m_argv.o   \
 		$(OBJDIR)/m_bbox.o   \
diff --git a/src/m_aatree.c b/src/m_aatree.c
new file mode 100644
index 0000000000000000000000000000000000000000..6cb3a32cb927aac773db7739b6a0dc6887e14294
--- /dev/null
+++ b/src/m_aatree.c
@@ -0,0 +1,167 @@
+// SONIC ROBO BLAST 2
+//-----------------------------------------------------------------------------
+// Copyright (C) 1993-1996 by id Software, Inc.
+// Copyright (C) 1998-2000 by DooM Legacy Team.
+// Copyright (C) 1999-2016 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  m_aatree.h
+/// \brief AA trees code
+
+#include "m_aatree.h"
+#include "z_zone.h"
+
+// A partial implementation of AA trees,
+// according to the algorithms given on Wikipedia.
+// http://en.wikipedia.org/wiki/AA_tree
+
+typedef struct aatree_node_s
+{
+	INT32	level;
+	INT32	key;
+	void*	value;
+
+	struct aatree_node_s *left, *right;
+} aatree_node_t;
+
+struct aatree_s
+{
+	aatree_node_t	*root;
+	UINT32		flags;
+};
+
+aatree_t *M_AATreeAlloc(UINT32 flags)
+{
+	aatree_t *aatree = Z_Malloc(sizeof (aatree_t), PU_STATIC, NULL);
+	aatree->root = NULL;
+	aatree->flags = flags;
+	return aatree;
+}
+
+static void M_AATreeFree_Node(aatree_node_t *node)
+{
+	if (node->left) M_AATreeFree_Node(node->left);
+	if (node->right) M_AATreeFree_Node(node->right);
+	Z_Free(node);
+}
+
+void M_AATreeFree(aatree_t *aatree)
+{
+	if (aatree->root)
+		M_AATreeFree_Node(aatree->root);
+
+	Z_Free(aatree);
+}
+
+static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
+{
+	if (node && node->left && node->left->level == node->level)
+	{
+		// Not allowed: horizontal left-link. Reverse the
+		// horizontal link and hook the orphan back in.
+		aatree_node_t *oldleft = node->left;
+		node->left = oldleft->right;
+		oldleft->right = node;
+
+		return oldleft;
+	}
+
+	// No change needed.
+	return node;
+}
+
+static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
+{
+	if (node && node->right && node->right->right && node->level == node->right->right->level)
+	{
+		// Not allowed: two consecutive horizontal right-links.
+		// The middle one becomes the new root at this point,
+		// with suitable adjustments below.
+
+		aatree_node_t *oldright = node->right;
+		node->right = oldright->left;
+		oldright->left = node;
+		oldright->level++;
+
+		return oldright;
+	}
+
+	// No change needed.
+	return node;
+}
+
+static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32 key, void* value)
+{
+	if (!node)
+	{
+		// Nothing here, so just add where we are
+
+		node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
+		node->level = 1;
+		node->key = key;
+		if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
+		else node->value = value;
+		node->left = node->right = NULL;
+	}
+	else
+	{
+		if (key < node->key)
+			node->left = M_AATreeSet_Node(node->left, flags, key, value);
+		else if (key > node->key)
+			node->right = M_AATreeSet_Node(node->right, flags, key, value);
+		else
+		{
+			if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
+			else node->value = value;
+		}
+
+		node = M_AATreeSkew(node);
+		node = M_AATreeSplit(node);
+	}
+
+	return node;
+}
+
+void M_AATreeSet(aatree_t *aatree, INT32 key, void* value)
+{
+	aatree->root = M_AATreeSet_Node(aatree->root, aatree->flags, key, value);
+}
+
+// Caveat: we don't distinguish between nodes that don't exists
+// and nodes with value == NULL.
+static void *M_AATreeGet_Node(aatree_node_t *node, INT32 key)
+{
+	if (node)
+	{
+		if (node->key == key)
+			return node->value;
+		else if(node->key < key)
+			return M_AATreeGet_Node(node->right, key);
+		else
+			return M_AATreeGet_Node(node->left, key);
+	}
+
+	return NULL;
+}
+
+void *M_AATreeGet(aatree_t *aatree, INT32 key)
+{
+	return M_AATreeGet_Node(aatree->root, key);
+}
+
+
+static void M_AATreeIterate_Node(aatree_node_t *node, aatree_iter_t callback)
+{
+	if (node->left) M_AATreeIterate_Node(node->left, callback);
+	callback(node->key, node->value);
+	if (node->right) M_AATreeIterate_Node(node->right, callback);
+}
+
+void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback)
+{
+	if (aatree->root)
+		M_AATreeIterate_Node(aatree->root, callback);
+}
diff --git a/src/m_aatree.h b/src/m_aatree.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9077b9740f1251eb4584120cd2f8283174d3eb3
--- /dev/null
+++ b/src/m_aatree.h
@@ -0,0 +1,31 @@
+// SONIC ROBO BLAST 2
+//-----------------------------------------------------------------------------
+// Copyright (C) 1993-1996 by id Software, Inc.
+// Copyright (C) 1998-2000 by DooM Legacy Team.
+// Copyright (C) 1999-2016 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  m_aatree.h
+/// \brief AA trees code
+
+#ifndef __M_AATREE__
+#define __M_AATREE__
+
+#include "doomtype.h"
+
+// Flags for AA trees.
+#define AATREE_ZUSER	1		// Treat values as z_zone-allocated blocks and set their user fields
+
+typedef struct aatree_s aatree_t;
+typedef void (*aatree_iter_t)(INT32 key, void *value);
+
+aatree_t *M_AATreeAlloc(UINT32 flags);
+void M_AATreeFree(aatree_t *aatree);
+void M_AATreeSet(aatree_t *aatree, INT32 key, void* value);
+void *M_AATreeGet(aatree_t *aatree, INT32 key);
+void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback);
+
+#endif
\ No newline at end of file
diff --git a/src/m_misc.c b/src/m_misc.c
index 64054d4f9cada065577d1293d09fed5823460730..457214e339e66b5897d0451f21f2798d99f24d63 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -2323,158 +2323,3 @@ void M_SetupMemcpy(void)
 	M_Memcpy = cpu_cpy;
 #endif
 }
-
-
-// A partial implementation of AA trees,
-// according to the algorithms given on Wikipedia.
-// http://en.wikipedia.org/wiki/AA_tree
-
-
-
-typedef struct aatree_node_s
-{
-	INT32	level;
-	INT32	key;
-	void*	value;
-
-	struct aatree_node_s *left, *right;
-} aatree_node_t;
-
-struct aatree_s
-{
-	aatree_node_t	*root;
-	UINT32		flags;
-};
-
-aatree_t *M_AATreeAlloc(UINT32 flags)
-{
-	aatree_t *aatree = Z_Malloc(sizeof (aatree_t), PU_STATIC, NULL);
-	aatree->root = NULL;
-	aatree->flags = flags;
-	return aatree;
-}
-
-static void M_AATreeFree_Node(aatree_node_t *node)
-{
-	if (node->left) M_AATreeFree_Node(node->left);
-	if (node->right) M_AATreeFree_Node(node->right);
-	Z_Free(node);
-}
-
-void M_AATreeFree(aatree_t *aatree)
-{
-	if (aatree->root)
-		M_AATreeFree_Node(aatree->root);
-
-	Z_Free(aatree);
-}
-
-static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
-{
-	if (node && node->left && node->left->level == node->level)
-	{
-		// Not allowed: horizontal left-link. Reverse the
-		// horizontal link and hook the orphan back in.
-		aatree_node_t *oldleft = node->left;
-		node->left = oldleft->right;
-		oldleft->right = node;
-
-		return oldleft;
-	}
-
-	// No change needed.
-	return node;
-}
-
-static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
-{
-	if (node && node->right && node->right->right && node->level == node->right->right->level)
-	{
-		// Not allowed: two consecutive horizontal right-links.
-		// The middle one becomes the new root at this point,
-		// with suitable adjustments below.
-
-		aatree_node_t *oldright = node->right;
-		node->right = oldright->left;
-		oldright->left = node;
-		oldright->level++;
-
-		return oldright;
-	}
-
-	// No change needed.
-	return node;
-}
-
-static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32 key, void* value)
-{
-	if (!node)
-	{
-		// Nothing here, so just add where we are
-
-		node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
-		node->level = 1;
-		node->key = key;
-		if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
-		else node->value = value;
-		node->left = node->right = NULL;
-	}
-	else
-	{
-		if (key < node->key)
-			node->left = M_AATreeSet_Node(node->left, flags, key, value);
-		else if (key > node->key)
-			node->right = M_AATreeSet_Node(node->right, flags, key, value);
-		else
-		{
-			if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
-			else node->value = value;
-		}
-
-		node = M_AATreeSkew(node);
-		node = M_AATreeSplit(node);
-	}
-
-	return node;
-}
-
-void M_AATreeSet(aatree_t *aatree, INT32 key, void* value)
-{
-	aatree->root = M_AATreeSet_Node(aatree->root, aatree->flags, key, value);
-}
-
-// Caveat: we don't distinguish between nodes that don't exists
-// and nodes with value == NULL.
-static void *M_AATreeGet_Node(aatree_node_t *node, INT32 key)
-{
-	if (node)
-	{
-		if (node->key == key)
-			return node->value;
-		else if(node->key < key)
-			return M_AATreeGet_Node(node->right, key);
-		else
-			return M_AATreeGet_Node(node->left, key);
-	}
-
-	return NULL;
-}
-
-void *M_AATreeGet(aatree_t *aatree, INT32 key)
-{
-	return M_AATreeGet_Node(aatree->root, key);
-}
-
-
-static void M_AATreeIterate_Node(aatree_node_t *node, aatree_iter_t callback)
-{
-	if (node->left) M_AATreeIterate_Node(node->left, callback);
-	callback(node->key, node->value);
-	if (node->right) M_AATreeIterate_Node(node->right, callback);
-}
-
-void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback)
-{
-	if (aatree->root)
-		M_AATreeIterate_Node(aatree->root, callback);
-}
diff --git a/src/m_misc.h b/src/m_misc.h
index fa1f3b33ca78032e64620bcc139d7cf365680c07..dc540dc16325ffca245ba194393463067823c083 100644
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -96,19 +96,6 @@ void M_SetupMemcpy(void);
 // counting bits, for weapon ammo code, usually
 FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
 
-// Flags for AA trees.
-#define AATREE_ZUSER	1		// Treat values as z_zone-allocated blocks and set their user fields
-
-typedef struct aatree_s aatree_t;
-typedef void (*aatree_iter_t)(INT32 key, void *value);
-
-aatree_t *M_AATreeAlloc(UINT32 flags);
-void M_AATreeFree(aatree_t *aatree);
-void M_AATreeSet(aatree_t *aatree, INT32 key, void* value);
-void *M_AATreeGet(aatree_t *aatree, INT32 key);
-void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback);
-
-// Nasty cyclic dependency workaround. This must come after aatree stuff.
 #include "w_wad.h"
 extern char configfile[MAX_WADPATH];
 
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj
index d12a7efbf86acf4ae461b101c4024ab13708e88b..820192649d981adeaa477f0791d200f46d3ddfe9 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -167,6 +167,7 @@
     <ClInclude Include="..\lzf.h" />
     <ClInclude Include="..\md5.h" />
     <ClInclude Include="..\mserv.h" />
+    <ClInclude Include="..\m_aatree.h" />
     <ClInclude Include="..\m_anigif.h" />
     <ClInclude Include="..\m_argv.h" />
     <ClInclude Include="..\m_bbox.h" />
@@ -308,6 +309,7 @@
     <ClCompile Include="..\lzf.c" />
     <ClCompile Include="..\md5.c" />
     <ClCompile Include="..\mserv.c" />
+    <ClCompile Include="..\m_aatree.c" />
     <ClCompile Include="..\m_anigif.c" />
     <ClCompile Include="..\m_argv.c" />
     <ClCompile Include="..\m_bbox.c" />
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters
index 9396b4823bf5ed60465fc8fef72fcb86e989b64e..d04007dd77d026e48e8480bf93a54b86d279b7c5 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj.filters
+++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters
@@ -294,6 +294,9 @@
     <ClInclude Include="..\md5.h">
       <Filter>M_Misc</Filter>
     </ClInclude>
+    <ClInclude Include="..\m_aatree.h">
+      <Filter>M_Misc</Filter>
+    </ClInclude>
     <ClInclude Include="..\m_anigif.h">
       <Filter>M_Misc</Filter>
     </ClInclude>
@@ -666,6 +669,9 @@
     <ClCompile Include="..\md5.c">
       <Filter>M_Misc</Filter>
     </ClCompile>
+    <ClCompile Include="..\m_aatree.c">
+      <Filter>M_Misc</Filter>
+    </ClCompile>
     <ClCompile Include="..\m_anigif.c">
       <Filter>M_Misc</Filter>
     </ClCompile>
diff --git a/src/w_wad.h b/src/w_wad.h
index c13f6933816ec1fe0091eebca00f65c6393f3880..b03e376bfaf76c62778a163f44994c25fc37efaf 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -54,10 +54,8 @@ typedef struct
 
 #define lumpcache_t void *
 
-// Annoying cyclic dependency workaround: this inlcusion must come after
-// the definition of MAX_WADPATH.
 #ifdef HWRENDER
-#include "m_misc.h"
+#include "m_aatree.h"
 #endif
 
 typedef struct wadfile_s
diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj
index 1e9d8241ede783576e7463246d5730164f54b836..064f75d7d06cdee1aa62d70dda03e9e28d53e6f2 100644
--- a/src/win32/Srb2win-vc10.vcxproj
+++ b/src/win32/Srb2win-vc10.vcxproj
@@ -145,6 +145,7 @@
     <ClCompile Include="..\lzf.c" />
     <ClCompile Include="..\md5.c" />
     <ClCompile Include="..\mserv.c" />
+    <ClCompile Include="..\m_aatree.c" />
     <ClCompile Include="..\m_anigif.c" />
     <ClCompile Include="..\m_argv.c" />
     <ClCompile Include="..\m_bbox.c" />
@@ -300,6 +301,7 @@
     <ClInclude Include="..\lzf.h" />
     <ClInclude Include="..\md5.h" />
     <ClInclude Include="..\mserv.h" />
+    <ClInclude Include="..\m_aatree.h" />
     <ClInclude Include="..\m_anigif.h" />
     <ClInclude Include="..\m_argv.h" />
     <ClInclude Include="..\m_bbox.h" />
diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters
index 3f5b84bfb7d131fef86d800acffcb53c4b9d6e4d..b2647ea1c21518389b7061276f6464d05998721b 100644
--- a/src/win32/Srb2win-vc10.vcxproj.filters
+++ b/src/win32/Srb2win-vc10.vcxproj.filters
@@ -255,6 +255,9 @@
     <ClCompile Include="..\lua_skinlib.c">
       <Filter>LUA</Filter>
     </ClCompile>
+    <ClCompile Include="..\m_aatree.c">
+      <Filter>M_Misc</Filter>
+    </ClCompile>
     <ClCompile Include="..\m_anigif.c">
       <Filter>M_Misc</Filter>
     </ClCompile>
@@ -662,6 +665,9 @@
     <ClInclude Include="..\md5.h">
       <Filter>M_Misc</Filter>
     </ClInclude>
+    <ClInclude Include="..\m_aatree.h">
+      <Filter>M_Misc</Filter>
+    </ClInclude>
     <ClInclude Include="..\m_anigif.h">
       <Filter>M_Misc</Filter>
     </ClInclude>