DP_QC_AUTOCVARS: declare a QC variable float/vector/string autocvar_foo, and it will...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 5 Dec 2009 15:33:56 +0000 (15:33 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 5 Dec 2009 15:33:56 +0000 (15:33 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9538 d7cf8633-e32d-0410-b094-e92efae38249

cvar.c
cvar.h
mvm_cmds.c
progsvm.h
prvm_edict.c
svvm_cmds.c

diff --git a/cvar.c b/cvar.c
index 111550a..30ba09f 100644 (file)
--- 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 8fb6ca2..636ca40 100644 (file)
--- 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;
index 2bcf93f..6042843 100644 (file)
@@ -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 "
index 1251944..2dd9e0f 100644 (file)
--- 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);
index 5ac8db8..35af00b 100644 (file)
@@ -2059,6 +2059,74 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
 
        PRVM_Init_Exec();
 
+       for (i=0 ; i<prog->progs->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;
index 6dc99e5..879f797 100644 (file)
@@ -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 "