]> icculus.org git repositories - btb/d2x.git/blob - main/cvar.c
cvar.value -> cvar.fixval, for less confusion
[btb/d2x.git] / main / cvar.c
1 /* Console variables */
2
3
4 #ifdef HAVE_CONFIG_H
5 #include <conf.h>
6 #endif
7
8 #include <stdlib.h>
9 #include <float.h>
10
11 #include "console.h"
12 #include "dxxerror.h"
13 #include "strutil.h"
14 #include "u_mem.h"
15 #include "hash.h"
16
17
18 #define CVAR_MAX_LENGTH 1024
19 #define CVAR_MAX_CVARS  1024
20
21 /* The list of cvars */
22 hashtable cvar_hash;
23 cvar_t *cvar_list[CVAR_MAX_CVARS];
24 int Num_cvars;
25
26
27 void cvar_free(void)
28 {
29         while (Num_cvars--)
30                 d_free(cvar_list[Num_cvars]->string);
31
32         hashtable_free(&cvar_hash);
33 }
34
35
36 void cvar_cmd_set(int argc, char **argv)
37 {
38         char buf[CVAR_MAX_LENGTH];
39         int ret, i;
40
41         if (argc == 2) {
42                 cvar_t *ptr;
43
44                 if ((ptr = cvar_find(argv[1])))
45                         con_printf(CON_NORMAL, "%s: %s\n", ptr->name, ptr->string);
46                 else
47                         con_printf(CON_NORMAL, "set: variable %s not found\n", argv[1]);
48                 return;
49         }
50
51         if (argc == 1) {
52                 for (i = 0; i < Num_cvars; i++)
53                         con_printf(CON_NORMAL, "%s: %s\n", cvar_list[i]->name, cvar_list[i]->string);
54                 return;
55         }
56
57         ret = snprintf(buf, sizeof(buf), "%s", argv[2]);
58         if (ret >= CVAR_MAX_LENGTH) {
59                 con_printf(CON_CRITICAL, "set: value too long (max %d characters)\n", CVAR_MAX_LENGTH);
60                 return;
61         }
62
63         for (i = 3; i < argc; i++) {
64                 ret = snprintf(buf, CVAR_MAX_LENGTH, "%s %s", buf, argv[i]);
65                 if (ret >= CVAR_MAX_LENGTH) {
66                         con_printf(CON_CRITICAL, "set: value too long (max %d characters)\n", CVAR_MAX_LENGTH);
67                         return;
68                 }
69         }
70         cvar_set(argv[1], buf);
71 }
72
73
74 void cvar_init(void)
75 {
76         hashtable_init( &cvar_hash, CVAR_MAX_CVARS );
77
78         cmd_addcommand("set", cvar_cmd_set, "set <name> <value>\n"  "    set variable <name> equal to <value>\n"
79                                             "set <name>\n"          "    show value of <name>\n"
80                                             "set\n"                 "    show value of all variables");
81
82         atexit(cvar_free);
83 }
84
85
86 cvar_t *cvar_find(const char *cvar_name)
87 {
88         int i;
89
90         i = hashtable_search( &cvar_hash, cvar_name );
91
92         if ( i < 0 )
93                 return NULL;
94
95         return cvar_list[i];
96 }
97
98
99 const char *cvar_complete(char *text)
100 {
101         int i;
102         size_t len = strlen(text);
103
104         if (!len)
105                 return NULL;
106
107         for (i = 0; i < Num_cvars; i++)
108                 if (!strnicmp(text, cvar_list[i]->name, len))
109                         return cvar_list[i]->name;
110
111         return NULL;
112 }
113
114
115 /* Register a cvar */
116 void cvar_registervariable(cvar_t *cvar)
117 {
118         char *stringval;
119
120         Assert(cvar != NULL);
121
122         stringval = cvar->string;
123
124         cvar->string = d_strdup(stringval);
125         cvar->fixval = fl2f(strtod(cvar->string, NULL));
126         cvar->intval = (int)strtol(cvar->string, NULL, 10);
127
128         if (cvar_find(cvar->name))
129         {
130                 Int3();
131                 con_printf(CON_URGENT, "cvar %s already exists!\n", cvar->name);
132                 return;
133         }
134
135         /* insert at end of list */
136         hashtable_insert(&cvar_hash, cvar->name, Num_cvars);
137         cvar_list[Num_cvars++] = cvar;
138 }
139
140
141 /* Set a CVar's value */
142 void cvar_set_cvar(cvar_t *cvar, char *value)
143 {
144         if (!cvar)
145                 return;
146
147         d_free(cvar->string);
148         cvar->string = d_strdup(value);
149         cvar->fixval = fl2f(strtod(cvar->string, NULL));
150         cvar->intval = (int)strtol(cvar->string, NULL, 10);
151         con_printf(CON_VERBOSE, "%s: %s\n", cvar->name, cvar->string);
152 }
153
154
155 void cvar_set_cvarf(cvar_t *cvar, const char *fmt, ...)
156 {
157         va_list arglist;
158         char buf[CVAR_MAX_LENGTH];
159         int n;
160
161         va_start (arglist, fmt);
162         n = vsnprintf(buf, sizeof(buf), fmt, arglist);
163         va_end (arglist);
164
165         Assert(!(n < 0 || n > CVAR_MAX_LENGTH));
166
167         cvar_set_cvar(cvar, buf);
168 }
169
170
171 void cvar_set(const char *cvar_name, char *value)
172 {
173         cvar_t *cvar;
174         extern cvar_t Cheats_enabled;
175
176         cvar = cvar_find(cvar_name);
177         if (!cvar) {
178                 Int3();
179                 con_printf(CON_NORMAL, "cvar %s not found\n", cvar_name);
180                 return;
181         }
182
183         if (cvar->flags & CVAR_CHEAT && !Cheats_enabled.intval)
184         {
185                 con_printf(CON_NORMAL, "cvar %s is cheat protected.\n", cvar_name);
186                 return;
187         }
188
189         cvar_set_cvar(cvar, value);
190 }
191
192
193 /* Write archive cvars to file */
194 void cvar_write(CFILE *file)
195 {
196         int i;
197
198         for (i = 0; i < Num_cvars; i++)
199                 if (cvar_list[i]->flags & CVAR_ARCHIVE)
200                         PHYSFSX_printf(file, "%s=%s\n", cvar_list[i]->name, cvar_list[i]->string);
201 }