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/appveyor.yml b/appveyor.yml
index 85cee6a3107a224213512eea0fba150d799c7232..e0ee99c61410ba8274296100122b9eb046055688 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 2.1.14.{branch}-{build}
+version: 2.1.16.{branch}-{build}
 os: MinGW
 
 environment:
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..ce4b569eebd7dcc94cfc8858daea7bf4f38dd287 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -189,6 +189,10 @@ ifdef FREEBSD
 UNIXCOMMON=1
 endif
 
+ifdef MACOSX
+UNIXCOMMON=1
+endif
+
 ifdef NDS
 NOPNG=1
 NONET=1
@@ -429,6 +433,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   \
@@ -593,11 +598,15 @@ ifndef WINDOWSHELL
 	-$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt
 endif
 endif
+
+# mac os x lsdlsrb2 does not like objcopy
+ifndef MACOSX
 ifndef PSP
 	$(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME)
 	$(OBJCOPY) --strip-debug $(BIN)/$(EXENAME)
 	-$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME)
 endif
+endif
 ifndef NOUPX
 	-$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME)
 endif
@@ -745,6 +754,11 @@ $(OBJDIR)/%.o: %.c
 $(OBJDIR)/%.o: $(INTERFACE)/%.c
 	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
 
+ifdef MACOSX
+$(OBJDIR)/%.o: sdl/macosx/%.c
+	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
+endif
+
 $(OBJDIR)/%.o: hardware/%.c
 	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
 
diff --git a/src/Makefile.cfg b/src/Makefile.cfg
index 347efa5e4450651d679cec537522a9dd4c21d51b..72404becca345b380fb9a60795f3a05734337db3 100644
--- a/src/Makefile.cfg
+++ b/src/Makefile.cfg
@@ -406,6 +406,15 @@ else
 	WINDRES=windres
 endif
 
+# because Apple screws with us on this
+# need to get bintools from homebrew
+ifdef MACOSX
+	CC=clang
+	CXX=clang
+	OBJCOPY=gobjcopy
+	OBJDUMP=gobjdump
+endif
+
 OBJDUMP_OPTS?=--wide --source --line-numbers
 LD=$(CC)
 
diff --git a/src/dehacked.c b/src/dehacked.c
index 2feb1a7a852a657f93a6186e6b741719c2e26f29..f2b906c23a2d338c2f0e9722bd840a9879a0b20a 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -673,6 +673,22 @@ static void readfreeslots(MYFILE *f)
 						break;
 					}
 			}
+			else if (fastcmp(type, "SPR2"))
+			{
+				// Search if we already have an SPR2 by that name...
+				for (i = SPR2_FIRSTFREESLOT; i < (int)free_spr2; i++)
+					if (memcmp(spr2names[i],word,4) == 0)
+						break;
+				// We found it? (Two mods using the same SPR2 name?) Then don't allocate another one.
+				if (i < (int)free_spr2)
+					continue;
+				// Copy in the spr2 name and increment free_spr2.
+				if (free_spr2 < NUMPLAYERSPRITES) {
+					strncpy(spr2names[free_spr2],word,4);
+					spr2names[free_spr2++][4] = 0;
+				} else
+					CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+			}
 			else
 				deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
 		}
@@ -7873,7 +7889,7 @@ static inline int lib_freeslot(lua_State *L)
 				lua_pushinteger(L, sfx);
 				r++;
 			} else
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n");
 		}
 		else if (fastcmp(type, "SPR"))
 		{
@@ -7900,7 +7916,7 @@ static inline int lib_freeslot(lua_State *L)
 				break;
 			}
 			if (j > SPR_LASTFREESLOT)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n");
 		}
 		else if (fastcmp(type, "S"))
 		{
@@ -7915,7 +7931,7 @@ static inline int lib_freeslot(lua_State *L)
 					break;
 				}
 			if (i == NUMSTATEFREESLOTS)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n");
 		}
 		else if (fastcmp(type, "MT"))
 		{
@@ -7930,7 +7946,26 @@ static inline int lib_freeslot(lua_State *L)
 					break;
 				}
 			if (i == NUMMOBJFREESLOTS)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
+		}
+		else if (fastcmp(type, "SPR2"))
+		{
+			// Search if we already have an SPR2 by that name...
+			enum playersprite i;
+			for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++)
+				if (memcmp(spr2names[i],word,4) == 0)
+					break;
+			// We don't, so allocate a new one.
+			if (i >= free_spr2) {
+				if (free_spr2 < NUMPLAYERSPRITES)
+				{
+					CONS_Printf("Sprite SPR2_%s allocated.\n",word);
+					strncpy(spr2names[free_spr2],word,4);
+					spr2names[free_spr2++][4] = 0;
+				} else
+					CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+			}
+			r++;
 		}
 		Z_Free(s);
 		lua_remove(L, 1);
@@ -8097,7 +8132,7 @@ static inline int lib_getenum(lua_State *L)
 	}
 	else if (fastncmp("SPR2_",word,4)) {
 		p = word+5;
-		for (i = 0; i < NUMPLAYERSPRITES; i++)
+		for (i = 0; i < (fixed_t)free_spr2; i++)
 			if (!spr2names[i][4])
 			{
 				// special 3-char cases, e.g. SPR2_RUN
diff --git a/src/doomtype.h b/src/doomtype.h
index 2d9d363282047afd76c12dc177ebd1279c4d52c8..a711b466d6ccf61d8262534cb585f0a7a3ef7c2e 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -92,7 +92,7 @@ typedef long ssize_t;
 #endif
 
 #ifdef __APPLE_CC__
-#define DIRECTFULLSCREEN
+#define DIRECTFULLSCREEN 1
 #define DEBUG_LOG
 #define NOIPX
 #endif
diff --git a/src/info.c b/src/info.c
index 2db0c3d216a4fea9eda80af1bfc85b540557fc5a..4e9671705c95e20e0fde962c27a474ad5ee19e40 100644
--- a/src/info.c
+++ b/src/info.c
@@ -103,6 +103,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"SRID",
 	"SFLT"
 };
+enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
 
 // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
 state_t states[NUMSTATES] =
diff --git a/src/info.h b/src/info.h
index c89f4a88c934940b79d24b1daee514f9fa348ccb..0e66bf3eb1e3ee54ead9709cb4fe4422eb83012b 100644
--- a/src/info.h
+++ b/src/info.h
@@ -625,6 +625,8 @@ enum playersprite
 	SPR2_SRID,
 	SPR2_SFLT,
 
+	SPR2_FIRSTFREESLOT,
+	SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
 	NUMPLAYERSPRITES
 };
 
@@ -3030,8 +3032,9 @@ typedef struct
 
 extern state_t states[NUMSTATES];
 extern char sprnames[NUMSPRITES + 1][5];
-char spr2names[NUMPLAYERSPRITES][5];
+extern char spr2names[NUMPLAYERSPRITES][5];
 extern state_t *astate;
+extern enum playersprite free_spr2;
 
 typedef enum mobj_type
 {
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index 3260e377e278ec988d38395840042d0d0b69a7a3..4f7fdaa2647d62706869d68afd23a96ff63219c6 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -105,7 +105,7 @@ static int lib_getSpr2name(lua_State *L)
 	if (lua_isnumber(L, 1))
 	{
 		i = lua_tonumber(L, 1);
-		if (i > NUMPLAYERSPRITES)
+		if (i >= free_spr2)
 			return 0;
 		lua_pushlstring(L, spr2names[i], 4);
 		return 1;
@@ -113,7 +113,7 @@ static int lib_getSpr2name(lua_State *L)
 	else if (lua_isstring(L, 1))
 	{
 		const char *name = lua_tostring(L, 1);
-		for (i = 0; i < NUMPLAYERSPRITES; i++)
+		for (i = 0; i < free_spr2; i++)
 			if (fastcmp(name, spr2names[i]))
 			{
 				lua_pushinteger(L, i);
@@ -125,7 +125,7 @@ static int lib_getSpr2name(lua_State *L)
 
 static int lib_spr2namelen(lua_State *L)
 {
-	lua_pushinteger(L, NUMPLAYERSPRITES);
+	lua_pushinteger(L, free_spr2);
 	return 1;
 }
 
diff --git a/src/lzf.c b/src/lzf.c
index 33a1b2dcdfc237490dbe0cce2d0a702dbab8f505..272174f30a54a6c04b64c864dff2304f57cad6cc 100644
--- a/src/lzf.c
+++ b/src/lzf.c
@@ -59,7 +59,11 @@
  * Unconditionally aligning does not cost very much, so do it if unsure
  */
 #ifndef STRICT_ALIGN
-# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) || defined (__clang__)
+#if !(defined(__i386) || defined (__amd64)) || defined (__clang__)
+#define STRICT_ALIGN 1
+#else
+#define STRICT_ALIGN 0
+#endif
 #endif
 
 /*
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/p_map.c b/src/p_map.c
index c902b0774ab14571c72570625f0db288566865dd..9bcd1b29ec761c671091a25b5ecc86ab293f47e5 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -129,6 +129,10 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
 		return false;
 	}
 
+#ifdef ESLOPE
+	object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you.
+#endif
+
 	object->eflags |= MFE_SPRUNG; // apply this flag asap!
 	spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
 
@@ -232,20 +236,24 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
 	if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
 		return;
 
-	// is object below thruster's position? if not, calculate distance between their bottoms
+	// is object's top below thruster's position? if not, calculate distance between their bottoms
 	if (spring->eflags & MFE_VERTICALFLIP)
 	{
-		if (object->z + object->height > spring->z + spring->height)
+		if (object->z > spring->z + spring->height)
 			return;
 		zdist = (spring->z + spring->height) - (object->z + object->height);
 	}
 	else
 	{
-		if (object->z < spring->z)
+		if (object->z + object->height < spring->z)
 			return;
 		zdist = object->z - spring->z;
 	}
 
+#ifdef ESLOPE
+	object->standingslope = NULL; // No launching off at silly angles for you.
+#endif
+
 	switch (spring->type)
 	{
 		case MT_FAN: // fan
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 3c271551284c854baa07a39fe9a096876b4e4940..fe09f6c01c2c97e5e77c79dd53a9488288e8a879 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -2563,9 +2563,9 @@ static boolean P_ZMovement(mobj_t *mo)
 
 #ifdef ESLOPE
 		P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
-		if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) {
+		if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
+		{
 			mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
-
 			P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
 		}
 #endif
@@ -2719,7 +2719,7 @@ static boolean P_ZMovement(mobj_t *mo)
 			mom.z = tmfloorthing->momz;
 
 #ifdef ESLOPE
-		if (mo->standingslope) {
+		if (mo->standingslope) { // MT_STEAM will never have a standingslope, see above.
 			P_QuantizeMomentumToSlope(&mom, mo->standingslope);
 		}
 #endif
diff --git a/src/r_data.h b/src/r_data.h
index 4a37f82c3dd9815551670204fd1cd1a8f2c4779c..69a2882af52da27a55f2dca8a43a4006c8a66554 100644
--- a/src/r_data.h
+++ b/src/r_data.h
@@ -30,7 +30,7 @@ typedef struct
 {
 	// Block origin (always UL), which has already accounted for the internal origin of the patch.
 	INT16 originx, originy;
-	INT16 wad, lump;
+	UINT16 wad, lump;
 } texpatch_t;
 
 // A maptexturedef_t describes a rectangular texture,
diff --git a/src/r_draw8.c b/src/r_draw8.c
index 7bfe5c79b5df11cb932b5871f73afbba8ebc34e1..6cb600c5e0e005fe0f582afc09fd93d6953ac54f 100644
--- a/src/r_draw8.c
+++ b/src/r_draw8.c
@@ -874,9 +874,9 @@ void R_DrawTiltedSplat_8(void)
 
 		colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
 
-		val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+		val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			*dest = val;
+			*dest = colormap[val];
 		dest++;
 		iz += ds_sz.x;
 		uz += ds_su.x;
@@ -913,9 +913,9 @@ void R_DrawTiltedSplat_8(void)
 		for (i = SPANSIZE-1; i >= 0; i--)
 		{
 			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
-			val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+			val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
 			if (val != TRANSPARENTPIXEL)
-				*dest = val;
+				*dest = colormap[val];
 			dest++;
 			u += stepu;
 			v += stepv;
@@ -931,9 +931,9 @@ void R_DrawTiltedSplat_8(void)
 			u = (INT64)(startu);
 			v = (INT64)(startv);
 			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
-			val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+			val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
 			if (val != TRANSPARENTPIXEL)
-				*dest = val;
+				*dest = colormap[val];
 		}
 		else
 		{
@@ -954,9 +954,9 @@ void R_DrawTiltedSplat_8(void)
 			for (; width != 0; width--)
 			{
 				colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
-				val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+				val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
 				if (val != TRANSPARENTPIXEL)
-					*dest = val;
+					*dest = colormap[val];
 				dest++;
 				u += stepu;
 				v += stepv;
@@ -1124,49 +1124,49 @@ void R_DrawTranslucentSplat_8 (void)
 		// need!
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[0])];
+			dest[0] = colormap[*(ds_transmap + (val << 8) + dest[0])];
 		xposition += xstep;
 		yposition += ystep;
 
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[1])];
+			dest[1] = colormap[*(ds_transmap + (val << 8) + dest[1])];
 		xposition += xstep;
 		yposition += ystep;
 
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[2])];
+			dest[2] = colormap[*(ds_transmap + (val << 8) + dest[2])];
 		xposition += xstep;
 		yposition += ystep;
 
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[3])];
+			dest[3] = colormap[*(ds_transmap + (val << 8) + dest[3])];
 		xposition += xstep;
 		yposition += ystep;
 
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[4])];
+			dest[4] = colormap[*(ds_transmap + (val << 8) + dest[4])];
 		xposition += xstep;
 		yposition += ystep;
 
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[5])];
+			dest[5] = colormap[*(ds_transmap + (val << 8) + dest[5])];
 		xposition += xstep;
 		yposition += ystep;
 
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[6])];
+			dest[6] = colormap[*(ds_transmap + (val << 8) + dest[6])];
 		xposition += xstep;
 		yposition += ystep;
 
 		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[7])];
+			dest[7] = colormap[*(ds_transmap + (val << 8) + dest[7])];
 		xposition += xstep;
 		yposition += ystep;
 
@@ -1175,9 +1175,9 @@ void R_DrawTranslucentSplat_8 (void)
 	}
 	while (count--)
 	{
-		val =colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
+		val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
 		if (val != TRANSPARENTPIXEL)
-			*dest = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dest)];
+			*dest = colormap[*(ds_transmap + (val << 8) + *dest)];
 
 		dest++;
 		xposition += xstep;
diff --git a/src/r_main.c b/src/r_main.c
index c37c2b87bfb558ab2ecf21eef08c8e9a83c37743..38a169c0844039a97989dd7a6561152e7897e04e 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -919,9 +919,9 @@ void R_SkyboxFrame(player_t *player)
 				}
 			}
 			if (mh->skybox_scalez > 0)
-				viewz += player->awayviewmobj->z / mh->skybox_scalez;
+				viewz += (player->awayviewmobj->z + 20*FRACUNIT) / mh->skybox_scalez;
 			else if (mh->skybox_scalez < 0)
-				viewz += player->awayviewmobj->z * -mh->skybox_scalez;
+				viewz += (player->awayviewmobj->z + 20*FRACUNIT) * -mh->skybox_scalez;
 		}
 		else if (thiscam->chase)
 		{
@@ -966,9 +966,9 @@ void R_SkyboxFrame(player_t *player)
 				}
 			}
 			if (mh->skybox_scalez > 0)
-				viewz += thiscam->z / mh->skybox_scalez;
+				viewz += (thiscam->z + (thiscam->height>>1)) / mh->skybox_scalez;
 			else if (mh->skybox_scalez < 0)
-				viewz += thiscam->z * -mh->skybox_scalez;
+				viewz += (thiscam->z + (thiscam->height>>1)) * -mh->skybox_scalez;
 		}
 		else
 		{
diff --git a/src/r_segs.c b/src/r_segs.c
index 59b4f5db936c2cd4a8b2e83738324e4e4384708d..cb78743b6d9f2d90310ef2427949c2fa4376bf74 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -1488,7 +1488,7 @@ static void R_RenderSegLoop (void)
 			{
 				// note: don't use min/max macros, since casting from INT32 to INT16 is involved here
 				if (markceiling)
-					ceilingclip[rw_x] = (yh >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
+					ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
 				if (markfloor)
 					floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
 			}
@@ -1523,10 +1523,10 @@ static void R_RenderSegLoop (void)
 						ceilingclip[rw_x] = -1;
 				}
 				else
-					ceilingclip[rw_x] = (yh >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
+					ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
 			}
 			else if (markceiling) // no top wall
-				ceilingclip[rw_x] = (yh >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
+				ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
 
 			if (bottomtexture)
 			{
diff --git a/src/r_things.c b/src/r_things.c
index 6c26620fe9f542761f19b1c31a6274f2773019d1..4933517581f523e116b1a06e4319c5f86aa351dc 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2717,7 +2717,7 @@ next_token:
 			if (z < lastlump) lastlump = z;
 
 			// load all sprite sets we are aware of.
-			for (sprite2 = 0; sprite2 < NUMPLAYERSPRITES; sprite2++)
+			for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
 				R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump);
 		}
 
diff --git a/src/sdl/MakeNIX.cfg b/src/sdl/MakeNIX.cfg
index f5c9b20750ec560ea144ee797eab492e5b6c9ec8..1a0b5421048ac134924e8b47e7d606e0abcf37e3 100644
--- a/src/sdl/MakeNIX.cfg
+++ b/src/sdl/MakeNIX.cfg
@@ -56,6 +56,15 @@ ifdef FREEBSD
 	LIBS+=-lipx -lkvm
 endif
 
+#
+#here is Mac OS X
+#
+ifdef MACOSX
+	OBJS+=$(OBJDIR)/mac_resources.o
+	OBJS+=$(OBJDIR)/mac_alert.o
+	LIBS+=-framework CoreFoundation
+endif
+
 #
 #here is GP2x (arm-gp2x-linux)
 #
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/sdl/macosx/mac_alert.c b/src/sdl/macosx/mac_alert.c
index 455e36509547e40af0a4a65f13f0e5517fb5dc24..2a139041a65157d8852951156413a29eaaa3c943 100644
--- a/src/sdl/macosx/mac_alert.c
+++ b/src/sdl/macosx/mac_alert.c
@@ -25,19 +25,38 @@
 #include "mac_alert.h"
 #include <CoreFoundation/CoreFoundation.h>
 
+#define CFSTRINGIFY(x) CFStringCreateWithCString(NULL, x, kCFStringEncodingASCII)
+
 int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3)
 {
 	CFOptionFlags results;
 
-	CFUserNotificationDisplayAlert(0,
-	 kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag,
-	 NULL, NULL, NULL,
-	 CFStringCreateWithCString(NULL, title, kCFStringEncodingASCII),
-	 CFStringCreateWithCString(NULL, message, kCFStringEncodingASCII),
-	 button1 != NULL ? CFStringCreateWithCString(NULL, button1, kCFStringEncodingASCII) : NULL,
-	 button2 != NULL ? CFStringCreateWithCString(NULL, button2, kCFStringEncodingASCII) : NULL,
-	 button3 != NULL ? CFStringCreateWithCString(NULL, button3, kCFStringEncodingASCII) : NULL,
-	 &results);
+        CFStringRef cf_title   = CFSTRINGIFY(title);
+        CFStringRef cf_message = CFSTRINGIFY(message);
+        CFStringRef cf_button1 = NULL;
+        CFStringRef cf_button2 = NULL;
+        CFStringRef cf_button3 = NULL;
+
+        if (button1 != NULL)
+            cf_button1 = CFSTRINGIFY(button1);
+        if (button2 != NULL)
+            cf_button2 = CFSTRINGIFY(button2);
+        if (button3 != NULL)
+            cf_button3 = CFSTRINGIFY(button3);
+
+        CFOptionFlags alert_flags = kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag;
+
+	CFUserNotificationDisplayAlert(0, alert_flags, NULL, NULL, NULL, cf_title, cf_message,
+                                       cf_button1, cf_button2, cf_button3, &results);
+
+        if (cf_button1 != NULL)
+           CFRelease(cf_button1);
+        if (cf_button2 != NULL)
+           CFRelease(cf_button2);
+        if (cf_button3 != NULL)
+           CFRelease(cf_button3);
+        CFRelease(cf_message);
+        CFRelease(cf_title);
 
 	return (int)results;
 }
diff --git a/src/sdl/macosx/mac_resources.c b/src/sdl/macosx/mac_resources.c
index dacc8014ba8da8fcd48ccbfe56a7772c4ec6c0fc..d67b925802666207160e9d75d3d0179042ca34ff 100644
--- a/src/sdl/macosx/mac_resources.c
+++ b/src/sdl/macosx/mac_resources.c
@@ -9,23 +9,29 @@ void OSX_GetResourcesPath(char * buffer)
     mainBundle = CFBundleGetMainBundle();
     if (mainBundle)
     {
+        const int BUF_SIZE = 256; // because we somehow always know that
+
         CFURLRef appUrlRef = CFBundleCopyBundleURL(mainBundle);
-        CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
-        CFStringRef resources = CFStringCreateWithCString(kCFAllocatorMalloc, "/Contents/Resources", kCFStringEncodingASCII);
-        const void* rawarray[2] = {macPath, resources};
-        CFArrayRef array = CFArrayCreate(kCFAllocatorMalloc, rawarray, 2, NULL);
-        CFStringRef separator = CFStringCreateWithCString(kCFAllocatorMalloc, "", kCFStringEncodingASCII);
-        CFStringRef fullPath = CFStringCreateByCombiningStrings(kCFAllocatorMalloc, array, separator);
-        const char * path = CFStringGetCStringPtr(fullPath, kCFStringEncodingASCII);
-        strcpy(buffer, path);
-        CFRelease(fullPath);
-        path = NULL;
-        CFRelease(array);
-        CFRelease(resources);
+        CFStringRef macPath;
+        if (appUrlRef != NULL)
+            macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
+        else
+            macPath = NULL;
+
+        const char* rawPath;
+
+        if (macPath != NULL)
+            rawPath = CFStringGetCStringPtr(macPath, kCFStringEncodingASCII);
+        else
+            rawPath = NULL;
+
+        if (rawPath != NULL && (CFStringGetLength(macPath) + strlen("/Contents/Resources") < BUF_SIZE))
+        {
+            strcpy(buffer, rawPath);
+            strcat(buffer, "/Contents/Resources");
+        }
+
         CFRelease(macPath);
         CFRelease(appUrlRef);
-        //CFRelease(mainBundle);
-        CFRelease(separator);
     }
-
-}
\ No newline at end of file
+}
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>