From 536075b00a3d36973b123b5d54f32cc2b7ee3b58 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 13 May 2025 22:28:29 +0200 Subject: [PATCH 01/15] Add string buffer library --- src/Sourcefile | 1 + src/strbuf.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/strbuf.h | 29 ++++++++++++++++++++++++++ src/typedef.h | 3 +++ 4 files changed, 88 insertions(+) create mode 100644 src/strbuf.c create mode 100644 src/strbuf.h diff --git a/src/Sourcefile b/src/Sourcefile index 36b9a0e79..e8e6eb5f7 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -1,5 +1,6 @@ qs22j.c string.c +strbuf.c d_main.cpp d_clisrv.c d_net.c diff --git a/src/strbuf.c b/src/strbuf.c new file mode 100644 index 000000000..a38db9aad --- /dev/null +++ b/src/strbuf.c @@ -0,0 +1,55 @@ +// BLANKART +//----------------------------------------------------------------------------- +// Copyright (C) 2025 by Team BlanKart. +// +// 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 strbuf.c +/// \brief string buffer library, for making chunks of many small strings + +#include "doomdef.h" +#include "strbuf.h" +#include "z_zone.h" + +#define STRBUF_BLOCKSIZE 16384 // 16K pages are the future, son! + +// allocates and returns a new string buffer +// free with Z_Free +strbuf_t *strbuf_alloc(void) +{ + strbuf_t *buf = Z_Malloc(STRBUF_BLOCKSIZE, PU_STATIC, NULL); + if (!buf) + I_Error("Failed to allocate string buffer"); + buf->size = sizeof(UINT32); + return buf; +} + +// appends a string to the buffer +// returns an offset to the newly appended string +UINT32 strbuf_append(strbuf_t **strbuf, const char *str) +{ + strbuf_t *buf = *strbuf; + size_t addbytes = strlen(str) + 1; + UINT32 oldsize = buf->size; + + buf->size += addbytes; + if ((oldsize % STRBUF_BLOCKSIZE) + addbytes >= STRBUF_BLOCKSIZE) { + UINT32 newsize = buf->size + STRBUF_BLOCKSIZE - (buf->size % STRBUF_BLOCKSIZE); + if (newsize <= oldsize) + I_Error("String buffer size wrapped around!?"); + buf = *strbuf = Z_Realloc(buf, newsize, PU_STATIC, NULL); + if (!buf) + I_Error("Failed to allocate string buffer"); + } + + strcpy(buf->buf - sizeof(UINT32) + oldsize, str); + return oldsize; +} + +// returns the string at the given offset +char *strbuf_get(strbuf_t *strbuf, UINT32 ofs) +{ + return strbuf->buf - sizeof(UINT32) + ofs; +} diff --git a/src/strbuf.h b/src/strbuf.h new file mode 100644 index 000000000..238e5bf7f --- /dev/null +++ b/src/strbuf.h @@ -0,0 +1,29 @@ +// BLANKART +//----------------------------------------------------------------------------- +// Copyright (C) 2025 by Team BlanKart. +// +// 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 strbuf.h +/// \brief string buffer library, for making chunks of many small strings + +#ifdef __cplusplus +extern "C" { +#endif + +// for simplicity's sake, the header is included in the size (keeps the allocation aligned!) +struct strbuf_t +{ + UINT32 size; + char buf[]; +}; + +strbuf_t *strbuf_alloc(void); +UINT32 strbuf_append(strbuf_t **strbuf, const char *str); +char *strbuf_get(strbuf_t *strbuf, UINT32 ofs); + +#ifdef __cplusplus +} +#endif diff --git a/src/typedef.h b/src/typedef.h index 467352019..312eaff03 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -393,6 +393,9 @@ TYPEDEF (vmode_t); // sounds.h TYPEDEF (sfxinfo_t); +// strbuf.h +TYPEDEF (strbuf_t); + // taglist.h TYPEDEF (taglist_t); TYPEDEF (taggroup_t); From 1793c2ea95e521522d2ac91c5c9e6b6363fde688 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 14 May 2025 15:35:26 +0200 Subject: [PATCH 02/15] Use string buffers for mobjs and states --- src/acs/call-funcs.cpp | 69 +++++++++--------------------------------- src/d_netcmd.c | 8 ++--- src/deh_lua.c | 49 +++++++++++------------------- src/deh_soc.c | 36 +++++++++------------- src/deh_tables.c | 24 ++------------- src/deh_tables.h | 11 +++---- src/dehacked.c | 23 ++++++++++++++ src/info.h | 4 +++ src/lua_infolib.c | 52 +++++++++++++++++++------------ src/p_tick.c | 8 ++--- 10 files changed, 121 insertions(+), 163 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 367569279..474d294e1 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -83,23 +83,14 @@ static bool ACS_GetMobjTypeFromString(const char *word, mobjtype_t *type) word += 3; } - for (int i = 0; i < NUMMOBJFREESLOTS; i++) + for (int i = 0; i < NUMMOBJTYPES; i++) { - if (!FREE_MOBJS[i]) + if (!mobjinfo[i].nameofs) { break; } - if (fastcmp(word, FREE_MOBJS[i])) - { - *type = static_cast(static_cast(MT_FIRSTFREESLOT) + i); - return true; - } - } - - for (int i = 0; i < MT_FIRSTFREESLOT; i++) - { - if (fastcmp(word, MOBJTYPE_LIST[i] + 3)) + if (fastcmp(word, strbuf_get(mobjnames, mobjinfo[i].nameofs))) { *type = static_cast(i); return true; @@ -234,23 +225,14 @@ static bool ACS_GetStateFromString(const char *word, statenum_t *type) word += 2; } - for (int i = 0; i < NUMMOBJFREESLOTS; i++) + for (int i = 0; i < NUMSTATES; i++) { - if (!FREE_STATES[i]) + if (!states[i].nameofs) { break; } - if (fastcmp(word, FREE_STATES[i])) - { - *type = static_cast(static_cast(S_FIRSTFREESLOT) + i); - return true; - } - } - - for (int i = 0; i < S_FIRSTFREESLOT; i++) - { - if (fastcmp(word, STATE_LIST[i] + 2)) + if (fastcmp(word, strbuf_get(statenames, states[i].nameofs))) { *type = static_cast(i); return true; @@ -2336,16 +2318,9 @@ bool CallFunc_GetObjectClass(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS mobj_t *mobj = P_FindMobjFromTID(argV[0], NULL, info->mo); if (mobj != NULL && P_MobjWasRemoved(mobj) == false) { - if (mobj->type >= MT_FIRSTFREESLOT) - { - std::string prefix = "MT_"; - std::string full = prefix + FREE_MOBJS[mobj->type - MT_FIRSTFREESLOT]; - mobjClass = static_cast( ~env->getString( full.c_str() )->idx ); - } - else - { - mobjClass = static_cast( ~env->getString( MOBJTYPE_LIST[ mobj->type ] )->idx ); - } + std::string prefix = "MT_"; + std::string full = prefix + (strbuf_get(mobjnames, mobjinfo[mobj->type].nameofs)); + mobjClass = static_cast( ~env->getString( full.c_str() )->idx ); } thread->dataStk.push(mobjClass); @@ -4397,16 +4372,9 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A #define PROP_TYPE(x, y) \ case x: \ { \ - if (mobj->y >= MT_FIRSTFREESLOT) \ - { \ - std::string prefix = "MT_"; \ - std::string full = prefix + FREE_MOBJS[mobj->y - MT_FIRSTFREESLOT]; \ - value = static_cast( ~env->getString( full.c_str() )->idx ); \ - } \ - else \ - { \ - value = static_cast( ~env->getString( MOBJTYPE_LIST[ mobj->y ] )->idx ); \ - } \ + std::string prefix = "MT_"; \ + std::string full = prefix + (strbuf_get(mobjnames, mobjinfo[mobj->y].nameofs)); \ + value = static_cast( ~env->getString( full.c_str() )->idx ); \ break; \ } @@ -4430,16 +4398,9 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A case x: \ { \ statenum_t stateID = static_cast(mobj->y - states); \ - if (stateID >= S_FIRSTFREESLOT) \ - { \ - std::string prefix = "S_"; \ - std::string full = prefix + FREE_STATES[stateID - S_FIRSTFREESLOT]; \ - value = static_cast( ~env->getString( full.c_str() )->idx ); \ - } \ - else \ - { \ - value = static_cast( ~env->getString( STATE_LIST[ stateID ] )->idx ); \ - } \ + std::string prefix = "S_"; \ + std::string full = prefix + strbuf_get(statenames, states[stateID].nameofs); \ + value = static_cast( ~env->getString( full.c_str() )->idx ); \ break; \ } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f0f6eea77..c3e705bcc 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4872,10 +4872,10 @@ static void Command_ListDoomednums_f(void) CONS_Printf(" doomednum \x82""%d""\x80 is \x85""double-defined\x80 by ", j+1); if (i < MT_FIRSTFREESLOT) { - CONS_Printf("\x87""hardcode %s <-- MAJOR ERROR\n", MOBJTYPE_LIST[i]); + CONS_Printf("\x87""hardcode MT_%s <-- MAJOR ERROR\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); continue; } - CONS_Printf("\x81""freeslot MT_""%s\n", FREE_MOBJS[i-MT_FIRSTFREESLOT]); + CONS_Printf("\x81""freeslot MT_""%s\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); continue; } table[j] = i; @@ -4908,10 +4908,10 @@ static void Command_ListDoomednums_f(void) CONS_Printf(" doomednum \x82""%d""\x80 is used by ", i+1); if (table[i] < MT_FIRSTFREESLOT) { - CONS_Printf("\x87""hardcode %s\n", MOBJTYPE_LIST[table[i]]); + CONS_Printf("\x87""hardcode MT_%s\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); continue; } - CONS_Printf("\x81""freeslot MT_""%s\n", FREE_MOBJS[table[i]-MT_FIRSTFREESLOT]); + CONS_Printf("\x81""freeslot MT_""%s\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); } } diff --git a/src/deh_lua.c b/src/deh_lua.c index 0e1915d05..a1983727b 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -81,33 +81,31 @@ static inline int lib_freeslot(lua_State *L) else if (fastcmp(type, "S")) { statenum_t i; - for (i = 0; i < NUMSTATEFREESLOTS; i++) - if (!FREE_STATES[i]) { + for (i = S_FIRSTFREESLOT; i < NUMSTATES; i++) + if (!states[i].nameofs) { CONS_Printf("State S_%s allocated.\n",word); - FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_STATES[i],word); + states[i].nameofs = strbuf_append(&statenames, word); freeslotusage[0][0]++; - lua_pushinteger(L, S_FIRSTFREESLOT + i); + lua_pushinteger(L, i); r++; break; } - if (i == NUMSTATEFREESLOTS) + if (i == NUMSTATES) CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n"); } else if (fastcmp(type, "MT")) { mobjtype_t i; - for (i = 0; i < NUMMOBJFREESLOTS; i++) - if (!FREE_MOBJS[i]) { + for (i = MT_FIRSTFREESLOT; i < NUMMOBJTYPES; i++) + if (!mobjinfo[i].nameofs) { CONS_Printf("MobjType MT_%s allocated.\n",word); - FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_MOBJS[i],word); + mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); freeslotusage[1][0]++; - lua_pushinteger(L, MT_FIRSTFREESLOT + i); + lua_pushinteger(L, i); r++; break; } - if (i == NUMMOBJFREESLOTS) + if (i == NUMMOBJTYPES) CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); } else if (fastcmp(type, "SKINCOLOR")) @@ -426,19 +424,14 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) lua_pushinteger(L, S_FIRSTFREESLOT); return 1; } - for (i = 0; i < NUMSTATEFREESLOTS; i++) { - if (!FREE_STATES[i]) + for (i = 0; i < NUMSTATES; i++) { + if (!states[i].nameofs) break; - if (fastcmp(p, FREE_STATES[i])) { - CacheAndPushConstant(L, word, S_FIRSTFREESLOT+i); - return 1; - } - } - for (i = 0; i < S_FIRSTFREESLOT; i++) - if (fastcmp(p, STATE_LIST[i]+2)) { + if (fastcmp(p, strbuf_get(statenames, states[i].nameofs))) { CacheAndPushConstant(L, word, i); return 1; } + } if (lua_compatmode) for (i = 0; STATE_ALIASES[i].n; i++) if (fastcmp(p, STATE_ALIASES[i].n)) { @@ -454,20 +447,14 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) lua_pushinteger(L, MT_FIRSTFREESLOT); return 1; } - for (i = 0; i < NUMMOBJFREESLOTS; i++) { - if (!FREE_MOBJS[i]) + for (i = 0; i < NUMMOBJTYPES; i++) { + if (!mobjinfo[i].nameofs) break; - if (fastcmp(p, FREE_MOBJS[i])) { - CacheAndPushConstant(L, word, MT_FIRSTFREESLOT+i); - return 1; - } - } - for (i = 0; i < MT_FIRSTFREESLOT; i++) - if (fastcmp(p, MOBJTYPE_LIST[i]+3)) { + if (fastcmp(p, strbuf_get(mobjnames, mobjinfo[i].nameofs))) { CacheAndPushConstant(L, word, i); return 1; } - + } if (lua_compatmode) for (i = 0; MOBJ_ALIASES[i].n; i++) if (fastcmp(p, MOBJ_ALIASES[i].n)) { diff --git a/src/deh_soc.c b/src/deh_soc.c index 6ca47041c..909760398 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -444,22 +444,20 @@ void readfreeslots(MYFILE *f) } else if (fastcmp(type, "S")) { - for (i = 0; i < NUMSTATEFREESLOTS; i++) - if (!FREE_STATES[i]) { + for (i = S_FIRSTFREESLOT; i < NUMSTATES; i++) + if (!states[i].nameofs) { CONS_Printf("State S_%s allocated.\n",word); - FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_STATES[i],word); + states[i].nameofs = strbuf_append(&statenames, word); freeslotusage[0][0]++; break; } } else if (fastcmp(type, "MT")) { - for (i = 0; i < NUMMOBJFREESLOTS; i++) - if (!FREE_MOBJS[i]) { + for (i = MT_FIRSTFREESLOT; i < NUMMOBJFREESLOTS; i++) + if (!mobjinfo[i].nameofs) { CONS_Printf("MobjType MT_%s allocated.\n",word); - FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_MOBJS[i],word); + mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); freeslotusage[1][0]++; break; } @@ -4266,15 +4264,12 @@ mobjtype_t get_mobjtype(const char *word) return atoi(word); if (fastncmp("MT_",word,3)) word += 3; // take off the MT_ - for (i = 0; i < NUMMOBJFREESLOTS; i++) { - if (!FREE_MOBJS[i]) + for (i = 0; i < NUMMOBJTYPES; i++) { + if (!mobjinfo[i].nameofs) break; - if (fastcmp(word, FREE_MOBJS[i])) - return MT_FIRSTFREESLOT+i; - } - for (i = 0; i < MT_FIRSTFREESLOT; i++) - if (fastcmp(word, MOBJTYPE_LIST[i]+3)) + if (fastcmp(word, strbuf_get(mobjnames, mobjinfo[i].nameofs))) return i; + } deh_warning("Couldn't find mobjtype named 'MT_%s'",word); return -1; } @@ -4286,15 +4281,12 @@ statenum_t get_state(const char *word) return atoi(word); if (fastncmp("S_",word,2)) word += 2; // take off the S_ - for (i = 0; i < NUMSTATEFREESLOTS; i++) { - if (!FREE_STATES[i]) + for (i = 0; i < NUMSTATES; i++) { + if (!states[i].nameofs) break; - if (fastcmp(word, FREE_STATES[i])) - return S_FIRSTFREESLOT+i; - } - for (i = 0; i < S_FIRSTFREESLOT; i++) - if (fastcmp(word, STATE_LIST[i]+2)) + if (fastcmp(word, strbuf_get(statenames, states[i].nameofs))) return i; + } deh_warning("Couldn't find state named 'S_%s'",word); return -1; } diff --git a/src/deh_tables.c b/src/deh_tables.c index f11c807fa..57229a2ee 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -32,8 +32,8 @@ #include "deh_tables.h" -char *FREE_STATES[NUMSTATEFREESLOTS]; -char *FREE_MOBJS[NUMMOBJFREESLOTS]; +strbuf_t *statenames; +strbuf_t *mobjnames; char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; char *FREE_MENUS[NUMMENUFREESLOTS]; UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. @@ -83,12 +83,6 @@ actionpointer_t actionpointers[] = // TODO: Make the lists public so we can start using actual mobj // and state names in warning and error messages! :D -const char *const STATE_LIST[] = { // array length left dynamic for sanity testing later. -#define _(name, ...) "S_"#name, -#include "info/states.h" -#undef _ -}; - struct int_const_s const STATE_ALIASES[] = { {"KART_STND1", S_KART_STILL}, {"KART_STND2" , S_KART_STILL}, @@ -123,12 +117,6 @@ struct int_const_s const STATE_ALIASES[] = { { NULL, 0 } }; -const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity testing later. -#define _(name, ...) "MT_"#name, -#include "info/mobjs.h" -#undef _ -}; - struct int_const_s const MOBJ_ALIASES[] = { {"BIRD", MT_FLICKY_01}, {"BUNNY" , MT_FLICKY_02}, @@ -1529,16 +1517,8 @@ struct int_const_s const INT_CONST[] = { void DEH_TableCheck(void) { #if defined(_DEBUG) || defined(PARANOIA) - const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); - const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*); const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*); - if (dehstates != S_FIRSTFREESLOT) - I_Error("You forgot to update the Dehacked states list, you dolt!\n(%d states defined, versus %s in the Dehacked list)\n", S_FIRSTFREESLOT, sizeu1(dehstates)); - - if (dehmobjs != MT_FIRSTFREESLOT) - I_Error("You forgot to update the Dehacked mobjtype list, you dolt!\n(%d mobj types defined, versus %s in the Dehacked list)\n", MT_FIRSTFREESLOT, sizeu1(dehmobjs)); - if (dehcolors != SKINCOLOR_FIRSTFREESLOT) I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors)); #endif diff --git a/src/deh_tables.h b/src/deh_tables.h index 4451f6b51..5071e7a2b 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -18,6 +18,7 @@ #include "info.h" // Mobj, state, sprite, etc constants #include "m_menu.h" // NUMMENUFREESLOTS #include "lua_script.h" +#include "strbuf.h" #ifdef __cplusplus extern "C" { @@ -25,15 +26,15 @@ extern "C" { // Free slot names // The crazy word-reading stuff uses these. -extern char *FREE_STATES[NUMSTATEFREESLOTS]; -extern char *FREE_MOBJS[NUMMOBJFREESLOTS]; +extern strbuf_t *statenames; +extern strbuf_t *mobjnames; extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; extern char *FREE_MENUS[NUMMENUFREESLOTS]; extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. #define initfreeslots() {\ - memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\ - memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\ + statenames = strbuf_alloc();\ + mobjnames = strbuf_alloc();\ memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ } @@ -71,9 +72,7 @@ struct int_const_s { extern struct flickytypes_s FLICKYTYPES[]; extern actionpointer_t actionpointers[]; // Array mapping action names to action functions. -extern const char *const STATE_LIST[]; extern struct int_const_s const STATE_ALIASES[]; -extern const char *const MOBJTYPE_LIST[]; extern struct int_const_s const MOBJ_ALIASES[]; extern const char *const MOBJFLAG_LIST[]; extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2 diff --git a/src/dehacked.c b/src/dehacked.c index 9f081ffc3..daa45d795 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -176,6 +176,18 @@ static void ignorelines(MYFILE *f) Z_Free(s); } +static const char *hardcodemobjs = +#define _(name, ...) #name "\0" +#include "info/mobjs.h" +#undef _ +; + +static const char *hardcodestates = +#define _(name, ...) #name "\0" +#include "info/states.h" +#undef _ +; + static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -185,7 +197,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) INT32 i; if (!deh_loaded) + { initfreeslots(); + const char *name; + + name = hardcodemobjs; + for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1) + mobjinfo[i].nameofs = strbuf_append(&mobjnames, name); + + name = hardcodestates; + for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) + states[i].nameofs = strbuf_append(&statenames, name); + } deh_num_warning = 0; diff --git a/src/info.h b/src/info.h index 1b3078827..dd7dce5bd 100644 --- a/src/info.h +++ b/src/info.h @@ -79,6 +79,8 @@ typedef enum state struct state_t { + UINT32 nameofs; + spritenum_t sprite; UINT32 frame; // we use the upper 16 bits for translucency and other shade effects INT32 tics; @@ -107,6 +109,8 @@ typedef enum mobj_type struct mobjinfo_t { + UINT32 nameofs; + INT32 doomednum; statenum_t spawnstate; INT32 spawnhealth; diff --git a/src/lua_infolib.c b/src/lua_infolib.c index a330bb900..eb52c0787 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -752,8 +752,13 @@ static int lib_setState(lua_State *L) return luaL_error(L, "Do not alter states in CMD building code!"); // clear the state to start with, in case of missing table elements - memset(state,0,sizeof(state_t)); + state->sprite = SPR_NULL; + state->frame = 0; state->tics = -1; + state->action.acp1 = NULL; + state->var1 = 0; + state->var2 = 0; + state->nextstate = S_NULL; lua_pushnil(L); while (lua_next(L, 1)) { @@ -975,16 +980,9 @@ static int state_get(lua_State *L) else if (fastcmp(field,"string")) { statenum_t id = st-states; - if (id < S_FIRSTFREESLOT) + if (id < NUMSTATES) { - lua_pushstring(L, STATE_LIST[id]+2); - return 1; - } - - id -= S_FIRSTFREESLOT; - if (id < NUMSTATEFREESLOTS && FREE_STATES[id]) - { - lua_pushstring(L, FREE_STATES[id]); + lua_pushstring(L, strbuf_get(statenames, states[id].nameofs)); return 1; } @@ -1114,9 +1112,30 @@ static int lib_setMobjInfo(lua_State *L) return luaL_error(L, "Do not alter mobjinfo in CMD building code!"); // clear the mobjinfo to start with, in case of missing table elements - memset(info,0,sizeof(mobjinfo_t)); info->doomednum = -1; // default to no editor value + info->spawnstate = S_NULL; info->spawnhealth = 1; // avoid 'dead' noclip behaviors + info->seestate = S_NULL; + info->seesound = sfx_None; + info->reactiontime = 0; + info->attacksound = sfx_None; + info->painstate = S_NULL; + info->painchance = 0; + info->painsound = sfx_None; + info->meleestate = S_NULL; + info->missilestate = S_NULL; + info->deathstate = S_NULL; + info->xdeathstate = S_NULL; + info->deathsound = sfx_None; + info->speed = 0; + info->radius = 0; + info->height = 0; + info->dispoffset = 0; + info->mass = 0; + info->damage = 0; + info->activesound = sfx_None; + info->flags = 0U; + info->raisestate = S_NULL; lua_pushnil(L); while (lua_next(L, 1)) { @@ -1257,16 +1276,9 @@ static int mobjinfo_get(lua_State *L) lua_pushinteger(L, info->raisestate); else if (fastcmp(field,"string")) { mobjtype_t id = info-mobjinfo; - if (id < MT_FIRSTFREESLOT) + if (id < NUMMOBJTYPES) { - lua_pushstring(L, MOBJTYPE_LIST[id]+3); - return 1; - } - - id -= MT_FIRSTFREESLOT; - if (id < NUMMOBJFREESLOTS && FREE_MOBJS[id]) - { - lua_pushstring(L, FREE_MOBJS[id]); + lua_pushstring(L, strbuf_get(mobjnames, mobjinfo[id].nameofs)); return 1; } diff --git a/src/p_tick.c b/src/p_tick.c index a845e5da7..5f92e8a79 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -263,13 +263,13 @@ static const char *MobjTypeName(const mobj_t *mobj) if (p1 == (actionf_p1)P_MobjThinker) { - return MOBJTYPE_LIST[mobj->type]; + return strbuf_get(mobjnames, mobjinfo[mobj->type].nameofs); } else if (p1 == (actionf_p1)P_RemoveThinkerDelayed) { if (mobj->thinker.debug_mobjtype != MT_NULL) { - return MOBJTYPE_LIST[mobj->thinker.debug_mobjtype]; + return strbuf_get(mobjnames, mobjinfo[mobj->thinker.debug_mobjtype].nameofs); } } @@ -331,7 +331,7 @@ void P_RemoveThinkerDelayed(thinker_t *thinker) else if ((thinker->debug_time + delay) <= leveltime) { CONS_Printf( - "PARANOIA/P_RemoveThinkerDelayed: %p %s references=%d\n", + "PARANOIA/P_RemoveThinkerDelayed: %p MT_%s references=%d\n", (void*)thinker, MobjTypeName((mobj_t*)thinker), thinker->references @@ -423,7 +423,7 @@ mobj_t *P_SetTarget2(mobj_t **mop, mobj_t *targ if ((*mop)->thinker.references < 0) { CONS_Printf( - "PARANOIA/P_SetTarget: %p %s %s references=%d, references go negative! (%s:%d)\n", + "PARANOIA/P_SetTarget: %p MT_%s %s references=%d, references go negative! (%s:%d)\n", (void*)*mop, MobjTypeName(*mop), MobjThinkerName(*mop), From 1b095d220eaef002fceeb5816fc8a703eb110457 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 14 May 2025 16:06:11 +0200 Subject: [PATCH 03/15] Why stop there? Go for skincolors too :^) --- src/d_main.cpp | 3 --- src/deh_lua.c | 24 +++++++++--------------- src/deh_soc.c | 18 +++++++----------- src/deh_tables.c | 20 +------------------- src/deh_tables.h | 8 ++------ src/dehacked.c | 10 ++++++++++ src/dehacked.h | 2 -- src/doomdef.h | 1 + src/p_setup.c | 5 +---- 9 files changed, 31 insertions(+), 60 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 0a9b105d5..cd4ae1cda 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1277,9 +1277,6 @@ void D_SRB2Main(void) // MAINCFG is now taken care of where "OBJCTCFG" is handled G_LoadGameSettings(); - // Test Dehacked lists - DEH_TableCheck(); - // Netgame URL special case: change working dir to EXE folder. ChangeDirForUrlHandler(); diff --git a/src/deh_lua.c b/src/deh_lua.c index a1983727b..132bd72c7 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -111,18 +111,17 @@ static inline int lib_freeslot(lua_State *L) else if (fastcmp(type, "SKINCOLOR")) { skincolornum_t i; - for (i = 0; i < NUMCOLORFREESLOTS; i++) - if (!FREE_SKINCOLORS[i]) { + for (i = SKINCOLOR_FIRSTFREESLOT; i < MAXSKINCOLORS; i++) + if (!skincolors[i].nameofs) { CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); - FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_SKINCOLORS[i],word); + skincolors[i].nameofs = strbuf_append(&skincolornames, word); M_AddMenuColor(numskincolors++); K_ReloadHUDColorCvar(); - lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT + i); + lua_pushinteger(L, i); r++; break; } - if (i == NUMCOLORFREESLOTS) + if (i == MAXSKINCOLORS) CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); } else if (fastcmp(type, "SPR2")) @@ -588,19 +587,14 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("SKINCOLOR_",word,10)) { p = word+10; - for (i = 0; i < NUMCOLORFREESLOTS; i++) { - if (!FREE_SKINCOLORS[i]) + for (i = 0; i < MAXSKINCOLORS; i++) { + if (!skincolors[i].nameofs) break; - if (fastcmp(p, FREE_SKINCOLORS[i])) { - CacheAndPushConstant(L, word, SKINCOLOR_FIRSTFREESLOT+i); - return 1; - } - } - for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++) - if (fastcmp(p, COLOR_ENUMS[i])) { + if (fastcmp(p, strbuf_get(skincolornames, skincolors[i].nameofs))) { CacheAndPushConstant(L, word, i); return 1; } + } return luaL_error(L, "skincolor '%s' could not be found.\n", word); } else if (fastncmp("MN_",word,3)) { diff --git a/src/deh_soc.c b/src/deh_soc.c index 909760398..564127ef4 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -464,11 +464,10 @@ void readfreeslots(MYFILE *f) } else if (fastcmp(type, "SKINCOLOR")) { - for (i = 0; i < NUMCOLORFREESLOTS; i++) - if (!FREE_SKINCOLORS[i]) { + for (i = SKINCOLOR_FIRSTFREESLOT; i < MAXSKINCOLORS; i++) + if (!skincolors[i].nameofs) { CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); - FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_SKINCOLORS[i],word); + skincolors[i].nameofs = strbuf_append(&skincolornames, word); M_AddMenuColor(numskincolors++); K_ReloadHUDColorCvar(); break; @@ -4298,15 +4297,12 @@ skincolornum_t get_skincolor(const char *word) return atoi(word); if (fastncmp("SKINCOLOR_",word,10)) word += 10; // take off the SKINCOLOR_ - for (i = 0; i < NUMCOLORFREESLOTS; i++) { - if (!FREE_SKINCOLORS[i]) + for (i = 0; i < MAXSKINCOLORS; i++) { + if (!skincolors[i].nameofs) break; - if (fastcmp(word, FREE_SKINCOLORS[i])) - return SKINCOLOR_FIRSTFREESLOT+i; - } - for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++) - if (fastcmp(word, COLOR_ENUMS[i])) + if (fastcmp(word, strbuf_get(skincolornames, skincolors[i].nameofs))) return i; + } deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'",word); return -1; } diff --git a/src/deh_tables.c b/src/deh_tables.c index 57229a2ee..92f522e21 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -34,7 +34,7 @@ strbuf_t *statenames; strbuf_t *mobjnames; -char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; +strbuf_t *skincolornames; char *FREE_MENUS[NUMMENUFREESLOTS]; UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. @@ -427,12 +427,6 @@ const char *const TO_LIST[] = { NULL }; -const char *COLOR_ENUMS[] = { -#define _(name, ...) #name, -#include "info/skincolors.h" -#undef _ -}; - const char *const POWERS_LIST[] = { "INVULNERABILITY", "SNEAKERS", @@ -1511,15 +1505,3 @@ struct int_const_s const INT_CONST[] = { {NULL,0} }; - -// For this to work compile-time without being in this file, -// this function would need to check sizes at runtime, without sizeof -void DEH_TableCheck(void) -{ -#if defined(_DEBUG) || defined(PARANOIA) - const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*); - - if (dehcolors != SKINCOLOR_FIRSTFREESLOT) - I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors)); -#endif -} diff --git a/src/deh_tables.h b/src/deh_tables.h index 5071e7a2b..2169d6a40 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -28,14 +28,14 @@ extern "C" { // The crazy word-reading stuff uses these. extern strbuf_t *statenames; extern strbuf_t *mobjnames; -extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; +extern strbuf_t *skincolornames; extern char *FREE_MENUS[NUMMENUFREESLOTS]; extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. #define initfreeslots() {\ statenames = strbuf_alloc();\ mobjnames = strbuf_alloc();\ - memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\ + skincolornames = strbuf_alloc();\ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ } @@ -87,7 +87,6 @@ extern const char *const MSF_LIST[]; // Sector flags extern const char *const SSF_LIST[]; // Sector special flags extern const char *const SD_LIST[]; // Sector damagetype extern const char *const TO_LIST[]; // Sector triggerer -extern const char *COLOR_ENUMS[]; extern const char *const POWERS_LIST[]; extern const char *const KARTSTUFF_LIST[]; extern const char *const KARTHUD_LIST[]; @@ -98,9 +97,6 @@ extern struct menu_drawer_s const MENU_DRAWERS[]; extern struct int_const_s const INT_CONST[]; -// Moved to this file because it can't work compile-time otherwise -void DEH_TableCheck(void); - #ifdef __cplusplus } // extern "C" #endif diff --git a/src/dehacked.c b/src/dehacked.c index daa45d795..daf240f36 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -188,6 +188,12 @@ static const char *hardcodestates = #undef _ ; +static const char *hardcodeskincolors = +#define _(name, ...) #name "\0" +#include "info/skincolors.h" +#undef _ +; + static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -208,6 +214,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) name = hardcodestates; for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) states[i].nameofs = strbuf_append(&statenames, name); + + name = hardcodeskincolors; + for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) + skincolors[i].nameofs = strbuf_append(&skincolornames, name); } deh_num_warning = 0; diff --git a/src/dehacked.h b/src/dehacked.h index f32cfd579..fca5c4b15 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -38,8 +38,6 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile); extern int freeslotusage[2][2]; void DEH_UpdateMaxFreeslots(void); -void DEH_Check(void); - fixed_t get_number(const char *word); FUNCPRINTF void deh_warning(const char *first, ...); void deh_strlcpy(char *dst, const char *src, size_t size, const char *warntext); diff --git a/src/doomdef.h b/src/doomdef.h index 4a5f83f0b..5b85038f8 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -222,6 +222,7 @@ extern char logfilename[1024]; struct skincolor_t { + UINT32 nameofs; // Offset for internal name char name[MAXCOLORNAME+1]; // Skincolor name UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp UINT16 invcolor; // Signpost color diff --git a/src/p_setup.c b/src/p_setup.c index 127891d12..b1ccec8a5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1185,10 +1185,7 @@ static void P_WriteSkincolor(INT32 constant, char **target) || constant >= (INT32)numskincolors) return; - if (constant >= SKINCOLOR_FIRSTFREESLOT) - color_name = FREE_SKINCOLORS[constant - SKINCOLOR_FIRSTFREESLOT]; - else - color_name = COLOR_ENUMS[constant]; + color_name = strbuf_get(skincolornames, skincolors[constant].nameofs); P_WriteDuplicateText( va("SKINCOLOR_%s", color_name), From e3f8019b84a16667706fafa1233a434afda7c17b Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 14 May 2025 16:43:20 +0200 Subject: [PATCH 04/15] And menus --- src/deh_lua.c | 23 +++++++++-------------- src/deh_soc.c | 38 +++++++++----------------------------- src/deh_tables.c | 8 +------- src/deh_tables.h | 4 ++-- src/dehacked.c | 10 ++++++++++ src/info.c | 4 ++++ src/m_menu.c | 48 +++++++++++++++++++++++------------------------- src/m_menu.h | 4 +++- 8 files changed, 61 insertions(+), 78 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 132bd72c7..484e5519d 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -190,15 +190,15 @@ static inline int lib_freeslot(lua_State *L) else if (fastcmp(type, "MN")) { menutype_t i; - for (i = 0; i < NUMMENUFREESLOTS; i++) - if (!FREE_MENUS[i]) { + for (i = MN_FIRSTFREESLOT; i < NUMMENUTYPES; i++) { + if (!menudefs[i].nameofs) { CONS_Printf("Menu MN_%s allocated.\n",word); - FREE_MENUS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_MENUS[i],word); - lua_pushinteger(L, MN_FIRSTFREESLOT + i); + menudefs[i].nameofs = strbuf_append(&menunames, word); + lua_pushinteger(L, i); r++; break; } + } if (i == NUMMENUFREESLOTS) CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n"); } @@ -599,19 +599,14 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("MN_",word,3)) { p = word+3; - for (i = 0; i < NUMMENUFREESLOTS; i++) { - if (!FREE_MENUS[i]) + for (i = 0; i < NUMMENUTYPES; i++) { + if (!menudefs[i].nameofs) break; - if (fastcmp(p, FREE_MENUS[i])) { - CacheAndPushConstant(L, word, MN_FIRSTFREESLOT+i); - return 1; - } - } - for (i = 0; i < MN_FIRSTFREESLOT; i++) - if (fastcmp(p, MENUTYPES_LIST[i])) { + if (fastcmp(p, strbuf_get(menunames, menudefs[i].nameofs)) ){ CacheAndPushConstant(L, word, i); return 1; } + } if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word); return 0; } diff --git a/src/deh_soc.c b/src/deh_soc.c index 564127ef4..1fe95a74b 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -531,11 +531,10 @@ void readfreeslots(MYFILE *f) } else if (fastcmp(type, "MN")) { - for (i = 0; i < NUMMENUFREESLOTS; i++) - if (!FREE_MENUS[i]) { + for (i = MN_FIRSTFREESLOT; i < NUMMENUTYPES; i++) + if (!menudefs[i].nameofs) { CONS_Printf("Menu MN_%s allocated.\n",word); - FREE_MENUS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); - strcpy(FREE_MENUS[i],word); + menudefs[i].nameofs = strbuf_append(&menunames, word); break; } } @@ -2151,21 +2150,6 @@ void readtextprompt(MYFILE *f, INT32 num) Z_Free(s); } -static menu_t *allocmenu(INT32 num) -{ - if (num < 0 || num >= NUMMENUTYPES) - I_Error("Tried to allocate out-of-range menu number"); - - menu_t *menu = menudefs[num]; - if (menu == NULL) - { - menudefs[num] = menu = Z_Calloc(sizeof(menu_t), PU_STATIC, NULL); - menu->drawroutine = M_DrawGenericMenu; - } - - return menu; -} - // super secret menu cvars... :shushing_face: static struct { const char *name; consvar_t *var; } HIDDENVARS[] = { { "CHOOSESKIN", &cv_chooseskin }, @@ -2315,7 +2299,6 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) } actionset = true; status |= IT_SUBMENU; - allocmenu(mn); menuitem->itemaction.submenu = mn; } else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER") || fastcmp(word, "ARROWS")) @@ -2369,7 +2352,7 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) #undef WARN #undef WARN0 -#define WARN(str, ...) deh_warning("Menu %s: " str, num < MN_FIRSTFREESLOT ? MENUTYPES_LIST[num] : FREE_MENUS[num - MN_FIRSTFREESLOT], __VA_ARGS__) +#define WARN(str, ...) deh_warning("Menu %s: " str, strbuf_get(menunames, menudefs[num].nameofs), __VA_ARGS__) void readmenu(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -2378,7 +2361,7 @@ void readmenu(MYFILE *f, INT32 num) char *tmp; INT32 value; - menu_t *menudef = allocmenu(num); + menu_t *menudef = &menudefs[num]; do { @@ -4358,15 +4341,12 @@ menutype_t get_menutype(const char *word) return atoi(word); if (fastncmp("MN_",word,3)) word += 3; // take off the MN_ - for (i = 0; i < NUMMENUFREESLOTS; i++) { - if (!FREE_MENUS[i]) + for (i = 0; i < NUMMENUTYPES; i++) { + if (!menudefs[i].nameofs) break; - if (fastcmp(word, FREE_MENUS[i])) - return MN_FIRSTFREESLOT+i; - } - for (i = 0; i < MN_FIRSTFREESLOT; i++) - if (fastcmp(word, MENUTYPES_LIST[i])) + if (fastcmp(word, strbuf_get(menunames, menudefs[i].nameofs))) return i; + } deh_warning("Couldn't find menutype named 'MN_%s'",word); return MN_NONE; } diff --git a/src/deh_tables.c b/src/deh_tables.c index 92f522e21..60496016e 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -35,7 +35,7 @@ strbuf_t *statenames; strbuf_t *mobjnames; strbuf_t *skincolornames; -char *FREE_MENUS[NUMMENUFREESLOTS]; +strbuf_t *menunames; UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. struct flickytypes_s FLICKYTYPES[] = { @@ -601,12 +601,6 @@ const char *const HUDITEMS_LIST[] = { "POWERUPS" }; -const char *const MENUTYPES_LIST[] = { -#define _(name, ...) #name, -#include "info/menus.h" -#undef _ -}; - struct menu_routine_s const MENU_ROUTINES[] = { { "SINGLEPLAYERMENU", &M_SinglePlayerMenu }, { "OPTIONS", &M_Options }, diff --git a/src/deh_tables.h b/src/deh_tables.h index 2169d6a40..c653afb59 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -29,13 +29,14 @@ extern "C" { extern strbuf_t *statenames; extern strbuf_t *mobjnames; extern strbuf_t *skincolornames; -extern char *FREE_MENUS[NUMMENUFREESLOTS]; +extern strbuf_t *menunames; extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. #define initfreeslots() {\ statenames = strbuf_alloc();\ mobjnames = strbuf_alloc();\ skincolornames = strbuf_alloc();\ + menunames = strbuf_alloc();\ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ } @@ -91,7 +92,6 @@ extern const char *const POWERS_LIST[]; extern const char *const KARTSTUFF_LIST[]; extern const char *const KARTHUD_LIST[]; extern const char *const HUDITEMS_LIST[]; -extern const char *const MENUTYPES_LIST[]; extern struct menu_routine_s const MENU_ROUTINES[]; extern struct menu_drawer_s const MENU_DRAWERS[]; diff --git a/src/dehacked.c b/src/dehacked.c index daf240f36..4ea7fef1d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -194,6 +194,12 @@ static const char *hardcodeskincolors = #undef _ ; +static const char *hardcodemenus = +#define _(name, ...) #name "\0" +#include "info/menus.h" +#undef _ +; + static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -218,6 +224,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) name = hardcodeskincolors; for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) skincolors[i].nameofs = strbuf_append(&skincolornames, name); + + name = hardcodemenus; + for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1) + menudefs[i].nameofs = strbuf_append(&menunames, name); } deh_num_warning = 0; diff --git a/src/info.c b/src/info.c index 0a1e1bd33..f00c2ad7a 100644 --- a/src/info.c +++ b/src/info.c @@ -23,6 +23,7 @@ #include "d_player.h" #include "v_video.h" // V_*MAP constants #include "lzf.h" +#include "m_menu.h" // Hey, moron! If you wanna change this table, you can just change the sprite enum in info/sprites.h, // so you don't have to copy and paste the list of sprite names back in here :^) @@ -115,12 +116,15 @@ void P_PatchInfoTables(void) memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS); memset(&mobjinfo[MT_FIRSTFREESLOT], 0, sizeof (mobjinfo_t) * NUMMOBJFREESLOTS); memset(&skincolors[SKINCOLOR_FIRSTFREESLOT], 0, sizeof (skincolor_t) * NUMCOLORFREESLOTS); + memset(&menudefs[MN_FIRSTFREESLOT], 0, sizeof (menu_t) * NUMMENUFREESLOTS); for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) { skincolors[i].accessible = false; skincolors[i].name[0] = '\0'; } for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++) mobjinfo[i].doomednum = -1; + for (i = 0; i < NUMMENUTYPES; i++) + menudefs[i].drawroutine = M_DrawGenericMenu; } #ifdef ALLOW_RESETDATA diff --git a/src/m_menu.c b/src/m_menu.c index 4d1c369db..01c3e2c2c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -166,7 +166,7 @@ static UINT32 serverlistpage; INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? -menu_t *menudefs[NUMMENUTYPES] = {NULL}; // pointers to all menudefs +menu_t menudefs[NUMMENUTYPES]; // array of all menudefs menutype_t menustack[NUMMENULEVELS]; // stack of active menus, [0] == current menu static menu_t *currentMenu; // current menudef static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 @@ -237,8 +237,7 @@ static void Dummystaff_OnChange(void); menuitem_t *M_CheckMenuItem(menutype_t type, const char *name) { INT16 i; - menu_t *menu = menudefs[type]; - I_Assert(menu); + menu_t *menu = &menudefs[type]; for (i = 0; i < menu->numitems; i++) if (!strncmp(menu->menuitems[i].itemname, name, ITEMNAMELEN)) @@ -256,7 +255,7 @@ menuitem_t *M_GetMenuItem(menutype_t type, const char *name) static INT16 M_GetMenuIndex(menutype_t type, const char *name) { - return M_GetMenuItem(type, name) - menudefs[type]->menuitems; + return M_GetMenuItem(type, name) - menudefs[type].menuitems; } // an array of macros for getting/setting menuitem properties @@ -1714,8 +1713,7 @@ void M_ClearMenus(boolean callexitmenufunc) static void M_SetupNextMenu(menutype_t menunum, boolean callexit) { INT16 i; - menu_t *menudef = menudefs[menunum]; - I_Assert(menudef); + menu_t *menudef = &menudefs[menunum]; // If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH if (callexit && currentMenu && currentMenu != menudef && currentMenu->quitroutine) @@ -4427,7 +4425,7 @@ void M_Options(INT32 choice) M_SetItemStatus(MN_OP_GAME, "ENCORE", M_SecretUnlocked(SECRET_ENCORE) ? IT_CVAR|IT_STRING : IT_SECRET); - M_SetItemStatus(MN_OP_MAIN, "CUSTOM", !menudefs[MN_OP_CUSTOM]->numitems ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU); + M_SetItemStatus(MN_OP_MAIN, "CUSTOM", !menudefs[MN_OP_CUSTOM].numitems ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU); M_EnterMenu(MN_OP_MAIN, true); } @@ -6262,7 +6260,7 @@ void M_DrawConnectMenu(void) UINT32 serversperpage = M_ServersPerPage(); // server sperpage? INT32 numPages = (serverlistcount+(serversperpage-1))/serversperpage; int waiting; - menu_t *conmenu = menudefs[MN_MP_CONNECT]; // meh, whatever + menu_t *conmenu = &menudefs[MN_MP_CONNECT]; // meh, whatever for (i = firstserverline; i < firstserverline+serversperpage; i++) conmenu->menuitems[i].status = IT_STRING | IT_SPACE; @@ -7026,8 +7024,8 @@ void M_DrawSetupMultiPlayerMenu(void) char *fname; INT16 i; - mx = menudefs[MN_MP_PLAYERSETUP]->x; - my = menudefs[MN_MP_PLAYERSETUP]->y; + mx = menudefs[MN_MP_PLAYERSETUP].x; + my = menudefs[MN_MP_PLAYERSETUP].y; statx = (BASEVIDWIDTH - mx - 118); staty = (my+62); @@ -7941,7 +7939,7 @@ void M_DrawJoystick(void) for (i = 0; i <= MAXGAMEPADS; i++) { - M_DrawTextBox(menudefs[MN_OP_JOYSTICKSET]->x-8, menudefs[MN_OP_JOYSTICKSET]->y+LINEHEIGHT*i-12, 28, 1); + M_DrawTextBox(menudefs[MN_OP_JOYSTICKSET].x-8, menudefs[MN_OP_JOYSTICKSET].y+LINEHEIGHT*i-12, 28, 1); #ifdef JOYSTICK_HOTPLUG if (atoi(cv_usejoystick[setupcontrolplayer-1].string) > I_NumJoys()) @@ -7950,7 +7948,7 @@ void M_DrawJoystick(void) #endif compareval = cv_usejoystick[setupcontrolplayer-1].value; - V_DrawString(menudefs[MN_OP_JOYSTICKSET]->x, menudefs[MN_OP_JOYSTICKSET]->y+LINEHEIGHT*i-4, (i == compareval) ? V_GREENMAP : 0, joystickInfo[i]); + V_DrawString(menudefs[MN_OP_JOYSTICKSET].x, menudefs[MN_OP_JOYSTICKSET].y+LINEHEIGHT*i-4, (i == compareval) ? V_GREENMAP : 0, joystickInfo[i]); } } @@ -8595,11 +8593,11 @@ void M_DrawVideoMode(void) // draw title M_DrawMenuTitle(); - V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y, highlightflags, "Choose mode, reselect to change default"); row = 41; - col = menudefs[MN_OP_VIDEOMODE]->y + 14; + col = menudefs[MN_OP_VIDEOMODE].y + 14; for (i = 0; i < vidm_nummodes; i++) { if (i == vidm_selected) @@ -8612,7 +8610,7 @@ void M_DrawVideoMode(void) if ((i % vidm_column_size) == (vidm_column_size-1)) { row += 7*13; - col = menudefs[MN_OP_VIDEOMODE]->y + 14; + col = menudefs[MN_OP_VIDEOMODE].y + 14; } } @@ -8620,40 +8618,40 @@ void M_DrawVideoMode(void) { INT32 testtime = (vidm_testingmode/TICRATE) + 1; - M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 116, + M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 116, va("Previewing mode %c%dx%d", (SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80, vid.width, vid.height)); - M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 138, + M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 138, "Press ENTER again to keep this mode"); - M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 150, + M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 150, va("Wait %d second%s", testtime, (testtime > 1) ? "s" : "")); - M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 158, + M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 158, "or press ESC to return"); } else { - M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 116, + M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 116, va("Current mode is %c%dx%d", (SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80, vid.width, vid.height)); - M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 124, + M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 124, va("Default mode is %c%dx%d", (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80, cv_scr_width.value, cv_scr_height.value)); - V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 138, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y + 138, recommendedflags, "Marked modes are recommended."); - V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 146, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y + 146, highlightflags, "Other modes may have visual errors."); - V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 158, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y + 158, highlightflags, "Larger modes may have performance issues."); } // Draw the cursor for the VidMode menu i = 41 - 10 + ((vidm_selected / vidm_column_size)*7*13); - j = menudefs[MN_OP_VIDEOMODE]->y + 14 + ((vidm_selected % vidm_column_size)*8); + j = menudefs[MN_OP_VIDEOMODE].y + 14 + ((vidm_selected % vidm_column_size)*8); V_DrawScaledPatch(i - 8, j, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); diff --git a/src/m_menu.h b/src/m_menu.h index de4512507..8b11fac75 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -50,7 +50,6 @@ typedef enum } menutype_t; #define NUMMENUFREESLOTS (NUMMENUTYPES - MN_FIRSTFREESLOT) -extern menu_t *menudefs[NUMMENUTYPES]; extern menutype_t menustack[NUMMENULEVELS]; typedef struct @@ -249,6 +248,7 @@ struct menuitem_t struct menu_t { + UINT32 nameofs; const char *headerpic; INT16 numitems; // # of menu items menuitem_t *menuitems; // menu items @@ -258,6 +258,8 @@ struct menu_t void (*quitroutine)(INT32 choice); // called before quit a menu }; +extern menu_t menudefs[NUMMENUTYPES]; + void M_EnterMenu(menutype_t menu, boolean callexit); void M_ExitMenu(void); void M_ClearMenus(boolean callexitmenufunc); From 1fa9a7cb8e5ac6cc2424943c44e15c96406682e8 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 14 May 2025 17:28:41 +0200 Subject: [PATCH 05/15] Refactor info table initialization We SOCced this stuff ages ago, time to exploit it Also fixes resetdata kek --- src/d_main.cpp | 5 +- src/deh_tables.h | 8 -- src/dehacked.c | 49 ----------- src/dehacked.h | 2 - src/doomdef.h | 7 -- src/info.c | 220 +++++++++++++++++++++++++---------------------- src/info.h | 4 - src/w_wad.c | 39 +++++++++ src/w_wad.h | 1 + 9 files changed, 156 insertions(+), 179 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index cd4ae1cda..5758a366b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1427,7 +1427,7 @@ void D_SRB2Main(void) netgame = server = true; // adapt tables to SRB2's needs, including extra slots for dehacked file support - P_PatchInfoTables(); + P_ResetData(15); // initiate menu metadata before SOCcing them M_InitMenuPresTables(); @@ -1443,9 +1443,6 @@ void D_SRB2Main(void) I_InitializeTime(); CON_SetLoadingProgress(LOADED_ISTARTUPTIMER); - // Make backups of some SOCcable tables. - P_BackupTables(); - // Setup default unlockable conditions M_SetupDefaultConditionSets(); diff --git a/src/deh_tables.h b/src/deh_tables.h index c653afb59..7d564694d 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -32,14 +32,6 @@ extern strbuf_t *skincolornames; extern strbuf_t *menunames; extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. -#define initfreeslots() {\ - statenames = strbuf_alloc();\ - mobjnames = strbuf_alloc();\ - skincolornames = strbuf_alloc();\ - menunames = strbuf_alloc();\ - memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ -} - struct flickytypes_s { const char *name; const mobjtype_t type; diff --git a/src/dehacked.c b/src/dehacked.c index 4ea7fef1d..102b8de30 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -15,8 +15,6 @@ #include "deh_soc.h" #include "deh_tables.h" -boolean deh_loaded = false; - boolean gamedataadded = false; boolean titlechanged = false; boolean introchanged = false; @@ -176,30 +174,6 @@ static void ignorelines(MYFILE *f) Z_Free(s); } -static const char *hardcodemobjs = -#define _(name, ...) #name "\0" -#include "info/mobjs.h" -#undef _ -; - -static const char *hardcodestates = -#define _(name, ...) #name "\0" -#include "info/states.h" -#undef _ -; - -static const char *hardcodeskincolors = -#define _(name, ...) #name "\0" -#include "info/skincolors.h" -#undef _ -; - -static const char *hardcodemenus = -#define _(name, ...) #name "\0" -#include "info/menus.h" -#undef _ -; - static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -208,28 +182,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) char *word2; INT32 i; - if (!deh_loaded) - { - initfreeslots(); - const char *name; - - name = hardcodemobjs; - for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1) - mobjinfo[i].nameofs = strbuf_append(&mobjnames, name); - - name = hardcodestates; - for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) - states[i].nameofs = strbuf_append(&statenames, name); - - name = hardcodeskincolors; - for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) - skincolors[i].nameofs = strbuf_append(&skincolornames, name); - - name = hardcodemenus; - for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1) - menudefs[i].nameofs = strbuf_append(&menunames, name); - } - deh_num_warning = 0; gamedataadded = titlechanged = introchanged = false; @@ -728,7 +680,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } } - deh_loaded = true; Z_Free(s); } diff --git a/src/dehacked.h b/src/dehacked.h index fca5c4b15..9b16178e7 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -42,8 +42,6 @@ fixed_t get_number(const char *word); FUNCPRINTF void deh_warning(const char *first, ...); void deh_strlcpy(char *dst, const char *src, size_t size, const char *warntext); -extern boolean deh_loaded; - extern boolean gamedataadded; extern boolean titlechanged; extern boolean introchanged; diff --git a/src/doomdef.h b/src/doomdef.h index 5b85038f8..497b5cfa3 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -513,13 +513,6 @@ extern int compuncommitted; /// Shuffle's incomplete OpenGL sorting code. #define SHUFFLE // This has nothing to do with sorting, why was it disabled? -/// Allow the use of the SOC RESETINFO command. -/// \note Builds that are tight on memory should disable this. -/// This stops the game from storing backups of the states, sprites, and mobjinfo tables. -/// Though this info is compressed under normal circumstances, it's still a lot of extra -/// memory that never gets touched. -#define ALLOW_RESETDATA - /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) //#define REDSANALOG diff --git a/src/info.c b/src/info.c index f00c2ad7a..4b9e594a4 100644 --- a/src/info.c +++ b/src/info.c @@ -14,16 +14,12 @@ // Data. #include "info.h" #include "doomdef.h" -#include "doomstat.h" -#include "sounds.h" -#include "p_mobj.h" -#include "p_local.h" // DMG_ constants -#include "m_misc.h" #include "z_zone.h" -#include "d_player.h" -#include "v_video.h" // V_*MAP constants -#include "lzf.h" +#include "w_wad.h" +#include "dehacked.h" +#include "d_main.h" #include "m_menu.h" +#include "deh_tables.h" // Hey, moron! If you wanna change this table, you can just change the sprite enum in info/sprites.h, // so you don't have to copy and paste the list of sprite names back in here :^) @@ -90,126 +86,140 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {0}; skincolor_t skincolors[MAXSKINCOLORS] = {0}; -/** Patches the mobjinfo, state, and skincolor tables. - * Free slots are emptied out and set to initial values. - */ -void P_PatchInfoTables(void) -{ - INT32 i; - char *tempname; - #if NUMSPRITEFREESLOTS > 9999 //tempname numbering actually starts at SPR_FIRSTFREESLOT, so the limit is actually 9999 + SPR_FIRSTFREESLOT-1, but the preprocessor doesn't understand enums, so its left at 9999 for safety #error "Update P_PatchInfoTables, you big dumb head" #endif - // empty out free slots - for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) - { - tempname = sprnames[i]; - tempname[0] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)/1000)); - tempname[1] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/100)%10)); - tempname[2] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/10)%10)); - tempname[3] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)%10)); - tempname[4] = '\0'; - } - sprnames[i][0] = '\0'; // i == NUMSPRITES - memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS); - memset(&mobjinfo[MT_FIRSTFREESLOT], 0, sizeof (mobjinfo_t) * NUMMOBJFREESLOTS); - memset(&skincolors[SKINCOLOR_FIRSTFREESLOT], 0, sizeof (skincolor_t) * NUMCOLORFREESLOTS); - memset(&menudefs[MN_FIRSTFREESLOT], 0, sizeof (menu_t) * NUMMENUFREESLOTS); - for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) { - skincolors[i].accessible = false; - skincolors[i].name[0] = '\0'; - } - for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++) - mobjinfo[i].doomednum = -1; - for (i = 0; i < NUMMENUTYPES; i++) - menudefs[i].drawroutine = M_DrawGenericMenu; -} +static const char *hardcodemobjs = +#define _(name, ...) #name "\0" +#include "info/mobjs.h" +#undef _ +; -#ifdef ALLOW_RESETDATA -static char *sprnamesbackup; -static state_t *statesbackup; -static mobjinfo_t *mobjinfobackup; -static skincolor_t *skincolorsbackup; -static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize, skincolorsbackupsize; -#endif +static const char *hardcodestates = +#define _(name, ...) #name "\0" +#include "info/states.h" +#undef _ +; -void P_BackupTables(void) -{ -#ifdef ALLOW_RESETDATA - // Allocate buffers in size equal to that of the uncompressed data to begin with - sprnamesbackup = Z_Malloc(sizeof(sprnames), PU_STATIC, NULL); - statesbackup = Z_Malloc(sizeof(states), PU_STATIC, NULL); - mobjinfobackup = Z_Malloc(sizeof(mobjinfo), PU_STATIC, NULL); - skincolorsbackup = Z_Malloc(sizeof(skincolors), PU_STATIC, NULL); +static const char *hardcodeskincolors = +#define _(name, ...) #name "\0" +#include "info/skincolors.h" +#undef _ +; - // Sprite names - sprnamesbackupsize = lzf_compress(sprnames, sizeof(sprnames), sprnamesbackup, sizeof(sprnames)); - if (sprnamesbackupsize > 0) - sprnamesbackup = Z_Realloc(sprnamesbackup, sprnamesbackupsize, PU_STATIC, NULL); - else - M_Memcpy(sprnamesbackup, sprnames, sizeof(sprnames)); - - // States - statesbackupsize = lzf_compress(states, sizeof(states), statesbackup, sizeof(states)); - if (statesbackupsize > 0) - statesbackup = Z_Realloc(statesbackup, statesbackupsize, PU_STATIC, NULL); - else - M_Memcpy(statesbackup, states, sizeof(states)); - - // Mobj info - mobjinfobackupsize = lzf_compress(mobjinfo, sizeof(mobjinfo), mobjinfobackup, sizeof(mobjinfo)); - if (mobjinfobackupsize > 0) - mobjinfobackup = Z_Realloc(mobjinfobackup, mobjinfobackupsize, PU_STATIC, NULL); - else - M_Memcpy(mobjinfobackup, mobjinfo, sizeof(mobjinfo)); - - //Skincolor info - skincolorsbackupsize = lzf_compress(skincolors, sizeof(skincolors), skincolorsbackup, sizeof(skincolors)); - if (skincolorsbackupsize > 0) - skincolorsbackup = Z_Realloc(skincolorsbackup, skincolorsbackupsize, PU_STATIC, NULL); - else - M_Memcpy(skincolorsbackup, skincolors, sizeof(skincolors)); -#endif -} +static const char *hardcodemenus = +#define _(name, ...) #name "\0" +#include "info/menus.h" +#undef _ +; void P_ResetData(INT32 flags) { -#ifndef ALLOW_RESETDATA - (void)flags; - CONS_Alert(CONS_NOTICE, M_GetText("P_ResetData(): not supported in this build.\n")); -#else + INT32 i; + UINT16 lumpnum; + boolean init = numwadfiles == 0; + const char *name; + + // sprnames if (flags & 1) { - if (sprnamesbackupsize > 0) - lzf_decompress(sprnamesbackup, sprnamesbackupsize, sprnames, sizeof(sprnames)); - else - M_Memcpy(sprnames, sprnamesbackup, sizeof(sprnamesbackup)); + memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1)); + + // vanilla sprnames are immutable + for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) + { + char *tempname = sprnames[i]; + tempname[0] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)/1000)); + tempname[1] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/100)%10)); + tempname[2] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/10)%10)); + tempname[3] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)%10)); + tempname[4] = '\0'; + } + sprnames[i][0] = '\0'; // i == NUMSPRITES } + // states if (flags & 2) { - if (statesbackupsize > 0) - lzf_decompress(statesbackup, statesbackupsize, states, sizeof(states)); - else - M_Memcpy(states, statesbackup, sizeof(statesbackup)); + if (!init) + memset(states, 0, sizeof(states)); + + if (statenames) + Z_Free(statenames); + statenames = strbuf_alloc(); + name = hardcodestates; + for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) + states[i].nameofs = strbuf_append(&statenames, name); + + if (!init) + { + lumpnum = W_CheckNumForLongNamePwadNoUpper("states", MAINWAD_MAIN, 0); + DEH_LoadDehackedLumpPwad(MAINWAD_MAIN, lumpnum, true); + } } + // mobjinfo if (flags & 4) { - if (mobjinfobackupsize > 0) - lzf_decompress(mobjinfobackup, mobjinfobackupsize, mobjinfo, sizeof(mobjinfo)); - else - M_Memcpy(mobjinfo, mobjinfobackup, sizeof(mobjinfobackup)); + if (!init) + memset(mobjinfo, 0, sizeof(mobjinfo)); + + if (mobjnames) + Z_Free(mobjnames); + mobjnames = strbuf_alloc(); + name = hardcodemobjs; + for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1) + mobjinfo[i].nameofs = strbuf_append(&mobjnames, name); + + for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++) + mobjinfo[i].doomednum = -1; + + if (!init) + { + lumpnum = W_CheckNumForLongNamePwadNoUpper("mobjs", MAINWAD_MAIN, 0); + DEH_LoadDehackedLumpPwad(MAINWAD_MAIN, lumpnum, true); + } } + // skincolors if (flags & 8) { - if (skincolorsbackupsize > 0) - lzf_decompress(skincolorsbackup, skincolorsbackupsize, skincolors, sizeof(skincolors)); - else - M_Memcpy(skincolors, skincolorsbackup, sizeof(skincolorsbackup)); + if (!init) + memset(skincolors, 0, sizeof(skincolors)); + + if (skincolornames) + Z_Free(skincolornames); + skincolornames = strbuf_alloc(); + name = hardcodeskincolors; + for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) + skincolors[i].nameofs = strbuf_append(&skincolornames, name); + + for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) + { + skincolors[i].accessible = false; + skincolors[i].name[0] = '\0'; + } + + if (!init) + { + lumpnum = W_CheckNumForLongNamePwadNoUpper("skincolors", MAINWAD_MAIN, 0); + DEH_LoadDehackedLumpPwad(MAINWAD_MAIN, lumpnum, true); + } + } + + // menudefs (TODO: actually reset this with resetdata?) + if (init) + { + memset(&menudefs[MN_FIRSTFREESLOT], 0, sizeof (menu_t) * NUMMENUFREESLOTS); + for (i = 0; i < NUMMENUTYPES; i++) + menudefs[i].drawroutine = M_DrawGenericMenu; + + if (menunames) + Z_Free(menunames); + menunames = strbuf_alloc(); + name = hardcodemenus; + for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1) + menudefs[i].nameofs = strbuf_append(&menunames, name); } -#endif } diff --git a/src/info.h b/src/info.h index dd7dce5bd..b8c616fec 100644 --- a/src/info.h +++ b/src/info.h @@ -139,10 +139,6 @@ struct mobjinfo_t extern mobjinfo_t mobjinfo[NUMMOBJTYPES]; -void P_PatchInfoTables(void); - -void P_BackupTables(void); - void P_ResetData(INT32 flags); #ifdef __cplusplus diff --git a/src/w_wad.c b/src/w_wad.c index 27d11d773..6fa3f1a80 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1292,6 +1292,45 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump) return INT16_MAX; } +// +// Like W_CheckNumForLongNamePwad, but doesn't uppercase the search string AAAAAAAAAAAAA +// +UINT16 W_CheckNumForLongNamePwadNoUpper(const char *name, UINT16 wad, UINT16 startlump) +{ + UINT16 i; + char uname[8+1]; + UINT32 hash; + + if (!TestValidLump(wad,0)) + return INT16_MAX; + + strncpy(uname, name, sizeof uname); + strupr(uname); + hash = quickncasehash(uname, 8); // Not a mistake, legacy system for short lumpnames + + // + // scan forward + // start at 'startlump', useful parameter when there are multiple + // resources with the same name + // + if (startlump < wadfiles[wad]->numlumps) + { + lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) + { + if (lump_p->hash != hash) + continue; + if (strcmp(lump_p->longname, name)) + continue; + return i; + } + + } + + // not found. + return INT16_MAX; +} + UINT16 W_CheckNumForMarkerStartPwad (const char *name, UINT16 wad, UINT16 startlump) { diff --git a/src/w_wad.h b/src/w_wad.h index 3a60b1389..6449027e3 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -169,6 +169,7 @@ UINT16 W_FindNextEmptyInPwad(UINT16 wad, UINT16 startlump); // checks only in on UINT16 W_CheckNumForMapPwad(const char *name, UINT32 hash, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump); +UINT16 W_CheckNumForLongNamePwadNoUpper(const char *name, UINT16 wad, UINT16 startlump); /* Find the first lump after F_START for instance. */ UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlump); From 711944350e1badb5e1ae1936423ba462f38e484e Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 14 May 2025 18:56:28 +0200 Subject: [PATCH 06/15] Deduplicated freeslotting code --- src/deh_lua.c | 160 +++--------------------------------------------- src/deh_soc.c | 124 +------------------------------------ src/dehacked.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++ src/dehacked.h | 1 + 4 files changed, 171 insertions(+), 275 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 484e5519d..12787801b 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -12,7 +12,6 @@ #include "deh_lua.h" #include "deh_tables.h" -#include "k_hud.h" // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. @@ -47,162 +46,17 @@ static inline int lib_freeslot(lua_State *L) Z_Free(s); return luaL_error(L, "Missing enum name in '%s'\n", luaL_checkstring(L, 1)); } - if (fastcmp(type, "SFX")) { - sfxenum_t sfx; + + if (fastcmp(type, "SFX")) strlwr(word); - CONS_Printf("Sound sfx_%s allocated.\n",word); - sfx = S_AddSoundFx(word, false, 0, false); - if (sfx != sfx_None) { - lua_pushinteger(L, sfx); - r++; - } else - CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n"); - } - else if (fastcmp(type, "SPR")) - { - spritenum_t j; - for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++) - { - if (used_spr[(j-SPR_FIRSTFREESLOT)/8] & (1<<(j%8))) - continue; // Already allocated, next. - // Found a free slot! - CONS_Printf("Sprite SPR_%s allocated.\n",word); - strncpy(sprnames[j],word,4); - used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now. - // Lua needs to update the value in _G if it exists - LUA_UpdateSprName(word, j); - lua_pushinteger(L, j); - r++; - break; - } - if (j > SPR_LASTFREESLOT) - CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n"); - } - else if (fastcmp(type, "S")) - { - statenum_t i; - for (i = S_FIRSTFREESLOT; i < NUMSTATES; i++) - if (!states[i].nameofs) { - CONS_Printf("State S_%s allocated.\n",word); - states[i].nameofs = strbuf_append(&statenames, word); - freeslotusage[0][0]++; - lua_pushinteger(L, i); - r++; - break; - } - if (i == NUMSTATES) - CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n"); - } - else if (fastcmp(type, "MT")) - { - mobjtype_t i; - for (i = MT_FIRSTFREESLOT; i < NUMMOBJTYPES; i++) - if (!mobjinfo[i].nameofs) { - CONS_Printf("MobjType MT_%s allocated.\n",word); - mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); - freeslotusage[1][0]++; - lua_pushinteger(L, i); - r++; - break; - } - if (i == NUMMOBJTYPES) - CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); - } - else if (fastcmp(type, "SKINCOLOR")) - { - skincolornum_t i; - for (i = SKINCOLOR_FIRSTFREESLOT; i < MAXSKINCOLORS; i++) - if (!skincolors[i].nameofs) { - CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); - skincolors[i].nameofs = strbuf_append(&skincolornames, word); - M_AddMenuColor(numskincolors++); - K_ReloadHUDColorCvar(); - lua_pushinteger(L, i); - r++; - break; - } - if (i == MAXSKINCOLORS) - CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); - } - else if (fastcmp(type, "SPR2")) - { - // Search if we already have an SPR2 by that name... - playersprite_t 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); - spr2defaults[free_spr2] = 0; - lua_pushinteger(L, free_spr2); - r++; - spr2names[free_spr2++][4] = 0; - } else - CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n"); - } - } - else if (fastcmp(type, "TOL")) - { - // Search if we already have a typeoflevel by that name... - int i; - for (i = 0; TYPEOFLEVEL[i].name; i++) - if (fastcmp(word, TYPEOFLEVEL[i].name)) - break; - // We don't, so allocate a new one. - if (TYPEOFLEVEL[i].name == NULL) { - if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags. - CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n"); - else { - CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word); - G_AddTOL(lastcustomtol, word); - lua_pushinteger(L, lastcustomtol); - lastcustomtol <<= 1; - r++; - } - } - } - else if (fastcmp(type, "PRECIP")) + INT32 index; + if (!DEH_ReadFreeslot(type, word, &index)) { - // Search if we already have a PRECIP by that name... - preciptype_t i; - for (i = PRECIP_FIRSTFREESLOT; i < precip_freeslot; i++) - if (fastcmp(word, precipprops[i].name)) - break; + lua_pushinteger(L, index); + r++; + } - // We don't, so allocate a new one. - if (i >= precip_freeslot) { - if (precip_freeslot < MAXPRECIP) - { - CONS_Printf("Weather PRECIP_%s allocated.\n",word); - precipprops[i].name = Z_StrDup(word); - lua_pushinteger(L, precip_freeslot); - r++; - precip_freeslot++; - } else - CONS_Alert(CONS_WARNING, "Ran out of free PRECIP slots!\n"); - } - } - else if (fastcmp(type, "MN")) - { - menutype_t i; - for (i = MN_FIRSTFREESLOT; i < NUMMENUTYPES; i++) { - if (!menudefs[i].nameofs) { - CONS_Printf("Menu MN_%s allocated.\n",word); - menudefs[i].nameofs = strbuf_append(&menunames, word); - lua_pushinteger(L, i); - r++; - break; - } - } - if (i == NUMMENUFREESLOTS) - CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n"); - } - Z_Free(s); lua_remove(L, 1); continue; } diff --git a/src/deh_soc.c b/src/deh_soc.c index 1fe95a74b..29344be94 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -52,7 +52,6 @@ // SRB2Kart #include "filesrch.h" // refreshdirmenu #include "k_follower.h" -#include "k_hud.h" #include "doomstat.h" // MAXMUSNAMES // Loops through every constant and operation in word and performs its calculations, returning the final value. @@ -392,7 +391,6 @@ void readfreeslots(MYFILE *f) char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word,*type; char *tmp; - int i; do { @@ -419,126 +417,8 @@ void readfreeslots(MYFILE *f) else break; - // TODO: Check for existing freeslot mobjs/states/etc. and make errors. - // TODO: Out-of-slots warnings/errors. - // TODO: Name too long (truncated) warnings. - if (fastcmp(type, "SFX")) - { - CONS_Printf("Sound sfx_%s allocated.\n",word); - S_AddSoundFx(word, false, 0, false); - } - else if (fastcmp(type, "SPR")) - { - for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) - { - if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8))) - continue; // Already allocated, next. - // Found a free slot! - CONS_Printf("Sprite SPR_%s allocated.\n",word); - strncpy(sprnames[i],word,4); - used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now. - // Lua needs to update the value in _G if it exists - LUA_UpdateSprName(word, i); - break; - } - } - else if (fastcmp(type, "S")) - { - for (i = S_FIRSTFREESLOT; i < NUMSTATES; i++) - if (!states[i].nameofs) { - CONS_Printf("State S_%s allocated.\n",word); - states[i].nameofs = strbuf_append(&statenames, word); - freeslotusage[0][0]++; - break; - } - } - else if (fastcmp(type, "MT")) - { - for (i = MT_FIRSTFREESLOT; i < NUMMOBJFREESLOTS; i++) - if (!mobjinfo[i].nameofs) { - CONS_Printf("MobjType MT_%s allocated.\n",word); - mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); - freeslotusage[1][0]++; - break; - } - } - else if (fastcmp(type, "SKINCOLOR")) - { - for (i = SKINCOLOR_FIRSTFREESLOT; i < MAXSKINCOLORS; i++) - if (!skincolors[i].nameofs) { - CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); - skincolors[i].nameofs = strbuf_append(&skincolornames, word); - M_AddMenuColor(numskincolors++); - K_ReloadHUDColorCvar(); - 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); - spr2defaults[free_spr2] = 0; - spr2names[free_spr2++][4] = 0; - } else - deh_warning("Ran out of free SPR2 slots!\n"); - } - else if (fastcmp(type, "TOL")) - { - // Search if we already have a typeoflevel by that name... - for (i = 0; TYPEOFLEVEL[i].name; i++) - if (fastcmp(word, TYPEOFLEVEL[i].name)) - break; - - // We found it? Then don't allocate another one. - if (TYPEOFLEVEL[i].name) - continue; - - // We don't, so freeslot it. - if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags. - deh_warning("Ran out of free typeoflevel slots!\n"); - else - { - G_AddTOL(lastcustomtol, word); - lastcustomtol <<= 1; - } - } - else if (fastcmp(type, "PRECIP")) - { - // Search if we already have a PRECIP by that name... - for (i = PRECIP_FIRSTFREESLOT; i < (int)precip_freeslot; i++) - if (fastcmp(word, precipprops[i].name)) - break; - - // We found it? Then don't allocate another one. - if (i < (int)precip_freeslot) - continue; - - // We don't, so allocate a new one. - if (precip_freeslot < MAXPRECIP) - { - precipprops[i].name = Z_StrDup(word); - precip_freeslot++; - } else - deh_warning("Ran out of free PRECIP slots!\n"); - } - else if (fastcmp(type, "MN")) - { - for (i = MN_FIRSTFREESLOT; i < NUMMENUTYPES; i++) - if (!menudefs[i].nameofs) { - CONS_Printf("Menu MN_%s allocated.\n",word); - menudefs[i].nameofs = strbuf_append(&menunames, word); - break; - } - } - else + INT32 index; + if (DEH_ReadFreeslot(type, word, &index) == -2) deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word); } } while (!myfeof(f)); // finish when the line is empty diff --git a/src/dehacked.c b/src/dehacked.c index 102b8de30..1b2e6e917 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -13,7 +13,9 @@ #include "doomdef.h" #include "m_cond.h" #include "deh_soc.h" +#include "deh_lua.h" #include "deh_tables.h" +#include "k_hud.h" boolean gamedataadded = false; boolean titlechanged = false; @@ -174,6 +176,165 @@ static void ignorelines(MYFILE *f) Z_Free(s); } +INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) +{ + size_t i; + + // TODO: Check for existing freeslot mobjs/states/etc. and make errors. + // TODO: Name too long (truncated) warnings. + if (fastcmp(type, "SFX")) + { + CONS_Printf("Sound sfx_%s allocated.\n", word); + i = S_AddSoundFx(word, false, 0, false); + if (i != sfx_None) + { + *out = i; + return 0; + } + CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n"); + return -1; + } + else if (fastcmp(type, "SPR")) + { + for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) + { + if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8))) + continue; // Already allocated, next. + // Found a free slot! + CONS_Printf("Sprite SPR_%s allocated.\n",word); + strncpy(sprnames[i],word,4); + used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now. + // Lua needs to update the value in _G if it exists + LUA_UpdateSprName(word, i); + *out = i; + return 0; + } + CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n"); + return -1; + } + else if (fastcmp(type, "S")) + { + for (i = S_FIRSTFREESLOT; i < NUMSTATES; i++) + if (!states[i].nameofs) { + CONS_Printf("State S_%s allocated.\n",word); + states[i].nameofs = strbuf_append(&statenames, word); + freeslotusage[0][0]++; + *out = i; + return 0; + } + CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n"); + return -1; + } + else if (fastcmp(type, "MT")) + { + for (i = MT_FIRSTFREESLOT; i < NUMMOBJTYPES; i++) + if (!mobjinfo[i].nameofs) { + CONS_Printf("MobjType MT_%s allocated.\n",word); + mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); + freeslotusage[1][0]++; + *out = i; + return 0; + } + CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); + return -1; + } + else if (fastcmp(type, "SKINCOLOR")) + { + for (i = SKINCOLOR_FIRSTFREESLOT; i < MAXSKINCOLORS; i++) + if (!skincolors[i].nameofs) { + CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); + skincolors[i].nameofs = strbuf_append(&skincolornames, word); + M_AddMenuColor(numskincolors++); + K_ReloadHUDColorCvar(); + *out = i; + return 0; + } + CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); + return -1; + } + else if (fastcmp(type, "SPR2")) + { + // Search if we already have an SPR2 by that name... + 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); + spr2defaults[free_spr2] = 0; + *out = free_spr2; + spr2names[free_spr2++][4] = 0; + return 0; + } else { + CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n"); + return -1; + } + } + } + else if (fastcmp(type, "TOL")) + { + // Search if we already have a typeoflevel by that name... + for (i = 0; TYPEOFLEVEL[i].name; i++) + if (fastcmp(word, TYPEOFLEVEL[i].name)) + break; + + // We don't, so allocate a new one. + if (TYPEOFLEVEL[i].name == NULL) { + if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags. + { + CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n"); + return -1; + } else { + CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word); + G_AddTOL(lastcustomtol, word); + *out = lastcustomtol; + lastcustomtol <<= 1; + return 0; + } + } + } + else if (fastcmp(type, "PRECIP")) + { + // Search if we already have a PRECIP by that name... + for (i = PRECIP_FIRSTFREESLOT; i < precip_freeslot; i++) + if (fastcmp(word, precipprops[i].name)) + break; + + // We don't, so allocate a new one. + if (i >= precip_freeslot) { + if (precip_freeslot < MAXPRECIP) + { + CONS_Printf("Weather PRECIP_%s allocated.\n",word); + precipprops[i].name = Z_StrDup(word); + *out = precip_freeslot; + precip_freeslot++; + return 0; + } else { + CONS_Alert(CONS_WARNING, "Ran out of free PRECIP slots!\n"); + return -1; + } + } + } + else if (fastcmp(type, "MN")) + { + for (i = MN_FIRSTFREESLOT; i < NUMMENUTYPES; i++) { + if (!menudefs[i].nameofs) { + CONS_Printf("Menu MN_%s allocated.\n",word); + menudefs[i].nameofs = strbuf_append(&menunames, word); + *out = i; + return 0; + } + } + CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n"); + return -1; + } + + return -2; +} + static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); diff --git a/src/dehacked.h b/src/dehacked.h index 9b16178e7..3948bbfeb 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -33,6 +33,7 @@ typedef enum void DEH_LoadDehackedLump(lumpnum_t lumpnum); void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile); +INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out); // SRB2Kart extern int freeslotusage[2][2]; From 4e66cb67a8b1696e82d50fb507bd793953125d6a Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 14 May 2025 19:03:29 +0200 Subject: [PATCH 07/15] Fix returned mobj/state index in compatmode --- src/deh_lua.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/deh_lua.c b/src/deh_lua.c index 12787801b..5f9940251 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -53,6 +53,14 @@ static inline int lib_freeslot(lua_State *L) INT32 index; if (!DEH_ReadFreeslot(type, word, &index)) { + if (lua_compatmode) + { + if (fastcmp(type, "MT")) + index -= MT_FIRSTFREESLOT; + if (fastcmp(type, "S")) + index -= S_FIRSTFREESLOT; + } + lua_pushinteger(L, index); r++; } From c3fe5e80ac8724e5637bd757aedc0b7222d17c49 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 18 May 2025 14:46:24 +0200 Subject: [PATCH 08/15] Screw checking for nameofs being zero, just keep count of mobjs/states --- src/deh_lua.c | 20 ++++++-------------- src/deh_soc.c | 16 ++++------------ src/deh_tables.h | 1 - src/dehacked.c | 9 ++++++--- src/info.c | 12 ++++++++++-- src/info.h | 2 ++ src/m_menu.c | 7 ++++--- src/m_menu.h | 8 ++++---- 8 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 5f9940251..5111f0dc3 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -111,7 +111,7 @@ static void CacheAndPushConstant(lua_State *L, const char *name, lua_Integer val static int ScanConstants(lua_State *L, boolean mathlib, const char *word) { const char *p; - fixed_t i; + size_t i; if (strlen(word) == 1) { // Assume sprite frame if length 1. if (*word >= 'A' && *word <= '~') @@ -285,9 +285,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) lua_pushinteger(L, S_FIRSTFREESLOT); return 1; } - for (i = 0; i < NUMSTATES; i++) { - if (!states[i].nameofs) - break; + for (i = 0; i < numstates; i++) { if (fastcmp(p, strbuf_get(statenames, states[i].nameofs))) { CacheAndPushConstant(L, word, i); return 1; @@ -308,9 +306,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) lua_pushinteger(L, MT_FIRSTFREESLOT); return 1; } - for (i = 0; i < NUMMOBJTYPES; i++) { - if (!mobjinfo[i].nameofs) - break; + for (i = 0; i < nummobjtypes ; i++) { if (fastcmp(p, strbuf_get(mobjnames, mobjinfo[i].nameofs))) { CacheAndPushConstant(L, word, i); return 1; @@ -346,7 +342,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("SPR2_",word,5)) { p = word+5; - for (i = 0; i < (fixed_t)free_spr2; i++) + for (i = 0; i < free_spr2; i++) if (!spr2names[i][4]) { // special 3-char cases, e.g. SPR2_RUN @@ -449,9 +445,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("SKINCOLOR_",word,10)) { p = word+10; - for (i = 0; i < MAXSKINCOLORS; i++) { - if (!skincolors[i].nameofs) - break; + for (i = 0; i < numskincolors; i++) { if (fastcmp(p, strbuf_get(skincolornames, skincolors[i].nameofs))) { CacheAndPushConstant(L, word, i); return 1; @@ -461,9 +455,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("MN_",word,3)) { p = word+3; - for (i = 0; i < NUMMENUTYPES; i++) { - if (!menudefs[i].nameofs) - break; + for (i = 0; i < nummenutypes; i++) { if (fastcmp(p, strbuf_get(menunames, menudefs[i].nameofs)) ){ CacheAndPushConstant(L, word, i); return 1; diff --git a/src/deh_soc.c b/src/deh_soc.c index 29344be94..f53d9c5ee 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -4126,9 +4126,7 @@ mobjtype_t get_mobjtype(const char *word) return atoi(word); if (fastncmp("MT_",word,3)) word += 3; // take off the MT_ - for (i = 0; i < NUMMOBJTYPES; i++) { - if (!mobjinfo[i].nameofs) - break; + for (i = 0; i < nummobjtypes; i++) { if (fastcmp(word, strbuf_get(mobjnames, mobjinfo[i].nameofs))) return i; } @@ -4143,9 +4141,7 @@ statenum_t get_state(const char *word) return atoi(word); if (fastncmp("S_",word,2)) word += 2; // take off the S_ - for (i = 0; i < NUMSTATES; i++) { - if (!states[i].nameofs) - break; + for (i = 0; i < numstates; i++) { if (fastcmp(word, strbuf_get(statenames, states[i].nameofs))) return i; } @@ -4160,9 +4156,7 @@ skincolornum_t get_skincolor(const char *word) return atoi(word); if (fastncmp("SKINCOLOR_",word,10)) word += 10; // take off the SKINCOLOR_ - for (i = 0; i < MAXSKINCOLORS; i++) { - if (!skincolors[i].nameofs) - break; + for (i = 0; i < numskincolors; i++) { if (fastcmp(word, strbuf_get(skincolornames, skincolors[i].nameofs))) return i; } @@ -4221,9 +4215,7 @@ menutype_t get_menutype(const char *word) return atoi(word); if (fastncmp("MN_",word,3)) word += 3; // take off the MN_ - for (i = 0; i < NUMMENUTYPES; i++) { - if (!menudefs[i].nameofs) - break; + for (i = 0; i < nummenutypes; i++) { if (fastcmp(word, strbuf_get(menunames, menudefs[i].nameofs))) return i; } diff --git a/src/deh_tables.h b/src/deh_tables.h index 7d564694d..9f0627a29 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -16,7 +16,6 @@ #include "doomdef.h" // Constants #include "d_think.h" // actionf_t #include "info.h" // Mobj, state, sprite, etc constants -#include "m_menu.h" // NUMMENUFREESLOTS #include "lua_script.h" #include "strbuf.h" diff --git a/src/dehacked.c b/src/dehacked.c index 1b2e6e917..bc8bf9d2c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -218,6 +218,7 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) if (!states[i].nameofs) { CONS_Printf("State S_%s allocated.\n",word); states[i].nameofs = strbuf_append(&statenames, word); + numstates++; freeslotusage[0][0]++; *out = i; return 0; @@ -231,6 +232,7 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) if (!mobjinfo[i].nameofs) { CONS_Printf("MobjType MT_%s allocated.\n",word); mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); + nummobjtypes++; freeslotusage[1][0]++; *out = i; return 0; @@ -320,10 +322,11 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "MN")) { - for (i = MN_FIRSTFREESLOT; i < NUMMENUTYPES; i++) { + for (i = MN_FIRSTFREESLOT; i < MAXMENUTYPES; i++) { if (!menudefs[i].nameofs) { CONS_Printf("Menu MN_%s allocated.\n",word); menudefs[i].nameofs = strbuf_append(&menunames, word); + nummenutypes++; *out = i; return 0; } @@ -632,12 +635,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_menutype(word2); // find a huditem by name - if (i >= 1 && i < NUMMENUTYPES) + if (i >= 1 && i < nummenutypes) readmenu(f, i); else { // zero-based, but let's start at 1 - deh_warning("Menu number %d out of range (1 - %d)", i, NUMMENUTYPES-1); + deh_warning("Menu number %d out of range (1 - %d)", i, nummenutypes-1); ignorelines(f); } } diff --git a/src/info.c b/src/info.c index 4b9e594a4..bc0774fc4 100644 --- a/src/info.c +++ b/src/info.c @@ -81,8 +81,10 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = { // Doesn't work with g++, needs actionf_p1 (don't modify this comment) state_t states[NUMSTATES] = {0}; +size_t numstates; mobjinfo_t mobjinfo[NUMMOBJTYPES] = {0}; +size_t nummobjtypes; skincolor_t skincolors[MAXSKINCOLORS] = {0}; @@ -145,6 +147,8 @@ void P_ResetData(INT32 flags) if (!init) memset(states, 0, sizeof(states)); + numstates = S_FIRSTFREESLOT; + if (statenames) Z_Free(statenames); statenames = strbuf_alloc(); @@ -165,6 +169,8 @@ void P_ResetData(INT32 flags) if (!init) memset(mobjinfo, 0, sizeof(mobjinfo)); + nummobjtypes = MT_FIRSTFREESLOT; + if (mobjnames) Z_Free(mobjnames); mobjnames = strbuf_alloc(); @@ -211,10 +217,12 @@ void P_ResetData(INT32 flags) // menudefs (TODO: actually reset this with resetdata?) if (init) { - memset(&menudefs[MN_FIRSTFREESLOT], 0, sizeof (menu_t) * NUMMENUFREESLOTS); - for (i = 0; i < NUMMENUTYPES; i++) + memset(menudefs, 0, sizeof(menudefs)); + for (i = 0; i < MAXMENUTYPES; i++) menudefs[i].drawroutine = M_DrawGenericMenu; + nummenutypes = MN_FIRSTFREESLOT; + if (menunames) Z_Free(menunames); menunames = strbuf_alloc(); diff --git a/src/info.h b/src/info.h index b8c616fec..45c6785d1 100644 --- a/src/info.h +++ b/src/info.h @@ -91,6 +91,7 @@ struct state_t }; extern state_t states[NUMSTATES]; +extern size_t numstates; extern char sprnames[NUMSPRITES + 1][5]; extern char spr2names[NUMPLAYERSPRITES][5]; extern playersprite_t spr2defaults[NUMPLAYERSPRITES]; @@ -138,6 +139,7 @@ struct mobjinfo_t }; extern mobjinfo_t mobjinfo[NUMMOBJTYPES]; +extern size_t nummobjtypes; void P_ResetData(INT32 flags); diff --git a/src/m_menu.c b/src/m_menu.c index 01c3e2c2c..74c09e682 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -166,7 +166,8 @@ static UINT32 serverlistpage; INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? -menu_t menudefs[NUMMENUTYPES]; // array of all menudefs +menu_t menudefs[MAXMENUTYPES]; // array of all menudefs +size_t nummenutypes; menutype_t menustack[NUMMENULEVELS]; // stack of active menus, [0] == current menu static menu_t *currentMenu; // current menudef static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 @@ -754,7 +755,7 @@ void Moviemode_option_Onchange(void) // MENU PRESENTATION PARAMETER HANDLING (BACKGROUNDS) // ========================================================================= -menupres_t menupres[NUMMENUTYPES]; +menupres_t menupres[MAXMENUTYPES]; void M_InitMenuPresTables(void) { @@ -762,7 +763,7 @@ void M_InitMenuPresTables(void) // Called in d_main before SOC can get to the tables // Set menupres defaults - for (i = 0; i < NUMMENUTYPES; i++) + for (i = 0; i < MAXMENUTYPES; i++) { // so-called "undefined" menupres[i].fadestrength = -1; diff --git a/src/m_menu.h b/src/m_menu.h index 8b11fac75..0d0024373 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -46,9 +46,8 @@ typedef enum MN_FIRSTFREESLOT, MN_LASTFREESLOT = MN_FIRSTFREESLOT + 128, - NUMMENUTYPES, + MAXMENUTYPES, } menutype_t; -#define NUMMENUFREESLOTS (NUMMENUTYPES - MN_FIRSTFREESLOT) extern menutype_t menustack[NUMMENULEVELS]; @@ -84,7 +83,7 @@ typedef struct INT16 exitwipe; // wipe type to run on menu exit, -1 means default } menupres_t; -extern menupres_t menupres[NUMMENUTYPES]; +extern menupres_t menupres[MAXMENUTYPES]; void M_InitMenuPresTables(void); //UINT8 M_GetYoungestChildMenu(void); @@ -258,7 +257,8 @@ struct menu_t void (*quitroutine)(INT32 choice); // called before quit a menu }; -extern menu_t menudefs[NUMMENUTYPES]; +extern menu_t menudefs[MAXMENUTYPES]; +extern size_t nummenutypes; void M_EnterMenu(menutype_t menu, boolean callexit); void M_ExitMenu(void); From 95ae54fd08a25b8a126a869cfecd3f3bfbea3032 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 18 May 2025 14:47:50 +0200 Subject: [PATCH 09/15] Actually inline strbuf_get --- src/strbuf.c | 6 ------ src/strbuf.h | 7 ++++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/strbuf.c b/src/strbuf.c index a38db9aad..89987e377 100644 --- a/src/strbuf.c +++ b/src/strbuf.c @@ -47,9 +47,3 @@ UINT32 strbuf_append(strbuf_t **strbuf, const char *str) strcpy(buf->buf - sizeof(UINT32) + oldsize, str); return oldsize; } - -// returns the string at the given offset -char *strbuf_get(strbuf_t *strbuf, UINT32 ofs) -{ - return strbuf->buf - sizeof(UINT32) + ofs; -} diff --git a/src/strbuf.h b/src/strbuf.h index 238e5bf7f..5ed454995 100644 --- a/src/strbuf.h +++ b/src/strbuf.h @@ -22,7 +22,12 @@ struct strbuf_t strbuf_t *strbuf_alloc(void); UINT32 strbuf_append(strbuf_t **strbuf, const char *str); -char *strbuf_get(strbuf_t *strbuf, UINT32 ofs); + +// returns the string at the given offset +FUNCINLINE static ATTRINLINE char *strbuf_get(strbuf_t *strbuf, UINT32 ofs) +{ + return (char *)strbuf + ofs; +} #ifdef __cplusplus } From 0009807746d7812e3339bf08002f281b3491b312 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 18 May 2025 17:37:47 +0200 Subject: [PATCH 10/15] Unify info lookup functions for SOC/Lua/ACS Use MAX* constants instead of -1 for invalid values, because enum signedness is implementation-defined --- src/acs/call-funcs.cpp | 42 +++++++++-------------------- src/d_netcmd.c | 8 +++--- src/deh_lua.c | 40 +++++++++++++-------------- src/deh_soc.c | 52 +++++++++++++++-------------------- src/deh_tables.c | 61 ++++++++++++++++++++++++++++++++++++++++++ src/deh_tables.h | 11 ++++++++ src/lua_infolib.c | 4 +-- src/p_setup.c | 2 +- src/p_tick.c | 4 +-- src/strbuf.h | 4 +++ 10 files changed, 140 insertions(+), 88 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 474d294e1..b41e19bc3 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -83,21 +83,13 @@ static bool ACS_GetMobjTypeFromString(const char *word, mobjtype_t *type) word += 3; } - for (int i = 0; i < NUMMOBJTYPES; i++) - { - if (!mobjinfo[i].nameofs) - { - break; - } + mobjtype_t i = DEH_FindMobjtype(word); - if (fastcmp(word, strbuf_get(mobjnames, mobjinfo[i].nameofs))) - { - *type = static_cast(i); - return true; - } - } + if (i == NUMMOBJTYPES) + return false; - return false; + *type = i; + return true; } /*-------------------------------------------------- @@ -225,21 +217,13 @@ static bool ACS_GetStateFromString(const char *word, statenum_t *type) word += 2; } - for (int i = 0; i < NUMSTATES; i++) - { - if (!states[i].nameofs) - { - break; - } + statenum_t i = DEH_FindState(word); - if (fastcmp(word, strbuf_get(statenames, states[i].nameofs))) - { - *type = static_cast(i); - return true; - } - } + if (i == NUMSTATES) + return false; - return false; + *type = i; + return true; } /*-------------------------------------------------- @@ -2319,7 +2303,7 @@ bool CallFunc_GetObjectClass(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS if (mobj != NULL && P_MobjWasRemoved(mobj) == false) { std::string prefix = "MT_"; - std::string full = prefix + (strbuf_get(mobjnames, mobjinfo[mobj->type].nameofs)); + std::string full = prefix + DEH_MobjtypeName(mobj->type); mobjClass = static_cast( ~env->getString( full.c_str() )->idx ); } @@ -4373,7 +4357,7 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A case x: \ { \ std::string prefix = "MT_"; \ - std::string full = prefix + (strbuf_get(mobjnames, mobjinfo[mobj->y].nameofs)); \ + std::string full = prefix + DEH_MobjtypeName(mobj->y); \ value = static_cast( ~env->getString( full.c_str() )->idx ); \ break; \ } @@ -4399,7 +4383,7 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A { \ statenum_t stateID = static_cast(mobj->y - states); \ std::string prefix = "S_"; \ - std::string full = prefix + strbuf_get(statenames, states[stateID].nameofs); \ + std::string full = prefix + DEH_StateName(stateID); \ value = static_cast( ~env->getString( full.c_str() )->idx ); \ break; \ } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c3e705bcc..94ca2d63e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4872,10 +4872,10 @@ static void Command_ListDoomednums_f(void) CONS_Printf(" doomednum \x82""%d""\x80 is \x85""double-defined\x80 by ", j+1); if (i < MT_FIRSTFREESLOT) { - CONS_Printf("\x87""hardcode MT_%s <-- MAJOR ERROR\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); + CONS_Printf("\x87""hardcode MT_%s <-- MAJOR ERROR\n", DEH_MobjtypeName(i)); continue; } - CONS_Printf("\x81""freeslot MT_""%s\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); + CONS_Printf("\x81""freeslot MT_""%s\n", DEH_MobjtypeName(i)); continue; } table[j] = i; @@ -4908,10 +4908,10 @@ static void Command_ListDoomednums_f(void) CONS_Printf(" doomednum \x82""%d""\x80 is used by ", i+1); if (table[i] < MT_FIRSTFREESLOT) { - CONS_Printf("\x87""hardcode MT_%s\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); + CONS_Printf("\x87""hardcode MT_%s\n", DEH_MobjtypeName(i)); continue; } - CONS_Printf("\x81""freeslot MT_""%s\n", strbuf_get(mobjnames, mobjinfo[i].nameofs)); + CONS_Printf("\x81""freeslot MT_""%s\n", DEH_MobjtypeName(i)); } } diff --git a/src/deh_lua.c b/src/deh_lua.c index 5111f0dc3..81028c879 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -285,11 +285,11 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) lua_pushinteger(L, S_FIRSTFREESLOT); return 1; } - for (i = 0; i < numstates; i++) { - if (fastcmp(p, strbuf_get(statenames, states[i].nameofs))) { - CacheAndPushConstant(L, word, i); - return 1; - } + i = DEH_FindState(p); + if (i != NUMSTATES) + { + CacheAndPushConstant(L, word, i); + return 1; } if (lua_compatmode) for (i = 0; STATE_ALIASES[i].n; i++) @@ -306,11 +306,11 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) lua_pushinteger(L, MT_FIRSTFREESLOT); return 1; } - for (i = 0; i < nummobjtypes ; i++) { - if (fastcmp(p, strbuf_get(mobjnames, mobjinfo[i].nameofs))) { - CacheAndPushConstant(L, word, i); - return 1; - } + i = DEH_FindMobjtype(p); + if (i != NUMMOBJTYPES) + { + CacheAndPushConstant(L, word, i); + return 1; } if (lua_compatmode) for (i = 0; MOBJ_ALIASES[i].n; i++) @@ -445,21 +445,21 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("SKINCOLOR_",word,10)) { p = word+10; - for (i = 0; i < numskincolors; i++) { - if (fastcmp(p, strbuf_get(skincolornames, skincolors[i].nameofs))) { - CacheAndPushConstant(L, word, i); - return 1; - } + i = DEH_FindSkincolor(p); + if (i != MAXSKINCOLORS) + { + CacheAndPushConstant(L, word, i); + return 1; } return luaL_error(L, "skincolor '%s' could not be found.\n", word); } else if (fastncmp("MN_",word,3)) { p = word+3; - for (i = 0; i < nummenutypes; i++) { - if (fastcmp(p, strbuf_get(menunames, menudefs[i].nameofs)) ){ - CacheAndPushConstant(L, word, i); - return 1; - } + i = DEH_FindMenutype(p); + if (i != MAXMENUTYPES) + { + CacheAndPushConstant(L, word, i); + return 1; } if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word); return 0; diff --git a/src/deh_soc.c b/src/deh_soc.c index f53d9c5ee..4411da648 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1160,7 +1160,7 @@ void readlevelheader(MYFILE *f, char * name) if (fastncmp(tmp, "MT_", 3)) // support for specified mobjtypes... { i = get_mobjtype(tmp); - if (i == -1) + if (i == NUMMOBJTYPES) { //deh_warning("Level header %d: unknown flicky mobj type %s\n", num, tmp); -- no need for this line as get_mobjtype complains too continue; @@ -2172,7 +2172,7 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) continue; } menutype_t mn = get_menutype(word2); - if (mn == MN_NONE) + if (mn == MAXMENUTYPES) { WARN("unknown menu '%s'", word2); continue; @@ -2232,7 +2232,7 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) #undef WARN #undef WARN0 -#define WARN(str, ...) deh_warning("Menu %s: " str, strbuf_get(menunames, menudefs[num].nameofs), __VA_ARGS__) +#define WARN(str, ...) deh_warning("Menu %s: " str, DEH_MenutypeName(num), __VA_ARGS__) void readmenu(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -2539,7 +2539,7 @@ void readframe(MYFILE *f, INT32 num) else if (fastcmp(word1, "NEXT")) { statenum_t state = get_state(word2); - states[num].nextstate = state == (statenum_t)-1 ? S_NULL : state; + states[num].nextstate = state == NUMSTATES ? S_NULL : state; } else if (fastcmp(word1, "VAR1")) { @@ -3867,7 +3867,7 @@ void readfollower(MYFILE *f) else { skincolornum_t color = get_skincolor(word2); - followers[numfollowers].defaultcolor = color == (skincolornum_t)-1 ? SKINCOLOR_GREEN : color; + followers[numfollowers].defaultcolor = color == MAXSKINCOLORS ? SKINCOLOR_GREEN : color; } } else if (fastcmp(word, "SCALE")) @@ -4101,7 +4101,7 @@ void readweather(MYFILE *f, INT32 num) if (fastcmp(word, "TYPE")) { mobjtype_t mt = get_mobjtype(word2); - precipprops[num].type = mt == (mobjtype_t)-1 ? MT_NULL : mt; + precipprops[num].type = mt == NUMMOBJTYPES ? MT_NULL : mt; } else if (fastcmp(word, "EFFECTS")) { @@ -4126,12 +4126,10 @@ mobjtype_t get_mobjtype(const char *word) return atoi(word); if (fastncmp("MT_",word,3)) word += 3; // take off the MT_ - for (i = 0; i < nummobjtypes; i++) { - if (fastcmp(word, strbuf_get(mobjnames, mobjinfo[i].nameofs))) - return i; - } - deh_warning("Couldn't find mobjtype named 'MT_%s'",word); - return -1; + i = DEH_FindMobjtype(word); + if (i == NUMMOBJTYPES) + deh_warning("Couldn't find mobjtype named 'MT_%s'", word); + return i; } statenum_t get_state(const char *word) @@ -4141,12 +4139,10 @@ statenum_t get_state(const char *word) return atoi(word); if (fastncmp("S_",word,2)) word += 2; // take off the S_ - for (i = 0; i < numstates; i++) { - if (fastcmp(word, strbuf_get(statenames, states[i].nameofs))) - return i; - } - deh_warning("Couldn't find state named 'S_%s'",word); - return -1; + i = DEH_FindState(word); + if (i == NUMSTATES) + deh_warning("Couldn't find state named 'S_%s'", word); + return i; } skincolornum_t get_skincolor(const char *word) @@ -4156,12 +4152,10 @@ skincolornum_t get_skincolor(const char *word) return atoi(word); if (fastncmp("SKINCOLOR_",word,10)) word += 10; // take off the SKINCOLOR_ - for (i = 0; i < numskincolors; i++) { - if (fastcmp(word, strbuf_get(skincolornames, skincolors[i].nameofs))) - return i; - } - deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'",word); - return -1; + i = DEH_FindSkincolor(word); + if (i == MAXSKINCOLORS) + deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'", word); + return i; } spritenum_t get_sprite(const char *word) @@ -4215,12 +4209,10 @@ menutype_t get_menutype(const char *word) return atoi(word); if (fastncmp("MN_",word,3)) word += 3; // take off the MN_ - for (i = 0; i < nummenutypes; i++) { - if (fastcmp(word, strbuf_get(menunames, menudefs[i].nameofs))) - return i; - } - deh_warning("Couldn't find menutype named 'MN_%s'",word); - return MN_NONE; + i = DEH_FindMenutype(word); + if (i == MAXMENUTYPES) + deh_warning("Couldn't find menutype named 'MN_%s'", word); + return i; } void (*get_menuroutine(const char *word))(INT32) diff --git a/src/deh_tables.c b/src/deh_tables.c index 60496016e..9d8cd1641 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -31,6 +31,7 @@ #include "k_kart.h" // awardscaledrings_t #include "deh_tables.h" +#include "fastcmp.h" strbuf_t *statenames; strbuf_t *mobjnames; @@ -38,6 +39,66 @@ strbuf_t *skincolornames; strbuf_t *menunames; UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. +const char *DEH_MobjtypeName(mobjtype_t i) +{ + return strbuf_get(mobjnames, mobjinfo[i].nameofs); +} + +const char *DEH_StateName(statenum_t i) +{ + return strbuf_get(statenames, states[i].nameofs); +} + +const char *DEH_SkincolorName(skincolornum_t i) +{ + return strbuf_get(skincolornames, skincolors[i].nameofs); +} + +const char *DEH_MenutypeName(menutype_t i) +{ + return strbuf_get(menunames, menudefs[i].nameofs); +} + +mobjtype_t DEH_FindMobjtype(const char *word) +{ + mobjtype_t i; + for (i = 0; i < nummobjtypes; i++) { + if (fastcmp(word, DEH_MobjtypeName(i))) + return i; + } + return NUMMOBJTYPES; +} + +statenum_t DEH_FindState(const char *word) +{ + statenum_t i; + for (i = 0; i < numstates; i++) { + if (fastcmp(word, DEH_StateName(i))) + return i; + } + return NUMSTATES; +} + +skincolornum_t DEH_FindSkincolor(const char *word) +{ + skincolornum_t i; + for (i = 0; i < numskincolors; i++) { + if (fastcmp(word, DEH_SkincolorName(i))) + return i; + } + return MAXSKINCOLORS; +} + +menutype_t DEH_FindMenutype(const char *word) +{ + menutype_t i; + for (i = 0; i < nummenutypes; i++) { + if (fastcmp(word, DEH_MenutypeName(i))) + return i; + } + return MAXMENUTYPES; +} + struct flickytypes_s FLICKYTYPES[] = { {"BLUEBIRD", MT_FLICKY_01}, // Flicky (Flicky) {"RABBIT", MT_FLICKY_02}, // Pocky (1) diff --git a/src/deh_tables.h b/src/deh_tables.h index 9f0627a29..a35e249c4 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -18,6 +18,7 @@ #include "info.h" // Mobj, state, sprite, etc constants #include "lua_script.h" #include "strbuf.h" +#include "m_menu.h" // menutype_t #ifdef __cplusplus extern "C" { @@ -31,6 +32,16 @@ extern strbuf_t *skincolornames; extern strbuf_t *menunames; extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. +const char *DEH_MobjtypeName(mobjtype_t i); +const char *DEH_StateName(statenum_t i); +const char *DEH_SkincolorName(skincolornum_t i); +const char *DEH_MenutypeName(menutype_t i); + +mobjtype_t DEH_FindMobjtype(const char *word); +statenum_t DEH_FindState(const char *word); +skincolornum_t DEH_FindSkincolor(const char *word); +menutype_t DEH_FindMenutype(const char *word); + struct flickytypes_s { const char *name; const mobjtype_t type; diff --git a/src/lua_infolib.c b/src/lua_infolib.c index eb52c0787..bc2c3611b 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -982,7 +982,7 @@ static int state_get(lua_State *L) statenum_t id = st-states; if (id < NUMSTATES) { - lua_pushstring(L, strbuf_get(statenames, states[id].nameofs)); + lua_pushstring(L, DEH_StateName(id)); return 1; } @@ -1278,7 +1278,7 @@ static int mobjinfo_get(lua_State *L) mobjtype_t id = info-mobjinfo; if (id < NUMMOBJTYPES) { - lua_pushstring(L, strbuf_get(mobjnames, mobjinfo[id].nameofs)); + lua_pushstring(L, DEH_MobjtypeName(id)); return 1; } diff --git a/src/p_setup.c b/src/p_setup.c index b1ccec8a5..aa6493ae9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1185,7 +1185,7 @@ static void P_WriteSkincolor(INT32 constant, char **target) || constant >= (INT32)numskincolors) return; - color_name = strbuf_get(skincolornames, skincolors[constant].nameofs); + color_name = DEH_SkincolorName(constant); P_WriteDuplicateText( va("SKINCOLOR_%s", color_name), diff --git a/src/p_tick.c b/src/p_tick.c index 5f92e8a79..a801cd7cb 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -263,13 +263,13 @@ static const char *MobjTypeName(const mobj_t *mobj) if (p1 == (actionf_p1)P_MobjThinker) { - return strbuf_get(mobjnames, mobjinfo[mobj->type].nameofs); + return DEH_MobjtypeName(mobj->type); } else if (p1 == (actionf_p1)P_RemoveThinkerDelayed) { if (mobj->thinker.debug_mobjtype != MT_NULL) { - return strbuf_get(mobjnames, mobjinfo[mobj->thinker.debug_mobjtype].nameofs); + return DEH_MobjtypeName(mobj->thinker.debug_mobjtype); } } diff --git a/src/strbuf.h b/src/strbuf.h index 5ed454995..85bef9860 100644 --- a/src/strbuf.h +++ b/src/strbuf.h @@ -26,7 +26,11 @@ UINT32 strbuf_append(strbuf_t **strbuf, const char *str); // returns the string at the given offset FUNCINLINE static ATTRINLINE char *strbuf_get(strbuf_t *strbuf, UINT32 ofs) { +#ifdef __cplusplus + return reinterpret_cast(strbuf) + ofs; +#else return (char *)strbuf + ofs; +#endif } #ifdef __cplusplus From 1d0a066590e9df06fe1be46b4f65cc1c0182c326 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 18 May 2025 18:13:04 +0200 Subject: [PATCH 11/15] Add name hashing for supported info types --- src/deh_tables.c | 12 ++++++++++++ src/dehacked.c | 4 ++++ src/doomdef.h | 1 + src/info.c | 16 ++++++++++++---- src/info.h | 4 ++-- src/m_menu.h | 2 +- 6 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 9d8cd1641..9bcf7aacb 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -62,7 +62,10 @@ const char *DEH_MenutypeName(menutype_t i) mobjtype_t DEH_FindMobjtype(const char *word) { mobjtype_t i; + UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < nummobjtypes; i++) { + if (hash != mobjinfo[i].namehash) + continue; if (fastcmp(word, DEH_MobjtypeName(i))) return i; } @@ -72,7 +75,10 @@ mobjtype_t DEH_FindMobjtype(const char *word) statenum_t DEH_FindState(const char *word) { statenum_t i; + UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < numstates; i++) { + if (hash != states[i].namehash) + continue; if (fastcmp(word, DEH_StateName(i))) return i; } @@ -82,7 +88,10 @@ statenum_t DEH_FindState(const char *word) skincolornum_t DEH_FindSkincolor(const char *word) { skincolornum_t i; + UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < numskincolors; i++) { + if (hash != skincolors[i].namehash) + continue; if (fastcmp(word, DEH_SkincolorName(i))) return i; } @@ -92,7 +101,10 @@ skincolornum_t DEH_FindSkincolor(const char *word) menutype_t DEH_FindMenutype(const char *word) { menutype_t i; + UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < nummenutypes; i++) { + if (hash != menudefs[i].namehash) + continue; if (fastcmp(word, DEH_MenutypeName(i))) return i; } diff --git a/src/dehacked.c b/src/dehacked.c index bc8bf9d2c..e98bd5e0e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -218,6 +218,7 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) if (!states[i].nameofs) { CONS_Printf("State S_%s allocated.\n",word); states[i].nameofs = strbuf_append(&statenames, word); + states[i].namehash = HASH32(word, strlen(word)); numstates++; freeslotusage[0][0]++; *out = i; @@ -232,6 +233,7 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) if (!mobjinfo[i].nameofs) { CONS_Printf("MobjType MT_%s allocated.\n",word); mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); + mobjinfo[i].namehash = HASH32(word, strlen(word)); nummobjtypes++; freeslotusage[1][0]++; *out = i; @@ -246,6 +248,7 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) if (!skincolors[i].nameofs) { CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); skincolors[i].nameofs = strbuf_append(&skincolornames, word); + skincolors[i].namehash = HASH32(word, strlen(word)); M_AddMenuColor(numskincolors++); K_ReloadHUDColorCvar(); *out = i; @@ -326,6 +329,7 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) if (!menudefs[i].nameofs) { CONS_Printf("Menu MN_%s allocated.\n",word); menudefs[i].nameofs = strbuf_append(&menunames, word); + menudefs[i].namehash = HASH32(word, strlen(word)); nummenutypes++; *out = i; return 0; diff --git a/src/doomdef.h b/src/doomdef.h index 497b5cfa3..5622a0021 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -222,6 +222,7 @@ extern char logfilename[1024]; struct skincolor_t { + UINT32 namehash; // Hash for internal name UINT32 nameofs; // Offset for internal name char name[MAXCOLORNAME+1]; // Skincolor name UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp diff --git a/src/info.c b/src/info.c index bc0774fc4..7ad593a1c 100644 --- a/src/info.c +++ b/src/info.c @@ -153,8 +153,10 @@ void P_ResetData(INT32 flags) Z_Free(statenames); statenames = strbuf_alloc(); name = hardcodestates; - for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) + for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) { states[i].nameofs = strbuf_append(&statenames, name); + states[i].namehash = HASH32(name, strlen(name)); + } if (!init) { @@ -175,8 +177,10 @@ void P_ResetData(INT32 flags) Z_Free(mobjnames); mobjnames = strbuf_alloc(); name = hardcodemobjs; - for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1) + for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1) { mobjinfo[i].nameofs = strbuf_append(&mobjnames, name); + mobjinfo[i].namehash = HASH32(name, strlen(name)); + } for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++) mobjinfo[i].doomednum = -1; @@ -198,8 +202,10 @@ void P_ResetData(INT32 flags) Z_Free(skincolornames); skincolornames = strbuf_alloc(); name = hardcodeskincolors; - for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) + for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) { skincolors[i].nameofs = strbuf_append(&skincolornames, name); + skincolors[i].namehash = HASH32(name, strlen(name)); + } for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) { @@ -227,7 +233,9 @@ void P_ResetData(INT32 flags) Z_Free(menunames); menunames = strbuf_alloc(); name = hardcodemenus; - for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1) + for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1) { menudefs[i].nameofs = strbuf_append(&menunames, name); + menudefs[i].namehash = HASH32(name, strlen(name)); + } } } diff --git a/src/info.h b/src/info.h index 45c6785d1..e6a716483 100644 --- a/src/info.h +++ b/src/info.h @@ -79,7 +79,7 @@ typedef enum state struct state_t { - UINT32 nameofs; + UINT32 namehash, nameofs; spritenum_t sprite; UINT32 frame; // we use the upper 16 bits for translucency and other shade effects @@ -110,7 +110,7 @@ typedef enum mobj_type struct mobjinfo_t { - UINT32 nameofs; + UINT32 namehash, nameofs; INT32 doomednum; statenum_t spawnstate; diff --git a/src/m_menu.h b/src/m_menu.h index 0d0024373..01de92f5d 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -247,7 +247,7 @@ struct menuitem_t struct menu_t { - UINT32 nameofs; + UINT32 namehash, nameofs; const char *headerpic; INT16 numitems; // # of menu items menuitem_t *menuitems; // menu items From 4d3f43b8e4d6ce191bf717871d1c8a972993d2cf Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 19 May 2025 17:28:53 +0200 Subject: [PATCH 12/15] Move skincolors definition from doomdef.h to info.h Recompiling 80% of the codebase every time was getting on my nerves... also clean up initialization a bit --- src/d_main.cpp | 5 ----- src/doomdef.h | 30 ------------------------------ src/info.c | 2 ++ src/info.h | 29 +++++++++++++++++++++++++++++ src/k_color.h | 2 +- src/m_cond.h | 2 +- src/m_menu.c | 1 - 7 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 59ba45c8a..ba167ed66 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1392,10 +1392,6 @@ void D_SRB2Main(void) if (M_CheckParm("-password") && M_IsNextParm()) D_SetPassword(M_GetNextParm()); - // player setup menu colors must be initialized before - // any wad file is added, as they may contain colors themselves - M_InitPlayerSetupColors(); - CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); Z_Init(); CON_SetLoadingProgress(LOADED_ZINIT); @@ -1504,7 +1500,6 @@ void D_SRB2Main(void) R_InitPaletteRemap(); - // now do it again for the SOC colors in main.pk3! M_InitPlayerSetupColors(); // Do it before P_InitMapData because PNG patch diff --git a/src/doomdef.h b/src/doomdef.h index 5622a0021..d4658569b 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -220,36 +220,6 @@ extern char logfilename[1024]; // Master Server compatibility ONLY #define MSCOMPAT_MAXPLAYERS (32) -struct skincolor_t -{ - UINT32 namehash; // Hash for internal name - UINT32 nameofs; // Offset for internal name - char name[MAXCOLORNAME+1]; // Skincolor name - UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp - UINT16 invcolor; // Signpost color - UINT8 invshade; // Signpost color shade - UINT16 chatcolor; // Chat color - boolean accessible; // Accessible by the color command + setup menu -}; - -typedef enum -{ -#define _(name, ...) SKINCOLOR_##name, -#include "info/skincolors.h" -#undef _ - SKINCOLOR_FIRSTFREESLOT, - SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, - MAXSKINCOLORS, - - FIRSTRAINBOWCOLOR = SKINCOLOR_PINK, - FIRSTSUPERCOLOR = SKINCOLOR_SUPER1, - NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5) -} skincolornum_t; - -extern UINT16 numskincolors; - -extern skincolor_t skincolors[MAXSKINCOLORS]; - // State updates, number of tics / second. // NOTE: used to setup the timer rate, see I_StartupTimer(). #define TICRATE 35 diff --git a/src/info.c b/src/info.c index 7ad593a1c..c7c4ef776 100644 --- a/src/info.c +++ b/src/info.c @@ -198,6 +198,8 @@ void P_ResetData(INT32 flags) if (!init) memset(skincolors, 0, sizeof(skincolors)); + numskincolors = SKINCOLOR_FIRSTFREESLOT; + if (skincolornames) Z_Free(skincolornames); skincolornames = strbuf_alloc(); diff --git a/src/info.h b/src/info.h index e6a716483..9b40b7e1d 100644 --- a/src/info.h +++ b/src/info.h @@ -141,6 +141,35 @@ struct mobjinfo_t extern mobjinfo_t mobjinfo[NUMMOBJTYPES]; extern size_t nummobjtypes; +typedef enum +{ +#define _(name, ...) SKINCOLOR_##name, +#include "info/skincolors.h" +#undef _ + SKINCOLOR_FIRSTFREESLOT, + SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, + MAXSKINCOLORS, + + FIRSTRAINBOWCOLOR = SKINCOLOR_PINK, + FIRSTSUPERCOLOR = SKINCOLOR_SUPER1, + NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5) +} skincolornum_t; + +struct skincolor_t +{ + UINT32 namehash; // Hash for internal name + UINT32 nameofs; // Offset for internal name + char name[MAXCOLORNAME+1]; // Skincolor name + UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp + UINT16 invcolor; // Signpost color + UINT8 invshade; // Signpost color shade + UINT16 chatcolor; // Chat color + boolean accessible; // Accessible by the color command + setup menu +}; + +extern skincolor_t skincolors[MAXSKINCOLORS]; +extern UINT16 numskincolors; + void P_ResetData(INT32 flags); #ifdef __cplusplus diff --git a/src/k_color.h b/src/k_color.h index 2f002c6e6..bd208a985 100644 --- a/src/k_color.h +++ b/src/k_color.h @@ -12,7 +12,7 @@ #ifndef __K_COLOR__ #define __K_COLOR__ -#include "doomdef.h" +#include "info.h" #include "doomtype.h" #ifdef __cplusplus diff --git a/src/m_cond.h b/src/m_cond.h index 636726019..d4c3e116b 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -13,7 +13,7 @@ #ifndef __M_COND_H__ #define __M_COND_H__ -#include "doomdef.h" +#include "info.h" #ifdef __cplusplus extern "C" { diff --git a/src/m_menu.c b/src/m_menu.c index 55b416226..8c7281e8a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7994,7 +7994,6 @@ UINT16 M_GetColorAfter(UINT16 color) { void M_InitPlayerSetupColors(void) { UINT16 i; - numskincolors = SKINCOLOR_FIRSTFREESLOT; menucolorhead = menucolortail = NULL; for (i=0; i Date: Mon, 19 May 2025 18:22:00 +0200 Subject: [PATCH 13/15] Turn namehash/nameofs into a struct, and linearly allocate freeslots Also fix bugged skincolor & precipprops clear in lua_infolib --- src/deh_tables.c | 16 ++++----- src/dehacked.c | 88 ++++++++++++++++++++++------------------------- src/dehacked.h | 15 +++----- src/info.c | 24 +++++-------- src/info.h | 10 +++--- src/lua_infolib.c | 34 +++--------------- src/m_menu.h | 2 +- src/typedef.h | 1 + 8 files changed, 72 insertions(+), 118 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 54141c797..9b0fab271 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -41,22 +41,22 @@ UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslo const char *DEH_MobjtypeName(mobjtype_t i) { - return strbuf_get(mobjnames, mobjinfo[i].nameofs); + return strbuf_get(mobjnames, mobjinfo[i].info.nameofs); } const char *DEH_StateName(statenum_t i) { - return strbuf_get(statenames, states[i].nameofs); + return strbuf_get(statenames, states[i].info.nameofs); } const char *DEH_SkincolorName(skincolornum_t i) { - return strbuf_get(skincolornames, skincolors[i].nameofs); + return strbuf_get(skincolornames, skincolors[i].info.nameofs); } const char *DEH_MenutypeName(menutype_t i) { - return strbuf_get(menunames, menudefs[i].nameofs); + return strbuf_get(menunames, menudefs[i].info.nameofs); } mobjtype_t DEH_FindMobjtype(const char *word) @@ -64,7 +64,7 @@ mobjtype_t DEH_FindMobjtype(const char *word) mobjtype_t i; UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < nummobjtypes; i++) { - if (hash != mobjinfo[i].namehash) + if (hash != mobjinfo[i].info.namehash) continue; if (fastcmp(word, DEH_MobjtypeName(i))) return i; @@ -77,7 +77,7 @@ statenum_t DEH_FindState(const char *word) statenum_t i; UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < numstates; i++) { - if (hash != states[i].namehash) + if (hash != states[i].info.namehash) continue; if (fastcmp(word, DEH_StateName(i))) return i; @@ -90,7 +90,7 @@ skincolornum_t DEH_FindSkincolor(const char *word) skincolornum_t i; UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < numskincolors; i++) { - if (hash != skincolors[i].namehash) + if (hash != skincolors[i].info.namehash) continue; if (fastcmp(word, DEH_SkincolorName(i))) return i; @@ -103,7 +103,7 @@ menutype_t DEH_FindMenutype(const char *word) menutype_t i; UINT32 hash = HASH32(word, strlen(word)); for (i = 0; i < nummenutypes; i++) { - if (hash != menudefs[i].namehash) + if (hash != menudefs[i].info.namehash) continue; if (fastcmp(word, DEH_MenutypeName(i))) return i; diff --git a/src/dehacked.c b/src/dehacked.c index e98bd5e0e..71d1cd9ad 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -176,6 +176,12 @@ static void ignorelines(MYFILE *f) Z_Free(s); } +void DEH_Link(const char *name, dehinfo_t *info, strbuf_t **buf) +{ + info->namehash = HASH32(name, strlen(name)); + info->nameofs = strbuf_append(buf, name); +} + INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) { size_t i; @@ -214,48 +220,40 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "S")) { - for (i = S_FIRSTFREESLOT; i < NUMSTATES; i++) - if (!states[i].nameofs) { - CONS_Printf("State S_%s allocated.\n",word); - states[i].nameofs = strbuf_append(&statenames, word); - states[i].namehash = HASH32(word, strlen(word)); - numstates++; - freeslotusage[0][0]++; - *out = i; - return 0; - } - CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n"); - return -1; + if (numstates == NUMSTATES) { + CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n"); + return -1; + } + CONS_Printf("State S_%s allocated.\n",word); + DEH_Link(word, &states[numstates].info, &statenames); + *out = numstates++; + freeslotusage[0][0]++; + return 0; } else if (fastcmp(type, "MT")) { - for (i = MT_FIRSTFREESLOT; i < NUMMOBJTYPES; i++) - if (!mobjinfo[i].nameofs) { - CONS_Printf("MobjType MT_%s allocated.\n",word); - mobjinfo[i].nameofs = strbuf_append(&mobjnames, word); - mobjinfo[i].namehash = HASH32(word, strlen(word)); - nummobjtypes++; - freeslotusage[1][0]++; - *out = i; - return 0; - } - CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); - return -1; + if (nummobjtypes == NUMMOBJTYPES) { + CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); + return -1; + } + CONS_Printf("MobjType MT_%s allocated.\n",word); + DEH_Link(word, &mobjinfo[nummobjtypes].info, &mobjnames); + *out = nummobjtypes++; + freeslotusage[1][0]++; + return 0; } else if (fastcmp(type, "SKINCOLOR")) { - for (i = SKINCOLOR_FIRSTFREESLOT; i < MAXSKINCOLORS; i++) - if (!skincolors[i].nameofs) { - CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); - skincolors[i].nameofs = strbuf_append(&skincolornames, word); - skincolors[i].namehash = HASH32(word, strlen(word)); - M_AddMenuColor(numskincolors++); - K_ReloadHUDColorCvar(); - *out = i; - return 0; - } - CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); - return -1; + if (numskincolors == MAXSKINCOLORS) { + CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); + return -1; + } + CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); + DEH_Link(word, &skincolors[numskincolors].info, &skincolornames); + M_AddMenuColor(numskincolors); + K_ReloadHUDColorCvar(); + *out = numskincolors++; + return 0; } else if (fastcmp(type, "SPR2")) { @@ -325,18 +323,14 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "MN")) { - for (i = MN_FIRSTFREESLOT; i < MAXMENUTYPES; i++) { - if (!menudefs[i].nameofs) { - CONS_Printf("Menu MN_%s allocated.\n",word); - menudefs[i].nameofs = strbuf_append(&menunames, word); - menudefs[i].namehash = HASH32(word, strlen(word)); - nummenutypes++; - *out = i; - return 0; - } + if (nummenutypes == MAXMENUTYPES) { + CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n"); + return -1; } - CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n"); - return -1; + CONS_Printf("Menu MN_%s allocated.\n",word); + DEH_Link(word, &menudefs[nummenutypes].info, &menunames); + *out = nummenutypes++; + return 0; } return -2; diff --git a/src/dehacked.h b/src/dehacked.h index 3948bbfeb..0ea22c387 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -19,20 +19,15 @@ extern "C" { #endif -typedef enum +struct dehinfo_t { - UNDO_NONE = 0x00, - UNDO_NEWLINE = 0x01, - UNDO_SPACE = 0x02, - UNDO_CUTLINE = 0x04, - UNDO_HEADER = 0x07, - UNDO_ENDTEXT = 0x08, - UNDO_TODO = 0, - UNDO_DONE = 0, -} undotype_f; + UINT32 namehash; // excluding prefix (no MT_ or S_) + UINT32 nameofs; // into strbuf_t +}; void DEH_LoadDehackedLump(lumpnum_t lumpnum); void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile); +void DEH_Link(const char *name, dehinfo_t *info, strbuf_t **buf); INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out); // SRB2Kart diff --git a/src/info.c b/src/info.c index c7c4ef776..b1b532cb7 100644 --- a/src/info.c +++ b/src/info.c @@ -153,10 +153,8 @@ void P_ResetData(INT32 flags) Z_Free(statenames); statenames = strbuf_alloc(); name = hardcodestates; - for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) { - states[i].nameofs = strbuf_append(&statenames, name); - states[i].namehash = HASH32(name, strlen(name)); - } + for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1) + DEH_Link(name, &states[i].info, &statenames); if (!init) { @@ -177,10 +175,8 @@ void P_ResetData(INT32 flags) Z_Free(mobjnames); mobjnames = strbuf_alloc(); name = hardcodemobjs; - for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1) { - mobjinfo[i].nameofs = strbuf_append(&mobjnames, name); - mobjinfo[i].namehash = HASH32(name, strlen(name)); - } + for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1) + DEH_Link(name, &mobjinfo[i].info, &mobjnames); for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++) mobjinfo[i].doomednum = -1; @@ -204,10 +200,8 @@ void P_ResetData(INT32 flags) Z_Free(skincolornames); skincolornames = strbuf_alloc(); name = hardcodeskincolors; - for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) { - skincolors[i].nameofs = strbuf_append(&skincolornames, name); - skincolors[i].namehash = HASH32(name, strlen(name)); - } + for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1) + DEH_Link(name, &skincolors[i].info, &skincolornames); for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) { @@ -235,9 +229,7 @@ void P_ResetData(INT32 flags) Z_Free(menunames); menunames = strbuf_alloc(); name = hardcodemenus; - for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1) { - menudefs[i].nameofs = strbuf_append(&menunames, name); - menudefs[i].namehash = HASH32(name, strlen(name)); - } + for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1) + DEH_Link(name, &menudefs[i].info, &menunames); } } diff --git a/src/info.h b/src/info.h index 9b40b7e1d..a1740d7af 100644 --- a/src/info.h +++ b/src/info.h @@ -18,6 +18,7 @@ #include "d_think.h" #include "sounds.h" #include "m_fixed.h" +#include "dehacked.h" #ifdef __cplusplus extern "C" { @@ -79,8 +80,7 @@ typedef enum state struct state_t { - UINT32 namehash, nameofs; - + dehinfo_t info; spritenum_t sprite; UINT32 frame; // we use the upper 16 bits for translucency and other shade effects INT32 tics; @@ -110,8 +110,7 @@ typedef enum mobj_type struct mobjinfo_t { - UINT32 namehash, nameofs; - + dehinfo_t info; INT32 doomednum; statenum_t spawnstate; INT32 spawnhealth; @@ -157,8 +156,7 @@ typedef enum struct skincolor_t { - UINT32 namehash; // Hash for internal name - UINT32 nameofs; // Offset for internal name + dehinfo_t info; // Internal name hash and offset char name[MAXCOLORNAME+1]; // Skincolor name UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp UINT16 invcolor; // Signpost color diff --git a/src/lua_infolib.c b/src/lua_infolib.c index bc2c3611b..5fa291cf9 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -752,13 +752,8 @@ static int lib_setState(lua_State *L) return luaL_error(L, "Do not alter states in CMD building code!"); // clear the state to start with, in case of missing table elements - state->sprite = SPR_NULL; - state->frame = 0; + memset((char *)state + sizeof(dehinfo_t), 0, sizeof(*state) - sizeof(dehinfo_t)); state->tics = -1; - state->action.acp1 = NULL; - state->var1 = 0; - state->var2 = 0; - state->nextstate = S_NULL; lua_pushnil(L); while (lua_next(L, 1)) { @@ -1112,30 +1107,9 @@ static int lib_setMobjInfo(lua_State *L) return luaL_error(L, "Do not alter mobjinfo in CMD building code!"); // clear the mobjinfo to start with, in case of missing table elements + memset((char *)info + sizeof(dehinfo_t), 0, sizeof(*info) - sizeof(dehinfo_t)); info->doomednum = -1; // default to no editor value - info->spawnstate = S_NULL; info->spawnhealth = 1; // avoid 'dead' noclip behaviors - info->seestate = S_NULL; - info->seesound = sfx_None; - info->reactiontime = 0; - info->attacksound = sfx_None; - info->painstate = S_NULL; - info->painchance = 0; - info->painsound = sfx_None; - info->meleestate = S_NULL; - info->missilestate = S_NULL; - info->deathstate = S_NULL; - info->xdeathstate = S_NULL; - info->deathsound = sfx_None; - info->speed = 0; - info->radius = 0; - info->height = 0; - info->dispoffset = 0; - info->mass = 0; - info->damage = 0; - info->activesound = sfx_None; - info->flags = 0U; - info->raisestate = S_NULL; lua_pushnil(L); while (lua_next(L, 1)) { @@ -1683,7 +1657,7 @@ static int lib_setSkinColor(lua_State *L) return luaL_error(L, "Do not alter skincolors in CMD building code!"); // clear the skincolor to start with, in case of missing table elements - memset(info,0,sizeof(skincolor_t)); + memset((char *)info + sizeof(dehinfo_t), 0, sizeof(*info) - sizeof(dehinfo_t)); Color_cons_t[cnum].value = cnum; lua_pushnil(L); @@ -1925,7 +1899,7 @@ static int lib_setPrecipProps(lua_State *L) // clear the precipprops to start with, in case of missing table elements // make sure we do not clear the name - memset(props + sizeof(props->name), 0, sizeof(precipprops_t) - sizeof(props->name)); + memset((char *)props + sizeof(props->name), 0, sizeof(*props) - sizeof(props->name)); lua_pushnil(L); while (lua_next(L, 1)) { diff --git a/src/m_menu.h b/src/m_menu.h index f1291f28f..c23ac4e0b 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -247,7 +247,7 @@ struct menuitem_t struct menu_t { - UINT32 namehash, nameofs; + dehinfo_t info; const char *headerpic; INT16 numitems; // # of menu items menuitem_t *menuitems; // menu items diff --git a/src/typedef.h b/src/typedef.h index 312eaff03..3afae55f4 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -88,6 +88,7 @@ TYPEDEF (ticcmd_t); TYPEDEF (actionpointer_t); // dehacked.h +TYPEDEF (dehinfo_t); TYPEDEF (MYFILE); // domdata.h From f5b779c7db0d685c797189e9829642903d6201c3 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 19 May 2025 18:22:34 +0200 Subject: [PATCH 14/15] Avoid duplicating freeslots and clean up lua_infolib --- src/dehacked.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 71d1cd9ad..eb1b3fecd 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -220,6 +220,10 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "S")) { + *out = DEH_FindState(word); + if (*out != NUMSTATES) + return 0; // already allocated + if (numstates == NUMSTATES) { CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n"); return -1; @@ -232,6 +236,10 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "MT")) { + *out = DEH_FindMobjtype(word); + if (*out != NUMMOBJTYPES) + return 0; // already allocated + if (nummobjtypes == NUMMOBJTYPES) { CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); return -1; @@ -244,6 +252,10 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "SKINCOLOR")) { + *out = DEH_FindSkincolor(word); + if (*out != MAXSKINCOLORS) + return 0; // already allocated + if (numskincolors == MAXSKINCOLORS) { CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); return -1; @@ -323,6 +335,10 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "MN")) { + *out = DEH_FindMenutype(word); + if (*out != MAXMENUTYPES) + return 0; // already allocated + if (nummenutypes == MAXMENUTYPES) { CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n"); return -1; From 4d2dc53972295118df491523e53732a019da17aa Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 19 May 2025 19:36:49 +0200 Subject: [PATCH 15/15] Fix warnings --- src/doomdef.h | 2 +- src/info.c | 4 ++-- src/info.h | 4 ++-- src/m_menu.c | 2 +- src/m_menu.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index d4658569b..da551b5b2 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -211,7 +211,7 @@ extern char logfilename[1024]; #define COLORRAMPSIZE 16 #define MAXCOLORNAME 32 -#define NUMCOLORFREESLOTS UINT16_MAX +#define NUMCOLORFREESLOTS 32768 // surely nobody's gonna change the palette a second time :Clueless: #define FADECOLOR 0 // 120 diff --git a/src/info.c b/src/info.c index b1b532cb7..824253974 100644 --- a/src/info.c +++ b/src/info.c @@ -81,10 +81,10 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = { // Doesn't work with g++, needs actionf_p1 (don't modify this comment) state_t states[NUMSTATES] = {0}; -size_t numstates; +UINT16 numstates; mobjinfo_t mobjinfo[NUMMOBJTYPES] = {0}; -size_t nummobjtypes; +UINT16 nummobjtypes; skincolor_t skincolors[MAXSKINCOLORS] = {0}; diff --git a/src/info.h b/src/info.h index a1740d7af..547fced8c 100644 --- a/src/info.h +++ b/src/info.h @@ -91,7 +91,7 @@ struct state_t }; extern state_t states[NUMSTATES]; -extern size_t numstates; +extern UINT16 numstates; extern char sprnames[NUMSPRITES + 1][5]; extern char spr2names[NUMPLAYERSPRITES][5]; extern playersprite_t spr2defaults[NUMPLAYERSPRITES]; @@ -138,7 +138,7 @@ struct mobjinfo_t }; extern mobjinfo_t mobjinfo[NUMMOBJTYPES]; -extern size_t nummobjtypes; +extern UINT16 nummobjtypes; typedef enum { diff --git a/src/m_menu.c b/src/m_menu.c index 8c7281e8a..3bfa6e73c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -167,7 +167,7 @@ static UINT32 serverlistpage; INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? menu_t menudefs[MAXMENUTYPES]; // array of all menudefs -size_t nummenutypes; +UINT16 nummenutypes; menutype_t menustack[NUMMENULEVELS]; // stack of active menus, [0] == current menu static menu_t *currentMenu; // current menudef static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 diff --git a/src/m_menu.h b/src/m_menu.h index c23ac4e0b..55b065258 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -258,7 +258,7 @@ struct menu_t }; extern menu_t menudefs[MAXMENUTYPES]; -extern size_t nummenutypes; +extern UINT16 nummenutypes; void M_EnterMenu(menutype_t menu, boolean callexit); void M_ExitMenu(void);