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>