diff --git a/src/command.c b/src/command.c index 244df5088..5997a4a9b 100644 --- a/src/command.c +++ b/src/command.c @@ -1443,6 +1443,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. @@ -1453,11 +1486,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; } @@ -1484,6 +1523,10 @@ static inline UINT16 CV_ComputeLegacyNetid(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; if (netid > consvar_number_of_netids) @@ -1492,6 +1535,7 @@ static consvar_t *CV_FindNetVar(UINT16 netid) for (cvar = consvar_vars; cvar; cvar = cvar->next) if (cvar->netid == netid) return cvar; + */ if (netid == 44542) // ouch this hack return &cv_karteliminatelast; @@ -1585,6 +1629,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. @@ -1971,6 +2020,25 @@ static void CV_LoadVars(UINT8 **p, // 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; + + if (store && cvar->revert.v.string == NULL) + { + cvar->revert.v.const_munge = cvar->string; + cvar->revert.allocated = ( cvar->zstring != NULL ); + cvar->zstring = NULL; // don't free this + } + + Setvalue(cvar, cvar->defaultvalue, true); + } + + /* for (cvar = consvar_vars; cvar; cvar = cvar->next) { if (cvar->flags & CV_NETVAR) @@ -1979,12 +2047,12 @@ static void CV_LoadVars(UINT8 **p, { cvar->revert.v.const_munge = cvar->string; cvar->revert.allocated = ( cvar->zstring != NULL ); - cvar->zstring = NULL;/* don't free this */ + cvar->zstring = NULL; // don't free this } Setvalue(cvar, cvar->defaultvalue, true); } - } + }*/ if (got == NULL) G_LoadDemoCvars((void **)p, Setvalue); diff --git a/src/doomdef.h b/src/doomdef.h index 70e783b97..97d89e277 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -440,6 +440,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. // NOTE: USE SRB2_ASSERT FOR C++ CODE INSTEAD #ifdef PARANOIA diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 7f10c82e2..c7d6eabf7 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -1364,7 +1364,6 @@ static void I_Fork(void) INT32 I_StartupSystem(void) { int SDLlinked = SDL_GetVersion(); - 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 bca038ca7..74568c9b2 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -155,8 +155,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); diff --git a/src/w_wad.h b/src/w_wad.h index bdf78f5a0..c6b8ef164 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -152,7 +152,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