]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
cvar: Proof of concept for "internal variables" as a subset of cvar_t Cloudwalk/cvar
authorCloudwalk <cloudwalk009@gmail.com>
Tue, 27 Oct 2020 14:49:25 +0000 (10:49 -0400)
committerCloudwalk <cloudwalk009@gmail.com>
Tue, 27 Oct 2020 14:51:08 +0000 (10:51 -0400)
The idea is to create a dividing line between internal variables and
their end-user configurability. This gives more control to the game dev,
where they can decide which engine variables they want configurable with
what ever name they choose. So far it works with sv_cheats.

This allows the engine to be in a more barebones state, not imposing on
the game dev as far as cvars are concerned. It makes cross-engine
compatibility more feasible by allowing variables to adopt different
names to satisfy MenuQC settings menus or what have you.

cmd.c
cvar.c
cvar.h
sv_ccmds.c

diff --git a/cmd.c b/cmd.c
index c353b4c854d80a250b586fc39be42452e84c07ad..aeeb110ce9fa81f103fcaad6c219b4dab79a01af 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -2146,7 +2146,7 @@ void Cmd_ClearCSQCCommands (cmd_state_t *cmd)
        }
 }
 
-extern cvar_t sv_cheats;
+extern ivar_t sv_cheats;
 
 /*
 ============
diff --git a/cvar.c b/cvar.c
index 1124494dd5c339038f4d1384fff06b70fd3d1dba..de83794542cde0fcb7f9284c5407344915b9db69 100644 (file)
--- a/cvar.c
+++ b/cvar.c
@@ -392,6 +392,22 @@ static void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
        memcpy ((char *)var->string, value, valuelen + 1);
        var->value = atof (var->string);
        var->integer = (int) var->value;
+
+       if(var->internal)
+       {
+               switch (var->internal->type)
+               {
+               case _bool:
+               case _int:
+               case _float:
+                       var->internal->integer = var->integer;
+                       break;
+               case _string:
+                       var->internal->string = (char *)var->string;
+                       break;
+               }
+       }
+
        if ((var->flags & CF_NOTIFY) && sv.active && !sv_disablenotify.integer)
                SV_BroadcastPrintf("\003^3Server cvar \"%s\" changed to \"%s\"\n", var->name, var->string);
 #if 0
@@ -527,6 +543,51 @@ static void Cvar_Link(cvar_t *variable, cvar_state_t *cvars)
        cvars->hashtable[hashindex] = hash;
 }
 
+void Cvar_RegisterInternal(ivar_t *variable, const char *name, const char *description, int flags)
+{
+       cvar_t *cvar = NULL;
+       char buf[256];
+       int i;
+
+       cvar = Cvar_FindVar(&cvars_all, name, ~0);
+       if(cvar)
+               return;
+       
+       cvar = (cvar_t *)Z_Malloc(sizeof(cvar_t));
+       cvar->flags = flags;
+       cvar->name = (char *)Mem_strdup(zonemempool, name);
+       switch (variable->type)
+       {
+       case _bool:
+       case _int:
+               dpsnprintf(buf, sizeof(buf), "%i", variable->integer);
+               break;
+       case _float:
+               dpsnprintf(buf, sizeof(buf), "%.9g", variable->value);
+               break;
+       case _string:
+               dpsnprintf(buf, sizeof(buf), "%s", variable->string);
+               break;
+       }
+
+       cvar->name = (char *)Mem_strdup(zonemempool, name);
+       cvar->string = (char *)Mem_strdup(zonemempool, buf);
+       cvar->defstring = (char *)Mem_strdup(zonemempool, buf);
+       cvar->description = (char *)Mem_strdup(zonemempool, description);
+       cvar->value = variable->value;
+       cvar->integer = variable->integer;
+       cvar->aliases = (char **)Z_Malloc(sizeof(char **));
+       cvar->internal = variable;
+       memset(cvar->aliases, 0, sizeof(char *));
+
+
+       // Mark it as not an autocvar.
+       for (i = 0;i < PRVM_PROG_MAX;i++)
+               cvar->globaldefindex[i] = -1;
+
+       Cvar_Link(cvar, &cvars_all);
+}
+
 /*
 ============
 Cvar_RegisterVariable
@@ -617,6 +678,7 @@ void Cvar_RegisterVariable (cvar_t *variable)
        variable->defstring = (char *)Mem_strdup(zonemempool, variable->string);
        variable->value = atof (variable->string);
        variable->integer = (int) variable->value;
+       variable->internal = NULL;
        variable->aliasindex = 0;
 
        // Mark it as not an autocvar.
@@ -685,6 +747,7 @@ cvar_t *Cvar_Get(cvar_state_t *cvars, const char *name, const char *value, int f
        cvar->value = atof (cvar->string);
        cvar->integer = (int) cvar->value;
        cvar->aliases = (char **)Z_Malloc(sizeof(char **));
+       cvar->internal = NULL;
        memset(cvar->aliases, 0, sizeof(char *));
 
        if(newdescription && *newdescription)
diff --git a/cvar.h b/cvar.h
index 1b01fc78348b123428006064efd27f436f1b41f5..1e01a7380db4dfe0c3b35b0dc80ca0bc868538e7 100644 (file)
--- a/cvar.h
+++ b/cvar.h
@@ -61,6 +61,50 @@ interface from being ambiguous.
 struct cmd_state_s;
 struct qfile_s;
 
+// TODO
+typedef enum ival_type_e
+{
+       _bool,
+       _int,
+       _float,
+       //_vector,
+       _string
+} ival_type_t;
+
+typedef struct ivar_s
+{
+       union
+       {
+               qbool boolean;
+               int integer;
+               float value;
+               //float *vector;
+               const char *string;
+       };
+
+       ival_type_t type;
+
+} ivar_t;
+
+// Not used, just what the new cvar_t *might* look like.
+typedef struct ncvar_s
+{
+       ivar_t var;
+       ivar_t init;
+       int flags;
+       const char *name;
+       const char *description;
+       const char *string;
+       const char *defstring;
+       void (*callback)(struct ncvar_s *var);
+
+       int globaldefindex[3];
+       int globaldefindex_stringno[3];
+
+       struct ncvar_s *next;
+
+} ncvar_t;
+
 typedef struct cvar_s
 {
        int flags;
@@ -94,6 +138,8 @@ typedef struct cvar_s
        int globaldefindex[3];
        int globaldefindex_stringno[3];
 
+       ivar_t *internal;
+
        struct cvar_s *next;
 } cvar_t;
 
@@ -117,6 +163,8 @@ void Cvar_RegisterAlias(cvar_t *variable, const char *alias );
 
 void Cvar_RegisterCallback(cvar_t *variable, void (*callback)(cvar_t *));
 
+void Cvar_RegisterInternal(ivar_t *variable, const char *name, const char *description, int flags);
+
 /// registers a cvar that already has the name, string, and optionally the
 /// archive elements set.
 void Cvar_RegisterVariable(cvar_t *variable);
index 95796d5c3ac04bc281a15d6ec1df4bc46dccb3e0..969fd46e12ceb6c74c0e04d4c022177b8cf8e973 100644 (file)
@@ -24,7 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "sv_demo.h"
 
 int current_skill;
-cvar_t sv_cheats = {CF_SERVER | CF_NOTIFY, "sv_cheats", "0", "enables cheat commands in any game, and cheat impulses in dpmod"};
+// TODO: Convenience macros? Maybe IVAR_BOOL(sv_cheats, 1) or something
+ivar_t sv_cheats = { .boolean = 0, _bool};
+//cvar_t sv_cheats = {CF_SERVER | CF_NOTIFY, "sv_cheats", "0", "enables cheat commands in any game, and cheat impulses in dpmod"};
 cvar_t sv_adminnick = {CF_SERVER | CF_ARCHIVE, "sv_adminnick", "", "nick name to use for admin messages instead of host name"};
 cvar_t sv_status_privacy = {CF_SERVER | CF_ARCHIVE, "sv_status_privacy", "0", "do not show IP addresses in 'status' replies to clients"};
 cvar_t sv_status_show_qcstatus = {CF_SERVER | CF_ARCHIVE, "sv_status_show_qcstatus", "0", "show the 'qcstatus' field in status replies, not the 'frags' field. Turn this on if your mod uses this field, and the 'frags' field on the other hand has no meaningful value."};
@@ -1609,8 +1611,12 @@ static void SV_Ent_Remove_All_f(cmd_state_t *cmd)
 
 void SV_InitOperatorCommands(void)
 {
-       Cvar_RegisterVariable(&sv_cheats);
-       Cvar_RegisterCallback(&sv_cheats, SV_DisableCheats_c);
+       // TODO: By making cvar_t a superset of ivar_t, we can just cast sv_cheats
+       // to cvar_t and not have to do what ever this shit is.
+       cvar_t *cheats;
+       Cvar_RegisterInternal(&sv_cheats, "sv_cheats", "enables cheat commands in any game, and cheat impulses in dpmod", CF_SERVER | CF_NOTIFY);
+       cheats = Cvar_FindVar(&cvars_all, "sv_cheats", ~0);
+       Cvar_RegisterCallback(cheats, SV_DisableCheats_c);
        Cvar_RegisterVariable(&sv_adminnick);
        Cvar_RegisterVariable(&sv_status_privacy);
        Cvar_RegisterVariable(&sv_status_show_qcstatus);