From 5e821de481bb3430b06853d607d586300c5233f9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 25 Dec 2019 09:51:44 +0100 Subject: [PATCH] - replaced the leaky hash table that was used to handle the animations. Just replaced with a linear array - for a hash table indexed with a string to be efficient, a much larger amount of data is needed than 20 or 30 entries. This is also hardly the kind of data where losing a microsecond for performing the search matters. --- source/duke3d/src/anim.cpp | 71 +++++++++++++++----------------------- source/duke3d/src/anim.h | 11 +++--- source/duke3d/src/game.cpp | 21 +++-------- source/rr/src/anim.cpp | 71 +++++++++++++++++--------------------- source/rr/src/anim.h | 8 ++--- source/rr/src/game.cpp | 20 +++-------- 6 files changed, 79 insertions(+), 123 deletions(-) diff --git a/source/duke3d/src/anim.cpp b/source/duke3d/src/anim.cpp index 87e67601c..fb320d759 100644 --- a/source/duke3d/src/anim.cpp +++ b/source/duke3d/src/anim.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "renderlayer.h" #include "duke3d.h" #include "animlib.h" +#include "cmdlib.h" #include "compat.h" @@ -38,43 +39,35 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_DUKE_NS -// animsound_t.sound -EDUKE32_STATIC_ASSERT(INT16_MAX >= MAXSOUNDS); +dukeanim_t* g_animPtr; +TArray g_Animations; -hashtable_t h_dukeanim = { 8, NULL }; -dukeanim_t * g_animPtr; - -dukeanim_t *Anim_Find(const char *s) +dukeanim_t* Anim_Find(const char* s) { - intptr_t ptr = hash_findcase(&h_dukeanim, s); - - if (ptr == -1) + auto index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(s); }); + if (index == g_Animations.Size()) { - int const siz = Bstrlen(s) + 5; - char * const str = (char *)Xcalloc(1, siz); - - maybe_append_ext(str, siz, s, ".anm"); - ptr = hash_findcase(&h_dukeanim, str); - - if (ptr == -1) + FString fname = s; + DefaultExtension(fname, ".anm"); + index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(fname); }); + if (index == g_Animations.Size()) { - maybe_append_ext(str, siz, s, ".ivf"); - ptr = hash_findcase(&h_dukeanim, str); + fname = s; + DefaultExtension(fname, ".ivf"); + index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(fname); }); + if (index == g_Animations.Size()) return nullptr; } - - Xfree(str); } - - return (dukeanim_t *)(ptr == -1 ? NULL : (dukeanim_t *)ptr); + return &g_Animations[index]; } + dukeanim_t * Anim_Create(char const * fn) { - dukeanim_t * anim = (dukeanim_t *)Xcalloc(1, sizeof(dukeanim_t)); - - hash_add(&h_dukeanim, fn, (intptr_t)anim, 0); - - return anim; + g_Animations.Reserve(1); + auto p = &g_Animations.Last(); + p->name = fn; + return p; } #ifndef EDUKE32_STANDALONE @@ -87,9 +80,6 @@ static int32_t const StopAllSounds = -1; void Anim_Init(void) { - hash_init(&h_dukeanim); - - struct defaultanmsound { #ifdef DYNSOUNDREMAP_ENABLE int32_t const & sound; @@ -208,17 +198,16 @@ void Anim_Init(void) if (anm.numsounds) { - anim->sounds = (animsound_t *)dump.Alloc(anm.numsounds * sizeof(animsound_t)); + anim->Sounds.Resize(anm.numsounds); int const numsounds = anm.numsounds; for (int i = 0; i < numsounds; ++i) { defaultanmsound const & src = anm.sounds[i]; - animsound_t & dst = anim->sounds[i]; + animsound_t & dst = anim->Sounds[i]; dst.sound = src.sound; dst.frame = src.frame; } - anim->numsounds = numsounds; } anim->frameflags = 0; @@ -358,9 +347,9 @@ int32_t Anim_Play(const char *fn) framenum++; if (anim) { - while (soundidx < anim->numsounds && anim->sounds[soundidx].frame <= framenum) + while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= framenum) { - int16_t sound = anim->sounds[soundidx].sound; + int16_t sound = anim->Sounds[soundidx].sound; if (sound == -1) FX_StopAllSounds(); else @@ -372,9 +361,9 @@ int32_t Anim_Play(const char *fn) else { uint16_t convframenum = scale(framenum, convnumer, convdenom); - while (soundidx < origanim->numsounds && origanim->sounds[soundidx].frame <= convframenum) + while (soundidx < origanim->Sounds.Size() && origanim->Sounds[soundidx].frame <= convframenum) { - int16_t sound = origanim->sounds[soundidx].sound; + int16_t sound = origanim->Sounds[soundidx].sound; if (sound == -1) FX_StopAllSounds(); else @@ -518,7 +507,6 @@ int32_t Anim_Play(const char *fn) z = divscale16(200, tilesiz[TILE_ANIM].x); rotatesprite_fs(160<<16, 100<<16, z, 512, TILE_ANIM, 0, 0, 2|4|8|64); } - g_animPtr = anim; i = VM_OnEventWithReturn(EVENT_CUTSCENE, g_player[screenpeek].ps->i, screenpeek, i); g_animPtr = NULL; @@ -529,9 +517,9 @@ int32_t Anim_Play(const char *fn) ototalclock += anim->framedelay; - while (soundidx < anim->numsounds && anim->sounds[soundidx].frame <= (uint16_t)i) + while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= (uint16_t)i) { - int16_t sound = anim->sounds[soundidx].sound; + int16_t sound = anim->Sounds[soundidx].sound; if (sound == -1) FX_StopAllSounds(); else @@ -539,7 +527,6 @@ int32_t Anim_Play(const char *fn) soundidx++; } - ++i; } while (i < numframes); @@ -555,8 +542,6 @@ end_anim: tileDelete(TILE_ANIM); - // this is the lock for anim->animbuf - return !running; } diff --git a/source/duke3d/src/anim.h b/source/duke3d/src/anim.h index 9927eec32..a921bd84c 100644 --- a/source/duke3d/src/anim.h +++ b/source/duke3d/src/anim.h @@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "compat.h" #include "hash.h" +#include "tarray.h" +#include "zstring.h" BEGIN_DUKE_NS @@ -35,16 +37,17 @@ typedef struct { typedef struct { + FString name; double frameaspect1, frameaspect2; uint8_t* animbuf; - animsound_t *sounds; - uint16_t numsounds; + TArray Sounds; uint8_t framedelay; uint8_t frameflags; } dukeanim_t; -extern dukeanim_t * g_animPtr; -extern hashtable_t h_dukeanim; +extern dukeanim_t* g_animPtr; +extern TArray g_Animations; + extern dukeanim_t * Anim_Find(const char *s); extern dukeanim_t * Anim_Create(const char *fn); int32_t Anim_Play(const char *fn); diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 22c55c8fd..057f71827 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -4756,12 +4756,9 @@ static void parsedefinitions_game_include(const char *fileName, scriptfile *pScr static void parsedefinitions_game_animsounds(scriptfile *pScript, const char * blockEnd, char const * fileName, dukeanim_t * animPtr) { - Xfree(animPtr->sounds); + size_t numPairs = 0; - size_t numPairs = 0, allocSize = 4; - - animPtr->sounds = (animsound_t *)Xmalloc(allocSize * sizeof(animsound_t)); - animPtr->numsounds = 0; + animPtr->Sounds.Clear(); int defError = 1; uint16_t lastFrameNum = 1; @@ -4812,32 +4809,27 @@ static void parsedefinitions_game_animsounds(scriptfile *pScript, const char * b break; } - if (numPairs >= allocSize) - { - allocSize *= 2; - animPtr->sounds = (animsound_t *)Xrealloc(animPtr->sounds, allocSize * sizeof(animsound_t)); - } defError = 0; - animsound_t & sound = animPtr->sounds[numPairs]; + animsound_t sound; sound.frame = frameNum; sound.sound = soundNum; + animPtr->Sounds.Push(sound); ++numPairs; } if (!defError) { - animPtr->numsounds = numPairs; // initprintf("Defined sound sequence for hi-anim \"%s\" with %d frame/sound pairs\n", // hardcoded_anim_tokens[animnum].text, numpairs); } else { - DO_FREE_AND_NULL(animPtr->sounds); initprintf("Failed defining sound sequence for anim \"%s\".\n", fileName); } + animPtr->Sounds.ShrinkToFit(); } static int parsedefinitions_game(scriptfile *pScript, int firstPass) @@ -5323,9 +5315,6 @@ static void G_Cleanup(void) hash_free(&h_arrays); hash_free(&h_labels); #endif - - hash_loop(&h_dukeanim, G_FreeHashAnim); - hash_free(&h_dukeanim); } /* diff --git a/source/rr/src/anim.cpp b/source/rr/src/anim.cpp index abc2e0bd7..7e4c9abd5 100644 --- a/source/rr/src/anim.cpp +++ b/source/rr/src/anim.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "animlib.h" #include "compat.h" +#include "cmdlib.h" #include "anim.h" @@ -40,40 +41,34 @@ BEGIN_RR_NS // animsound_t.sound EDUKE32_STATIC_ASSERT(INT16_MAX >= MAXSOUNDS); -hashtable_t h_dukeanim = { 8, NULL }; +TArray g_Animations; dukeanim_t * g_animPtr; -dukeanim_t *Anim_Find(const char *s) +dukeanim_t* Anim_Find(const char* s) { - intptr_t ptr = hash_findcase(&h_dukeanim, s); - - if (ptr == -1) + auto index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(s); }); + if (index == g_Animations.Size()) { - int const siz = Bstrlen(s) + 5; - char * const str = (char *)Xcalloc(1, siz); - - maybe_append_ext(str, siz, s, ".anm"); - ptr = hash_findcase(&h_dukeanim, str); - - if (ptr == -1) + FString fname = s; + DefaultExtension(fname, ".anm"); + index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(fname); }); + if (index == g_Animations.Size()) { - maybe_append_ext(str, siz, s, ".ivf"); - ptr = hash_findcase(&h_dukeanim, str); + fname = s; + DefaultExtension(fname, ".ivf"); + index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(fname); }); + if (index == g_Animations.Size()) return nullptr; } - - Bfree(str); } - - return (dukeanim_t *)(ptr == -1 ? NULL : (dukeanim_t *)ptr); + return &g_Animations[index]; } dukeanim_t * Anim_Create(char const * fn) { - dukeanim_t * anim = (dukeanim_t *)Xcalloc(1, sizeof(dukeanim_t)); - - hash_add(&h_dukeanim, fn, (intptr_t)anim, 0); - - return anim; + g_Animations.Reserve(1); + auto p = &g_Animations.Last(); + p->name = fn; + return p; } #ifdef DYNSOUNDREMAP_ENABLE @@ -84,9 +79,6 @@ static int32_t const StopAllSounds = -1; void Anim_Init(void) { - hash_init(&h_dukeanim); - - struct defaultanmsound { #ifdef DYNSOUNDREMAP_ENABLE int32_t const & sound; @@ -237,24 +229,23 @@ void Anim_Init(void) }; #undef anmsnd - for (defaultanm const & anm : anms) + for (defaultanm const& anm : anms) { - dukeanim_t * anim = Anim_Create(anm.fn); + dukeanim_t* anim = Anim_Create(anm.fn); anim->framedelay = anm.fdelay; if (anm.numsounds) { - anim->sounds = (animsound_t *)Xmalloc(anm.numsounds * sizeof(animsound_t)); - size_t const numsounds = anm.numsounds; - for (size_t i = 0; i < numsounds; ++i) + anim->Sounds.Resize(anm.numsounds); + int const numsounds = anm.numsounds; + for (int i = 0; i < numsounds; ++i) { - defaultanmsound const & src = anm.sounds[i]; - animsound_t & dst = anim->sounds[i]; + defaultanmsound const& src = anm.sounds[i]; + animsound_t& dst = anim->Sounds[i]; dst.sound = src.sound; dst.frame = src.frame; } - anim->numsounds = numsounds; } anim->frameflags = 0; @@ -390,9 +381,9 @@ int32_t Anim_Play(const char *fn) framenum++; if (anim) { - while (soundidx < anim->numsounds && anim->sounds[soundidx].frame <= framenum) + while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= framenum) { - int16_t sound = anim->sounds[soundidx].sound; + int16_t sound = anim->Sounds[soundidx].sound; if (sound == -1) FX_StopAllSounds(); else @@ -404,9 +395,9 @@ int32_t Anim_Play(const char *fn) else { uint16_t convframenum = scale(framenum, convnumer, convdenom); - while (soundidx < origanim->numsounds && origanim->sounds[soundidx].frame <= convframenum) + while (soundidx < origanim->Sounds.Size() && origanim->Sounds[soundidx].frame <= convframenum) { - int16_t sound = origanim->sounds[soundidx].sound; + int16_t sound = origanim->Sounds[soundidx].sound; if (sound == -1) FX_StopAllSounds(); else @@ -560,9 +551,9 @@ int32_t Anim_Play(const char *fn) ototalclock += anim->framedelay; - while (soundidx < anim->numsounds && anim->sounds[soundidx].frame <= (uint16_t)i) + while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= (uint16_t)i) { - int16_t sound = anim->sounds[soundidx].sound; + int16_t sound = anim->Sounds[soundidx].sound; if (sound == -1) FX_StopAllSounds(); else diff --git a/source/rr/src/anim.h b/source/rr/src/anim.h index 757f9fc67..595dc0e0f 100644 --- a/source/rr/src/anim.h +++ b/source/rr/src/anim.h @@ -32,16 +32,16 @@ typedef struct { typedef struct { + FString name; double frameaspect1, frameaspect2; uint8_t* animbuf; - animsound_t *sounds; - uint16_t numsounds; + TArray Sounds; uint8_t framedelay; uint8_t frameflags; } dukeanim_t; -extern dukeanim_t * g_animPtr; -extern hashtable_t h_dukeanim; +extern dukeanim_t* g_animPtr; +extern TArray g_Animations; extern dukeanim_t * Anim_Find(const char *s); extern dukeanim_t * Anim_Create(const char *fn); int32_t Anim_Play(const char *fn); diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 316daf9a4..320bb717c 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -6317,12 +6317,9 @@ static void parsedefinitions_game_include(const char *fileName, scriptfile *pScr static void parsedefinitions_game_animsounds(scriptfile *pScript, const char * blockEnd, char const * fileName, dukeanim_t * animPtr) { - Bfree(animPtr->sounds); - size_t numPairs = 0, allocSize = 4; - animPtr->sounds = (animsound_t *)Xmalloc(allocSize * sizeof(animsound_t)); - animPtr->numsounds = 0; + animPtr->Sounds.Clear(); int defError = 1; uint16_t lastFrameNum = 1; @@ -6373,32 +6370,26 @@ static void parsedefinitions_game_animsounds(scriptfile *pScript, const char * b break; } - if (numPairs >= allocSize) - { - allocSize *= 2; - animPtr->sounds = (animsound_t *)Xrealloc(animPtr->sounds, allocSize * sizeof(animsound_t)); - } - defError = 0; - animsound_t & sound = animPtr->sounds[numPairs]; + animsound_t sound; sound.frame = frameNum; sound.sound = soundNum; + animPtr->Sounds.Push(sound); ++numPairs; } if (!defError) { - animPtr->numsounds = numPairs; // initprintf("Defined sound sequence for hi-anim \"%s\" with %d frame/sound pairs\n", // hardcoded_anim_tokens[animnum].text, numpairs); } else { - DO_FREE_AND_NULL(animPtr->sounds); initprintf("Failed defining sound sequence for anim \"%s\".\n", fileName); } + animPtr->Sounds.ShrinkToFit(); } static int parsedefinitions_game(scriptfile *pScript, int firstPass) @@ -6734,9 +6725,6 @@ static void G_Cleanup(void) // Bfree(MusicPtr); hash_free(&h_labels); - - hash_loop(&h_dukeanim, G_FreeHashAnim); - hash_free(&h_dukeanim); } /*