Fix string autocvars bug in menuqc.

This commit is contained in:
Shpoike 2020-07-19 01:47:06 +01:00
parent f37a1898a9
commit 7191e540a6
4 changed files with 47 additions and 16 deletions

View file

@ -35,7 +35,6 @@ int type_size[8] = {
}; };
static ddef_t *ED_FieldAtOfs (int ofs); static ddef_t *ED_FieldAtOfs (int ofs);
qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s);
cvar_t nomonsters = {"nomonsters", "0", CVAR_NONE}; cvar_t nomonsters = {"nomonsters", "0", CVAR_NONE};
cvar_t gamecfg = {"gamecfg", "0", CVAR_NONE}; cvar_t gamecfg = {"gamecfg", "0", CVAR_NONE};
@ -575,7 +574,7 @@ static void ED_PrintEdict_f (void)
else if (Cmd_Argc() < 4) else if (Cmd_Argc() < 4)
Con_Printf("Edict %u.%s==%s\n", i, PR_GetString(def->s_name), PR_UglyValueString(def->type&~DEF_SAVEGLOBAL, (eval_t *)((char *)&EDICT_NUM(i)->v + def->ofs*4))); Con_Printf("Edict %u.%s==%s\n", i, PR_GetString(def->s_name), PR_UglyValueString(def->type&~DEF_SAVEGLOBAL, (eval_t *)((char *)&EDICT_NUM(i)->v + def->ofs*4)));
else else
ED_ParseEpair((void *)&EDICT_NUM(i)->v, def, Cmd_Argv(3)); ED_ParseEpair((void *)&EDICT_NUM(i)->v, def, Cmd_Argv(3), false);
} }
} }
@ -698,7 +697,7 @@ const char *ED_ParseGlobals (const char *data)
continue; continue;
} }
if (!ED_ParseEpair ((void *)qcvm->globals, key, com_token)) if (!ED_ParseEpair ((void *)qcvm->globals, key, com_token, false))
Host_Error ("ED_ParseGlobals: parse error"); Host_Error ("ED_ParseGlobals: parse error");
} }
return data; return data;
@ -737,7 +736,37 @@ static string_t ED_NewString (const char *string)
return num; return num;
} }
static void ED_RezoneString (string_t *ref, const char *str)
{
char *buf;
size_t len = strlen(str)+1;
size_t id;
if (*ref)
{ //if the reference is already a zoned string then free it first.
id = -1-*ref;
if (id < qcvm->knownzonesize && (qcvm->knownzone[id>>3] & (1u<<(id&7))))
{ //okay, it was zoned.
qcvm->knownzone[id>>3] &= ~(1u<<(id&7));
buf = (char*)PR_GetString(*ref);
PR_ClearEngineString(*ref);
Z_Free(buf);
}
// else
// Con_Warning("ED_RezoneString: string wasn't strzoned\n"); //warnings would trigger from the default cvar value that autocvars are initialised with
}
buf = Z_Malloc(len);
memcpy(buf, str, len);
id = -1-(*ref = PR_SetEngineString(buf));
//make sure its flagged as zoned so we can clean up properly after.
if (id >= qcvm->knownzonesize)
{
qcvm->knownzonesize = (id+32)&~7;
qcvm->knownzone = Z_Realloc(qcvm->knownzone, (qcvm->knownzonesize+7)>>3);
}
qcvm->knownzone[id>>3] |= 1u<<(id&7);
}
/* /*
============= =============
@ -747,7 +776,7 @@ Can parse either fields or globals
returns false if error returns false if error
============= =============
*/ */
qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s) qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s, qboolean zoned)
{ {
int i; int i;
char string[128]; char string[128];
@ -762,6 +791,9 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s)
switch (key->type & ~DEF_SAVEGLOBAL) switch (key->type & ~DEF_SAVEGLOBAL)
{ {
case ev_string: case ev_string:
if (zoned) //zoned version allows us to change the strings more freely
ED_RezoneString((string_t *)d, s);
else
*(string_t *)d = ED_NewString(s); *(string_t *)d = ED_NewString(s);
break; break;
@ -960,7 +992,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
sprintf (com_token, "0 %s 0", temp); sprintf (com_token, "0 %s 0", temp);
} }
if (!ED_ParseEpair ((void *)&ent->v, key, com_token)) if (!ED_ParseEpair ((void *)&ent->v, key, com_token, false))
Host_Error ("ED_ParseEdict: parse error"); Host_Error ("ED_ParseEdict: parse error");
} }

View file

@ -492,7 +492,7 @@ static void PF_strzone(void)
if (id >= qcvm->knownzonesize) if (id >= qcvm->knownzonesize)
{ {
qcvm->knownzonesize = (id+32)&~7; qcvm->knownzonesize = (id+32)&~7;
qcvm->knownzone = Z_Realloc(qcvm->knownzone, qcvm->knownzonesize>>3); qcvm->knownzone = Z_Realloc(qcvm->knownzone, (qcvm->knownzonesize+7)>>3);
} }
qcvm->knownzone[id>>3] |= 1u<<(id&7); qcvm->knownzone[id>>3] |= 1u<<(id&7);
@ -3809,7 +3809,7 @@ static void PF_putentfldstr(void)
edict_t *ent = G_EDICT(OFS_PARM1); edict_t *ent = G_EDICT(OFS_PARM1);
const char *value = G_STRING(OFS_PARM2); const char *value = G_STRING(OFS_PARM2);
if (fldidx < (unsigned int)qcvm->progs->numfielddefs) if (fldidx < (unsigned int)qcvm->progs->numfielddefs)
G_FLOAT(OFS_RETURN) = ED_ParseEpair ((void *)&ent->v, qcvm->fielddefs+fldidx, value); G_FLOAT(OFS_RETURN) = ED_ParseEpair ((void *)&ent->v, qcvm->fielddefs+fldidx, value, true);
else else
G_FLOAT(OFS_RETURN) = false; G_FLOAT(OFS_RETURN) = false;
} }
@ -6645,33 +6645,31 @@ void PR_AutoCvarChanged(cvar_t *var)
glob = ED_FindGlobal(n); glob = ED_FindGlobal(n);
if (glob) if (glob)
{ {
if (!ED_ParseEpair ((void *)qcvm->globals, glob, var->string)) if (!ED_ParseEpair ((void *)qcvm->globals, glob, var->string, true))
Con_Warning("EXT: Unable to configure %s\n", n); Con_Warning("EXT: Unable to configure %s\n", n);
} }
PR_SwitchQCVM(NULL); PR_SwitchQCVM(NULL);
} }
if (cl.qcvm.globals) if (cl.qcvm.globals)
{ {
PR_SwitchQCVM(NULL);
PR_SwitchQCVM(&cl.qcvm); PR_SwitchQCVM(&cl.qcvm);
n = va("autocvar_%s", var->name); n = va("autocvar_%s", var->name);
glob = ED_FindGlobal(n); glob = ED_FindGlobal(n);
if (glob) if (glob)
{ {
if (!ED_ParseEpair ((void *)qcvm->globals, glob, var->string)) if (!ED_ParseEpair ((void *)qcvm->globals, glob, var->string, true))
Con_Warning("EXT: Unable to configure %s\n", n); Con_Warning("EXT: Unable to configure %s\n", n);
} }
PR_SwitchQCVM(NULL); PR_SwitchQCVM(NULL);
} }
if (cls.menu_qcvm.globals) if (cls.menu_qcvm.globals)
{ {
PR_SwitchQCVM(NULL);
PR_SwitchQCVM(&cls.menu_qcvm); PR_SwitchQCVM(&cls.menu_qcvm);
n = va("autocvar_%s", var->name); n = va("autocvar_%s", var->name);
glob = ED_FindGlobal(n); glob = ED_FindGlobal(n);
if (glob) if (glob)
{ {
if (!ED_ParseEpair ((void *)qcvm->globals, glob, var->string)) if (!ED_ParseEpair ((void *)qcvm->globals, glob, var->string, true))
Con_Warning("EXT: Unable to configure %s\n", n); Con_Warning("EXT: Unable to configure %s\n", n);
} }
PR_SwitchQCVM(NULL); PR_SwitchQCVM(NULL);
@ -6806,7 +6804,7 @@ void PR_EnableExtensions(ddef_t *pr_globaldefs)
if (!var) if (!var)
continue; //name conflicts with a command? continue; //name conflicts with a command?
if (!ED_ParseEpair ((void *)qcvm->globals, &pr_globaldefs[i], var->string)) if (!ED_ParseEpair ((void *)qcvm->globals, &pr_globaldefs[i], var->string, true))
Con_Warning("EXT: Unable to configure %s\n", n); Con_Warning("EXT: Unable to configure %s\n", n);
var->flags |= CVAR_AUTOCVAR; var->flags |= CVAR_AUTOCVAR;
} }

View file

@ -84,7 +84,7 @@ int SV_Precache_Sound(const char *s);
void PR_spawnfunc_misc_model(edict_t *self); void PR_spawnfunc_misc_model(edict_t *self);
//from pr_edict, for pr_ext. reflection is messy. //from pr_edict, for pr_ext. reflection is messy.
qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s); qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s, qboolean zoned);
const char *PR_UglyValueString (int type, eval_t *val); const char *PR_UglyValueString (int type, eval_t *val);
ddef_t *ED_FindField (const char *name); ddef_t *ED_FindField (const char *name);
ddef_t *ED_FindGlobal (const char *name); ddef_t *ED_FindGlobal (const char *name);

View file

@ -76,7 +76,8 @@ void Z_Free (void *ptr)
memblock_t *block, *other; memblock_t *block, *other;
if (!ptr) if (!ptr)
Sys_Error ("Z_Free: NULL pointer"); return; //ignore this like libc would
// Sys_Error ("Z_Free: NULL pointer");
block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t)); block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
if (block->id != ZONEID) if (block->id != ZONEID)