From bbcf2bb6f9b983ccd031fe6c0c90d0b9e9b61bf6 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 4 Dec 2025 01:23:33 -0500 Subject: [PATCH] Cache emote patches as they are used to prevent excess calls to W_CachePatchName --- src/m_emotes.cpp | 40 +++++++++++++++++++++++++++++++++++++++- src/m_emotes.h | 6 ++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/m_emotes.cpp b/src/m_emotes.cpp index a6a56d0f4..1944eba42 100644 --- a/src/m_emotes.cpp +++ b/src/m_emotes.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "m_emotes.h" #include "i_time.h" // I_GetTime @@ -20,6 +21,8 @@ static void Command_ListEmotes_f(void); static std::map emotes; +static std::vector emotecache; + // TODO - Would be really nice to generalize soc-like file parsing and not reimplement it 100 times :))))) void M_LoadEmotes(UINT16 wadnum) { @@ -243,13 +246,48 @@ emote_t *M_VerifyEmote(const char *name, int *emotelen) return match; } +static patch_t *M_ReturnEmotePatch(const char *lumpname) +{ + UINT32 hash = HASH32(lumpname, 8); + emotecache_t cache; + + if (emotecache.empty()) + { + cache = {lumpname, hash, (patch_t*)W_CachePatchName(lumpname, PU_CACHE)}; + + emotecache.push_back(cache); + return emotecache.back().patch; + } + else + { + size_t i; + + for (i = 0; i < emotecache.size(); i++) + { + if (emotecache[i].hash != hash) + continue; + if (stricmp(emotecache[i].name, lumpname)) + continue; + + return emotecache[i].patch; + } + + cache = {lumpname, hash, (patch_t*)W_CachePatchName(lumpname, PU_CACHE)}; + + emotecache.push_back(cache); + return emotecache.back().patch; + } +} + void M_DrawScaledEmote(fixed_t x, fixed_t y, fixed_t scale, emote_t *emote, INT32 flags) { if (emote->numframes == 0) return; const char *lumpname = emote->frames[(I_GetTime()/emote->timeperframe) % emote->numframes]; - patch_t *emotepatch = (patch_t*)W_CachePatchName(lumpname, PU_CACHE); + // Cache this emote patch after grabbing it for the first time + // so packed addon lists don't get their frames nuked by cachenum calls... + patch_t *emotepatch = M_ReturnEmotePatch(lumpname); const int CHARHEIGHT = 6; diff --git a/src/m_emotes.h b/src/m_emotes.h index 7601d9d16..6c4959247 100644 --- a/src/m_emotes.h +++ b/src/m_emotes.h @@ -22,6 +22,12 @@ typedef struct emote_s { tic_t timeperframe; } emote_t; +typedef struct emotecache_s { + const char *name; + UINT32 hash; + patch_t *patch; +} emotecache_t; + // Reads and adds emotes from EMOTES lump, with syntax similar to soc void M_LoadEmotes(UINT16 wadnum);