From 7552885ae0db4b06e323f60ad00e43274adcdd61 Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 5 Dec 2009 15:33:56 +0000 Subject: [PATCH] DP_QC_AUTOCVARS: declare a QC variable float/vector/string autocvar_foo, and it will always reflect the cvar "foo" when read git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9538 d7cf8633-e32d-0410-b094-e92efae38249 --- cvar.c | 45 ++++++++++++++++++++++++++++ cvar.h | 4 +++ mvm_cmds.c | 1 + progsvm.h | 2 ++ prvm_edict.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ svvm_cmds.c | 1 + 6 files changed, 135 insertions(+) diff --git a/cvar.c b/cvar.c index 111550a8..30ba09fd 100644 --- a/cvar.c +++ b/cvar.c @@ -233,6 +233,8 @@ void Cvar_SetQuick_Internal (cvar_t *var, const char *value) { qboolean changed; size_t valuelen; + prvm_prog_t *tmpprog; + int i; changed = strcmp(var->string, value) != 0; // LordHavoc: don't reallocate when there is no change @@ -305,6 +307,49 @@ void Cvar_SetQuick_Internal (cvar_t *var, const char *value) else if (!strcmp(var->name, "net_slist_favorites")) NetConn_UpdateFavorites(); } + + tmpprog = prog; + for(i = 0; i < PRVM_MAXPROGS; ++i) + { + if(PRVM_ProgLoaded(i)) + { + PRVM_SetProg(i); + if(var->globaldefindex_progid[i] == prog->id) + { + // MUST BE SYNCED WITH prvm_edict.c PRVM_LoadProgs + int j; + const char *s; + prvm_eval_t *val = (prvm_eval_t *)(prog->globals.generic + prog->globaldefs[var->globaldefindex[i]].ofs); + switch(prog->globaldefs[var->globaldefindex[i]].type & ~DEF_SAVEGLOBAL) + { + case ev_float: + val->_float = var->value; + break; + case ev_vector: + s = var->string; + VectorClear(val->vector); + for (j = 0;j < 3;j++) + { + while (*s && ISWHITESPACE(*s)) + s++; + if (!*s) + break; + val->vector[j] = atof(s); + while (!ISWHITESPACE(*s)) + s++; + if (!*s) + break; + } + break; + case ev_string: + PRVM_ChangeEngineString(var->globaldefindex_stringno[i], var->string); + val->string = var->globaldefindex_stringno[i]; + break; + } + } + } + } + prog = tmpprog; } void Cvar_SetQuick (cvar_t *var, const char *value) diff --git a/cvar.h b/cvar.h index 8fb6ca2c..636ca40b 100644 --- a/cvar.h +++ b/cvar.h @@ -124,6 +124,10 @@ typedef struct cvar_s char *defstring; + unsigned int globaldefindex_progid[3]; + int globaldefindex[3]; + int globaldefindex_stringno[3]; + //menucvar_t menuinfo; struct cvar_s *next; struct cvar_s *nextonhashchain; diff --git a/mvm_cmds.c b/mvm_cmds.c index 2bcf93fe..6042843f 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -16,6 +16,7 @@ char *vm_m_extensions = "DP_GECKO_SUPPORT " "DP_MENU_EXTRESPONSEPACKET " "DP_QC_ASINACOSATANATAN2TAN " +"DP_QC_AUTOCVARS " "DP_QC_CMD " "DP_QC_CRC16 " "DP_QC_CVAR_TYPE " diff --git a/progsvm.h b/progsvm.h index 1251944b..2dd9e0ff 100644 --- a/progsvm.h +++ b/progsvm.h @@ -358,6 +358,7 @@ prvm_stringbuffer_t; typedef struct prvm_prog_s { double starttime; + unsigned int id; // increasing unique id of progs instance dprograms_t *progs; mfunction_t *functions; char *strings; @@ -628,6 +629,7 @@ void PRVM_ED_PrintNum (int ent, const char *wildcard_fieldname); const char *PRVM_GetString(int num); int PRVM_SetEngineString(const char *s); +const char *PRVM_ChangeEngineString(int i, const char *s); int PRVM_SetTempString(const char *s); int PRVM_AllocString(size_t bufferlength, char **pointer); void PRVM_FreeString(int num); diff --git a/prvm_edict.c b/prvm_edict.c index 5ac8db89..35af00bf 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -2059,6 +2059,74 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required PRVM_Init_Exec(); + for (i=0 ; iprogs->numglobaldefs ; i++) + { + const char *name; + cvar_t *cvar; + name = PRVM_GetString(prog->globaldefs[i].s_name); + if(name + && !strncmp(name, "autocvar_", 9) + // && !(strlen(name) > 1 && name[strlen(name)-2] == '_' && (name[strlen(name)-1] == 'x' || name[strlen(name)-1] == 'y' || name[strlen(name)-1] == 'z')) + ) + { + + cvar = Cvar_FindVar(name + 9); + if(!cvar) + { + Con_Printf("PRVM_LoadProgs: no cvar for autocvar global %s in %s\n", name, PRVM_NAME); + cvar = Cvar_Get(name + 9, "", 0, NULL); + if(!cvar) + PRVM_ERROR("PRVM_LoadProgs: could not create cvar for autocvar global %s in %s", name, PRVM_NAME); + } + if(cvar && ((cvar->flags & CVAR_PRIVATE) == 0)) + { + // MUST BE SYNCED WITH cvar.c Cvar_Set + int j; + const char *s; + prvm_eval_t *val = (prvm_eval_t *)(prog->globals.generic + prog->globaldefs[i].ofs); + switch(prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) + { + case ev_float: + val->_float = cvar->value; + cvar->globaldefindex_progid[prog - prog_list] = prog->id; + cvar->globaldefindex[prog - prog_list] = i; + break; + case ev_vector: + s = cvar->string; + VectorClear(val->vector); + for (j = 0;j < 3;j++) + { + while (*s && ISWHITESPACE(*s)) + s++; + if (!*s) + break; + val->vector[j] = atof(s); + while (!ISWHITESPACE(*s)) + s++; + if (!*s) + break; + } + cvar->globaldefindex_progid[prog - prog_list] = prog->id; + cvar->globaldefindex[prog - prog_list] = i; + break; + case ev_string: + val->string = PRVM_SetEngineString(cvar->string); + cvar->globaldefindex_progid[prog - prog_list] = prog->id; + cvar->globaldefindex[prog - prog_list] = i; + cvar->globaldefindex_stringno[prog - prog_list] = val->string; + break; + default: + Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, PRVM_NAME); + break; + } + } + else + Con_Printf("PRVM_LoadProgs: private cvar for autocvar global %s in %s\n", name, PRVM_NAME); + } + if((prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) == ev_vector) + i += 3; // skip the _x _y _z floats + } + prog->loaded = TRUE; // set flags & ddef_ts in prog @@ -2341,6 +2409,8 @@ PRVM_InitProg */ void PRVM_InitProg(int prognr) { + static unsigned int progid = 0; + if(prognr < 0 || prognr >= PRVM_MAXPROGS) Sys_Error("PRVM_InitProg: Invalid program number %i",prognr); @@ -2351,6 +2421,7 @@ void PRVM_InitProg(int prognr) memset(prog, 0, sizeof(prvm_prog_t)); prog->starttime = Sys_DoubleTime(); + prog->id = ++progid; prog->error_cmd = Host_Error; prog->leaktest_active = prvm_leaktest.integer != 0; @@ -2449,6 +2520,17 @@ const char *PRVM_GetString(int num) } } +const char *PRVM_ChangeEngineString(int i, const char *s) +{ + const char *old; + i = -1 - i; + if(i < 0 || i >= prog->numknownstrings) + PRVM_ERROR("PRVM_ChangeEngineString: s is not an engine string"); + old = prog->knownstrings[i]; + prog->knownstrings[i] = s; + return old; +} + int PRVM_SetEngineString(const char *s) { int i; diff --git a/svvm_cmds.c b/svvm_cmds.c index 6dc99e5c..879f7974 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -65,6 +65,7 @@ char *vm_sv_extensions = "DP_MOVETYPEFOLLOW " "DP_NULL_MODEL " "DP_QC_ASINACOSATANATAN2TAN " +"DP_QC_AUTOCVARS " "DP_QC_CHANGEPITCH " "DP_QC_CMD " "DP_QC_COPYENTITY " -- 2.39.2