+void Cvar_SaveInitState(cvar_state_t *cvars)
+{
+ cvar_t *c;
+ for (c = cvars->vars;c;c = c->next)
+ {
+ c->initstate = (cvar_t *)Z_Malloc(sizeof(cvar_t));
+ memcpy(c->initstate, c, sizeof(cvar_t));
+ }
+}
+
+void Cvar_RestoreInitState(cvar_state_t *cvars)
+{
+ int hashindex;
+ cvar_t *c, **cp;
+ cvar_t *c2, **cp2;
+ for (cp = &cvars->vars;(c = *cp);)
+ {
+ if (c->initstate)
+ {
+ // restore this cvar, it existed at init
+ if (((c->flags ^ c->initstate->flags) & CF_MAXFLAGSVAL)
+ || strcmp(c->defstring ? c->defstring : "", c->initstate->defstring ? c->initstate->defstring : "")
+ || strcmp(c->string ? c->string : "", c->initstate->string ? c->initstate->string : ""))
+ {
+ Con_DPrintf("Cvar_RestoreInitState: Restoring cvar \"%s\"\n", c->name);
+ if (c->defstring)
+ Z_Free((char *)c->defstring);
+ c->defstring = Mem_strdup(zonemempool, c->initstate->defstring);
+ if (c->string)
+ Z_Free((char *)c->string);
+ c->string = Mem_strdup(zonemempool, c->initstate->string);
+ }
+ c->flags = c->initstate->flags;
+ c->value = c->initstate->value;
+ c->integer = c->initstate->integer;
+ VectorCopy(c->initstate->vector, c->vector);
+ cp = &c->next;
+ }
+ else
+ {
+ if (!(c->flags & CF_ALLOCATED))
+ {
+ Con_DPrintf("Cvar_RestoreInitState: Unable to destroy cvar \"%s\", it was registered after init!\n", c->name);
+ // In this case, at least reset it to the default.
+ if((c->flags & CF_PERSISTENT) == 0)
+ Cvar_SetQuick(c, c->defstring);
+ cp = &c->next;
+ continue;
+ }
+ if (Cvar_IsAutoCvar(c))
+ {
+ Con_DPrintf("Cvar_RestoreInitState: Unable to destroy cvar \"%s\", it is an autocvar used by running progs!\n", c->name);
+ // In this case, at least reset it to the default.
+ if((c->flags & CF_PERSISTENT) == 0)
+ Cvar_SetQuick(c, c->defstring);
+ cp = &c->next;
+ 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 = &cvars->hashtable[hashindex]->cvar;(c2 = *cp2);)
+ {
+ if (c2 == c)
+ {
+ *cp2 = cvars->hashtable[hashindex]->next->cvar;
+ break;
+ }
+ else
+ cp2 = &cvars->hashtable[hashindex]->next->cvar;
+ }
+ // 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);
+ }
+ }
+}