]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cvar.c
reworked the entire config loading system for the gamedir command
[xonotic/darkplaces.git] / cvar.c
diff --git a/cvar.c b/cvar.c
index 8d5af144ee6a2b09c8be09485c9b6d910dff9f62..221a52447da5acea64cfb4ab5f2b04460c8dd2ca 100644 (file)
--- a/cvar.c
+++ b/cvar.c
@@ -557,7 +557,6 @@ cvar_t *Cvar_Get (const char *name, const char *value, int flags, const char *ne
 {
        int hashindex;
        cvar_t *current, *next, *cvar;
-       size_t alloclen;
 
        if (developer_extra.integer)
                Con_DPrintf("Cvar_Get(\"%s\", \"%s\", %i);\n", name, value, flags);
@@ -574,11 +573,7 @@ cvar_t *Cvar_Get (const char *name, const char *value, int flags, const char *ne
                                Z_Free((char *)cvar->description);
 
                        if(*newdescription)
-                       {
-                               alloclen = strlen(newdescription) + 1;
-                               cvar->description = (char *)Z_Malloc(alloclen);
-                               memcpy((char *)cvar->description, newdescription, alloclen);
-                       }
+                               cvar->description = (char *)Mem_strdup(zonemempool, newdescription);
                        else
                                cvar->description = cvar_dummy_description;
                }
@@ -604,23 +599,14 @@ cvar_t *Cvar_Get (const char *name, const char *value, int flags, const char *ne
 // FIXME: these never get Z_Free'd
        cvar = (cvar_t *)Z_Malloc(sizeof(cvar_t));
        cvar->flags = flags | CVAR_ALLOCATED;
-       alloclen = strlen(name) + 1;
-       cvar->name = (char *)Z_Malloc(alloclen);
-       memcpy((char *)cvar->name, name, alloclen);
-       alloclen = strlen(value) + 1;
-       cvar->string = (char *)Z_Malloc(alloclen);
-       memcpy((char *)cvar->string, value, alloclen);
-       cvar->defstring = (char *)Z_Malloc(alloclen);
-       memcpy((char *)cvar->defstring, value, alloclen);
+       cvar->name = (char *)Mem_strdup(zonemempool, name);
+       cvar->string = (char *)Mem_strdup(zonemempool, value);
+       cvar->defstring = (char *)Mem_strdup(zonemempool, value);
        cvar->value = atof (cvar->string);
        cvar->integer = (int) cvar->value;
 
        if(newdescription && *newdescription)
-       {
-               alloclen = strlen(newdescription) + 1;
-               cvar->description = (char *)Z_Malloc(alloclen);
-               memcpy((char *)cvar->description, newdescription, alloclen);
-       }
+               cvar->description = (char *)Mem_strdup(zonemempool, newdescription);
        else
                cvar->description = cvar_dummy_description; // actually checked by VM_cvar_type
 
@@ -710,6 +696,84 @@ void Cvar_LockDefaults_f (void)
        }
 }
 
+void Cvar_SaveInitState(void)
+{
+       cvar_t *c;
+       for (c = cvar_vars;c;c = c->next)
+       {
+               c->initstate = true;
+               c->initflags = c->flags;
+               c->initdefstring = Mem_strdup(zonemempool, c->defstring);
+               c->initstring = Mem_strdup(zonemempool, c->string);
+               c->initvalue = c->value;
+               c->initinteger = c->integer;
+               VectorCopy(c->vector, c->initvector);
+       }
+}
+
+void Cvar_RestoreInitState(void)
+{
+       int hashindex;
+       cvar_t *c, **cp;
+       cvar_t *c2, **cp2;
+       for (cp = &cvar_vars;(c = *cp);)
+       {
+               if (c->initstate)
+               {
+                       // restore this cvar, it existed at init
+                       if (((c->flags ^ c->initflags) & CVAR_MAXFLAGSVAL)
+                        || strcmp(c->defstring ? c->defstring : "", c->initdefstring ? c->initdefstring : "")
+                        || strcmp(c->string ? c->string : "", c->initstring ? c->initstring : ""))
+                       {
+                               Con_DPrintf("Cvar_RestoreInitState: Restoring cvar \"%s\"\n", c->name);
+                               if (c->defstring)
+                                       Z_Free((char *)c->defstring);
+                               c->defstring = Mem_strdup(zonemempool, c->initdefstring);
+                               if (c->string)
+                                       Z_Free((char *)c->string);
+                               c->string = Mem_strdup(zonemempool, c->initstring);
+                       }
+                       c->flags = c->initflags;
+                       c->value = c->initvalue;
+                       c->integer = c->initinteger;
+                       VectorCopy(c->initvector, c->vector);
+                       cp = &c->next;
+               }
+               else
+               {
+                       if (!(c->flags & CVAR_ALLOCATED))
+                       {
+                               Con_DPrintf("Cvar_RestoreInitState: Unable to destroy cvar \"%s\", it was registered after init!\n", c->name);
+                               continue;
+                       }
+                       // remove this cvar, it did not exist at init
+                       Con_DPrintf("Cvar_RestoreInitState: Destroying cvar \"%s\"\n", c->name);
+                       // unlink struct from hash
+                       hashindex = CRC_Block((const unsigned char *)c->name, strlen(c->name)) % CVAR_HASHSIZE;
+                       for (cp2 = &cvar_hashtable[hashindex];(c2 = *cp2);)
+                       {
+                               if (c2 == c)
+                               {
+                                       *cp2 = c2->nextonhashchain;
+                                       break;
+                               }
+                               else
+                                       cp2 = &c2->next;
+                       }
+                       // unlink struct from main list
+                       *cp = c->next;
+                       // free strings
+                       if (c->defstring)
+                               Z_Free((char *)c->defstring);
+                       if (c->string)
+                               Z_Free((char *)c->string);
+                       if (c->description && c->description != cvar_dummy_description)
+                               Z_Free((char *)c->description);
+                       // free struct
+                       Z_Free(c);
+               }
+       }
+}
 
 void Cvar_ResetToDefaults_All_f (void)
 {