diff --git a/src/command.c b/src/command.c index c37b8f1d3..f19bb89c6 100644 --- a/src/command.c +++ b/src/command.c @@ -1165,6 +1165,39 @@ void VS_Print(vsbuf_t *buf, const char *data) // // ========================================================================= +#define NAME cvar_map_t +#define KEY_TY const char * +#define VAL_TY consvar_t * +#define HASH_FN vt_hash_string +#define CMPR_FN vt_cmpr_string +#include "verstable.h" + +#define NAME netvar_map_t +#define KEY_TY UINT16 +#define VAL_TY consvar_t * +#define HASH_FN vt_hash_integer +#define CMPR_FN vt_cmpr_integer +#include "verstable.h" + +static cvar_map_t cvar_map; +static netvar_map_t netvar_map; + +CONSTRUCTOR static void CV_InitMap(void) +{ + // ensure the map is initialized + cvar_map_t_init(&cvar_map); + cvar_map_t_reserve(&cvar_map, 512); + + netvar_map_t_init(&netvar_map); + netvar_map_t_reserve(&netvar_map, 256); +} + +DESTRUCTOR static void CV_DestroyMap(void) +{ + cvar_map_t_cleanup(&cvar_map); + netvar_map_t_cleanup(&netvar_map); +} + static const char *cv_null_string = ""; /** Searches if a variable has been registered. @@ -1175,11 +1208,17 @@ static const char *cv_null_string = ""; */ consvar_t *CV_FindVar(const char *name) { - consvar_t *cvar; + cvar_map_t_itr it = cvar_map_t_get(&cvar_map, name); + if (!cvar_map_t_is_end(it)) + return it.data->val; + // fallback linear search + /* + consvar_t *cvar; for (cvar = consvar_vars; cvar; cvar = cvar->next) if (fasticmp(name, cvar->name)) return cvar; + */ return NULL; } @@ -1213,11 +1252,17 @@ static inline UINT16 CV_ComputeNetid(const char *s) */ static consvar_t *CV_FindNetVar(UINT16 netid) { + netvar_map_t_itr it = netvar_map_t_get(&netvar_map, netid); + if (!netvar_map_t_is_end(it)) + return it.data->val; + + /* consvar_t *cvar; for (cvar = consvar_vars; cvar; cvar = cvar->next) if (cvar->netid == netid) return cvar; + */ if (netid == 44542) // ouch this hack return &cv_karteliminatelast; @@ -1283,6 +1328,11 @@ void CV_RegisterVar(consvar_t *variable) // the SetValue will set this bit variable->flags &= ~CV_MODIFIED; + + cvar_map_t_insert(&cvar_map, variable->name, variable); + + if (variable->flags & CV_NETVAR) + netvar_map_t_insert(&netvar_map, variable->netid, variable); } /** Finds the string value of a console variable. @@ -1588,9 +1638,21 @@ size_t CV_LoadNetVars(const UINT8 *bufstart) // prevent "invalid command received" serverloading = true; + // we can use our netvar map instead of going through all cvars each time + netvar_map_t_itr it; + for (it = netvar_map_t_first(&netvar_map); + !netvar_map_t_is_end(it); + it = netvar_map_t_next(it)) + { + cvar = it.data->val; + Setvalue(cvar, cvar->defaultvalue, true); + } + + /* for (cvar = consvar_vars; cvar; cvar = cvar->next) if (cvar->flags & CV_NETVAR) Setvalue(cvar, cvar->defaultvalue, true); + */ count = READUINT16(p); while (count--) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index ddc17d6a5..f6450134c 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1384,7 +1384,6 @@ static void I_Fork(void) INT32 I_StartupSystem(void) { - W_Startup(); I_StartupConsole(); #ifdef NEWSIGNALHANDLER // This is useful when debugging. It lets GDB attach to diff --git a/src/doomdef.h b/src/doomdef.h index 445b6951f..1543e68a9 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -573,6 +573,13 @@ INT32 I_GetKey(void); // NOTE: you WILL have nasal troubles if the variable is not initialized #define CLEANUP(f) __attribute__((__cleanup__(f))) +// the GNU constructor and destructor attributes +// The constructor attribute causes the function to be called automatically before execution enters main (). +// Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called. +// Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program. +#define CONSTRUCTOR __attribute__((constructor, used)) +#define DESTRUCTOR __attribute__((destructor, used)) + // An assert-type mechanism. #ifdef PARANOIA #define I_Assert(e) ((e) ? (void)0 : I_Error("assert failed: %s, file %s, line %d", #e, __FILE__, __LINE__)) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 407e5c3a0..c30e93d90 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -1887,8 +1887,6 @@ INT32 I_StartupSystem(void) SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); - W_Startup(); - I_StartupConsole(); #ifdef NEWSIGNALHANDLER // This is useful when debugging. It lets GDB attach to diff --git a/src/w_wad.c b/src/w_wad.c index 2ac8ae68d..8c7494898 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -158,8 +158,7 @@ void W_Shutdown(void) } // the lumpnum cache needs to be initialized before use -// call this as early as possible! -void W_Startup(void) +CONSTRUCTOR static void W_Startup(void) { lumpnum_map_init(&lumpnumcache); lumpnum_map_reserve(&lumpnumcache, LUMPNUMCACHESIZE); @@ -367,7 +366,7 @@ static inline INT32 W_MakeFileMD5(const char *filename, void *resblock) { precise_t t = I_GetPreciseTime(); - CONS_Debug(DBG_SETUP, "Making MD5 for %s\n",filename); + CONS_Debug(DBG_SETUP, "Making MD5 for %s\n", filename); if (md5_stream(fhandle, resblock) == 1) { diff --git a/src/w_wad.h b/src/w_wad.h index ea4a98dd6..474f72c23 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -154,7 +154,6 @@ extern wadfile_t *wadfiles[MAX_WADFILES]; // ========================================================================= -void W_Startup(void); void W_Shutdown(void); // Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened