From 71e075efa49758f4fd21831973fb0d8e4d6938c8 Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 17 Sep 2004 21:25:04 +0000 Subject: [PATCH] added set (create/set a cvar) and seta (create/set a saved cvar) commands, now config saving uses seta, and this allows mods to add their own cvars in default.cfg easily cleaned up some of the command/cvar startup sequence, the menu commands and cvars were being registered AFTER config loading and video init, now they're registered before like they should be cleaned up some cvar code and added developer printing of the more important cvar calls git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4514 d7cf8633-e32d-0410-b094-e92efae38249 --- cmd.c | 4 +- cvar.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++------ cvar.h | 14 +++- host.c | 1 + menu.c | 5 +- menu.h | 1 + pr_cmds.c | 18 +---- prvm_cmds.c | 21 +----- 8 files changed, 196 insertions(+), 59 deletions(-) diff --git a/cmd.c b/cmd.c index 41a68f58..2e1323a4 100644 --- a/cmd.c +++ b/cmd.c @@ -455,6 +455,8 @@ void Cmd_Init (void) Cmd_AddCommand ("cmdlist", Cmd_List_f); // Added/Modified by EvilTypeGuy eviltypeguy@qeradiant.com Cmd_AddCommand ("cvarlist", Cvar_List_f); // 2000-01-09 CmdList, CvarList commands // By Matthias "Maddes" Buecher + Cmd_AddCommand ("set", Cvar_Set_f); + Cmd_AddCommand ("seta", Cvar_SetA_f); } /* @@ -781,7 +783,7 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src) } // check functions (only after host_initialized) - if (host_initialized || !strcasecmp(cmd_argv[0], "exec")) + if (host_initialized || !strcasecmp(cmd_argv[0], "exec") || !strcasecmp(cmd_argv[0], "set") || !strcasecmp(cmd_argv[0], "seta")) { for (cmd=cmd_functions ; cmd ; cmd=cmd->next) { diff --git a/cvar.c b/cvar.c index 98a7207e..2de6617f 100644 --- a/cvar.c +++ b/cvar.c @@ -34,7 +34,7 @@ cvar_t *Cvar_FindVar (const char *var_name) cvar_t *var; for (var = cvar_vars;var;var = var->next) - if (!strcmp (var_name, var->name)) + if (!strcasecmp (var_name, var->name)) return var; return NULL; @@ -113,7 +113,7 @@ const char *Cvar_CompleteVariable (const char *partial) // check functions for (cvar=cvar_vars ; cvar ; cvar=cvar->next) - if (!strncmp (partial,cvar->name, len)) + if (!strncasecmp (partial,cvar->name, len)) return cvar->name; return NULL; @@ -181,16 +181,10 @@ const char **Cvar_CompleteBuildList (const char *partial) Cvar_Set ============ */ -void Cvar_SetQuick (cvar_t *var, const char *value) +void Cvar_SetQuick_Internal (cvar_t *var, const char *value) { qboolean changed; - if (var == NULL) - { - Con_Print("Cvar_SetQuick: var == NULL\n"); - return; - } - changed = strcmp(var->string, value); // LordHavoc: don't reallocate when there is no change if (!changed) @@ -210,22 +204,29 @@ void Cvar_SetQuick (cvar_t *var, const char *value) SV_BroadcastPrintf("\"%s\" changed to \"%s\"\n", var->name, var->string); } +void Cvar_SetQuick (cvar_t *var, const char *value) +{ + if (var == NULL) + { + Con_Print("Cvar_SetQuick: var == NULL\n"); + return; + } + + if (developer.integer) + Con_Printf("Cvar_SetQuick({\"%s\", \"%s\", %i}, \"%s\");\n", var->name, var->string, var->flags, value); + + Cvar_SetQuick_Internal(var, value); +} + void Cvar_Set (const char *var_name, const char *value) { cvar_t *var; var = Cvar_FindVar (var_name); if (var == NULL) { - // there is an error in C code if this happens Con_Printf("Cvar_Set: variable %s not found\n", var_name); return; } - if (var->flags & CVAR_READONLY) - { - Con_Printf("Cvar_Set: %s is read-only\n", var_name); - return; - } - Cvar_SetQuick(var, value); } @@ -265,12 +266,51 @@ Adds a freestanding variable to the variable list. */ void Cvar_RegisterVariable (cvar_t *variable) { - char *oldstr; + cvar_t *cvar, *cvar2; + char *oldstr; + + if (developer.integer) + Con_Printf("Cvar_RegisterVariable({\"%s\", \"%s\", %i});\n", variable->name, variable->string, variable->flags); // first check to see if it has already been defined - if (Cvar_FindVar (variable->name)) + cvar = Cvar_FindVar (variable->name); + if (cvar) { - Con_Printf("Can't register variable %s, already defined\n", variable->name); + if (cvar->flags & CVAR_ALLOCATED) + { + if (developer.integer) + Con_Printf("... replacing existing allocated cvar {\"%s\", \"%s\", %i}", cvar->name, cvar->string, cvar->flags); + // fixed variables replace allocated ones + // (because the engine directly accesses fixed variables) + // NOTE: this isn't actually used currently + // (all cvars are registered before config parsing) + variable->flags |= (cvar->flags & ~CVAR_ALLOCATED); + // cvar->string is now owned by variable instead + variable->string = cvar->string; + variable->value = atof (variable->string); + variable->integer = (int) variable->value; + // replace cvar with this one... + variable->next = cvar->next; + if (cvar_vars == cvar) + { + // head of the list is easy to change + cvar_vars = variable; + } + else + { + // otherwise find it somewhere in the list + for (cvar2 = cvar_vars;cvar2->next != cvar;cvar2 = cvar2->next); + if (cvar2->next == cvar) + cvar2->next = variable; + } + + // get rid of old allocated cvar + // (but not the cvar->string, because we kept that) + Z_Free(cvar->name); + Z_Free(cvar); + } + else + Con_Printf("Can't register variable %s, already defined\n", variable->name); return; } @@ -293,6 +333,54 @@ void Cvar_RegisterVariable (cvar_t *variable) cvar_vars = variable; } +/* +============ +Cvar_Get + +Adds a newly allocated variable to the variable list or sets its value. +============ +*/ +cvar_t *Cvar_Get (const char *name, const char *value, int flags) +{ + cvar_t *cvar; + + if (developer.integer) + Con_Printf("Cvar_Get(\"%s\", \"%s\", %i);\n", name, value, flags); + +// first check to see if it has already been defined + cvar = Cvar_FindVar (name); + if (cvar) + { + cvar->flags |= flags; + Cvar_SetQuick_Internal (cvar, value); + return cvar; + } + +// check for overlap with a command + if (Cmd_Exists (name)) + { + Con_Printf("Cvar_Get: %s is a command\n", name); + return NULL; + } + +// allocate a new cvar, cvar name, and cvar string +// FIXME: these never get Z_Free'd + cvar = Z_Malloc(sizeof(cvar_t)); + cvar->flags = flags | CVAR_ALLOCATED; + cvar->name = Z_Malloc(strlen(name)+1); + strcpy(cvar->name, name); + cvar->string = Z_Malloc(strlen(value)+1); + strcpy(cvar->string, value); + cvar->value = atof (cvar->string); + cvar->integer = (int) cvar->value; + +// link the variable in + cvar->next = cvar_vars; + cvar_vars = cvar; + return cvar; +} + + /* ============ Cvar_Command @@ -318,6 +406,14 @@ qboolean Cvar_Command (void) return true; } + if (developer.integer) + Con_Print("Cvar_Command: "); + + if (v->flags & CVAR_READONLY) + { + Con_Printf("%s is read-only\n", v->name); + return true; + } Cvar_Set (v->name, Cmd_Argv(1)); return true; } @@ -337,7 +433,7 @@ void Cvar_WriteVariables (qfile_t *f) for (var = cvar_vars ; var ; var = var->next) if (var->flags & CVAR_SAVE) - FS_Printf(f, "%s \"%s\"\n", var->name, var->string); + FS_Printf(f, "seta %s \"%s\"\n", var->name, var->string); } @@ -368,7 +464,7 @@ void Cvar_List_f (void) count = 0; for (cvar = cvar_vars; cvar; cvar = cvar->next) { - if (partial && strncmp (partial,cvar->name,len)) + if (partial && strncasecmp (partial,cvar->name,len)) continue; Con_Printf("%s is \"%s\"\n", cvar->name, cvar->string); @@ -382,3 +478,56 @@ void Cvar_List_f (void) } // 2000-01-09 CvarList command by Maddes +void Cvar_Set_f (void) +{ + cvar_t *cvar; + + // make sure it's the right number of parameters + if (Cmd_Argc() < 3) + { + Con_Printf("Set: wrong number of parameters, usage: set \n"); + return; + } + + // check if it's read-only + cvar = Cvar_FindVar(Cmd_Argv(1)); + if (cvar && cvar->flags & CVAR_READONLY) + { + Con_Printf("Set: %s is read-only\n", cvar->name); + return; + } + + if (developer.integer) + Con_Print("Set: "); + + // all looks ok, create/modify the cvar + Cvar_Get(Cmd_Argv(1), Cmd_Argv(2), 0); +} + +void Cvar_SetA_f (void) +{ + cvar_t *cvar; + + // make sure it's the right number of parameters + if (Cmd_Argc() < 3) + { + Con_Printf("SetA: wrong number of parameters, usage: seta \n"); + return; + } + + // check if it's read-only + cvar = Cvar_FindVar(Cmd_Argv(1)); + if (cvar && cvar->flags & CVAR_READONLY) + { + Con_Printf("SetA: %s is read-only\n", cvar->name); + return; + } + + if (developer.integer) + Con_Print("SetA: "); + + // all looks ok, create/modify the cvar + Cvar_Get(Cmd_Argv(1), Cmd_Argv(2), CVAR_SAVE); +} + + diff --git a/cvar.h b/cvar.h index 0ed510ab..9523404e 100644 --- a/cvar.h +++ b/cvar.h @@ -61,7 +61,10 @@ interface from being ambiguous. #define CVAR_SAVE 1 #define CVAR_NOTIFY 2 #define CVAR_READONLY 4 -#define CVAR_MAXFLAGSVAL 7 // used to determine if flags is valid +// used to determine if flags is valid +#define CVAR_MAXFLAGSVAL 7 +// for internal use only! +#define CVAR_ALLOCATED (1<<31) /* // type of a cvar for menu purposes @@ -166,5 +169,14 @@ void Cvar_List_f (void); // Added by EvilTypeGuy eviltypeguy@qeradiant.com // Thanks to Matthias "Maddes" Buecher, http://www.inside3d.com/qip/ +void Cvar_Set_f (void); +void Cvar_SetA_f (void); +// commands to create new cvars (or set existing ones) +// seta creates an archived cvar (saved to config) + +cvar_t *Cvar_Get (const char *name, const char *value, int flags); +// allocates a cvar by name and returns its address, +// or merely sets its value if it already exists. + #endif diff --git a/host.c b/host.c index ee924867..5cd787a9 100644 --- a/host.c +++ b/host.c @@ -868,6 +868,7 @@ void Host_Init (void) if (cls.state != ca_dedicated) { Palette_Init(); + MR_Init_Commands(); VID_Shared_Init(); VID_Init(); diff --git a/menu.c b/menu.c index 8a1105dc..917374f3 100644 --- a/menu.c +++ b/menu.c @@ -4260,7 +4260,7 @@ void Call_MR_ToggleMenu_f(void) MR_ToggleMenu_f(); } -void MR_Init() +void MR_Init_Commands(void) { // set router console commands Cvar_RegisterVariable (&forceqmenu); @@ -4268,7 +4268,10 @@ void MR_Init() Cmd_AddCommand ("menu_fallback", MP_Error); //Force to old-style menu Cmd_AddCommand ("menu_restart",MR_Restart); Cmd_AddCommand ("togglemenu", Call_MR_ToggleMenu_f); +} +void MR_Init(void) +{ // use -forceqmenu to use always the normal quake menu (it sets forceqmenu to 1) if(COM_CheckParm("-forceqmenu")) Cvar_SetValueQuick(&forceqmenu,1); diff --git a/menu.h b/menu.h index 8b518327..883bfb50 100644 --- a/menu.h +++ b/menu.h @@ -70,6 +70,7 @@ void MP_Shutdown (void);*/ // // menu router // +void MR_Init_Commands (void); void MR_Init (void); void MR_Restart (void); void (*MR_Keydown) (int key, char ascii); diff --git a/pr_cmds.c b/pr_cmds.c index b2268272..89702b38 100644 --- a/pr_cmds.c +++ b/pr_cmds.c @@ -2044,17 +2044,13 @@ void PF_GetLight (void) VectorMA(ambientcolor, 0.5, diffusecolor, G_VECTOR(OFS_RETURN)); } -#define MAX_QC_CVARS 128 -cvar_t qc_cvar[MAX_QC_CVARS]; -int currentqc_cvar; - void PF_registercvar (void) { char *name, *value; - cvar_t *variable; name = G_STRING(OFS_PARM0); value = G_STRING(OFS_PARM1); G_FLOAT(OFS_RETURN) = 0; + // first check to see if it has already been defined if (Cvar_FindVar (name)) return; @@ -2066,18 +2062,8 @@ void PF_registercvar (void) return; } - if (currentqc_cvar >= MAX_QC_CVARS) - PF_ERROR("PF_registercvar: ran out of cvar slots\n"); - -// copy the name and value - variable = &qc_cvar[currentqc_cvar++]; - variable->name = Z_Malloc (strlen(name)+1); - strcpy (variable->name, name); - variable->string = Z_Malloc (strlen(value)+1); - strcpy (variable->string, value); - variable->value = atof (value); + Cvar_Get(name, value, 0); - Cvar_RegisterVariable(variable); G_FLOAT(OFS_RETURN) = 1; // success } diff --git a/prvm_cmds.c b/prvm_cmds.c index 503fafc6..79fee2a8 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -180,11 +180,6 @@ mempool_t *vm_strings_mempool[PRVM_MAXPROGS]; static char vm_string_temp[VM_STRINGTEMP_BUFFERS][VM_STRINGTEMP_LENGTH]; static int vm_string_tempindex = 0; -// qc cvar -#define MAX_QC_CVARS 128 * PRVM_MAXPROGS -cvar_t vm_qc_cvar[MAX_QC_CVARS]; -int vm_currentqc_cvar; - // qc file handling #define MAX_VMFILES 256 #define MAX_PRVMFILES MAX_VMFILES * PRVM_MAXPROGS @@ -1496,8 +1491,7 @@ float registercvar (string name, string value, float flags) void VM_registercvar (void) { char *name, *value; - cvar_t *variable; - int flags; + int flags; VM_SAFEPARMCOUNT(3,VM_registercvar); @@ -1520,19 +1514,8 @@ void VM_registercvar (void) return; } - if (vm_currentqc_cvar >= MAX_QC_CVARS) - PRVM_ERROR ("VM_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS); - -// copy the name and value - variable = &vm_qc_cvar[vm_currentqc_cvar++]; - variable->flags = flags; - variable->name = Z_Malloc (strlen(name)+1); - strcpy (variable->name, name); - variable->string = Z_Malloc (strlen(value)+1); - strcpy (variable->string, value); - variable->value = atof (value); + Cvar_Get(name, value, 0); - Cvar_RegisterVariable(variable); PRVM_G_FLOAT(OFS_RETURN) = 1; // success } -- 2.39.2