1 /*
2 ** c_cvars.h
3 **
4 **---------------------------------------------------------------------------
5 ** Copyright 1998-2006 Randy Heit
6 ** All rights reserved.
7 **
8 ** Redistribution and use in source and binary forms, with or without
9 ** modification, are permitted provided that the following conditions
10 ** are met:
11 **
12 ** 1. Redistributions of source code must retain the above copyright
13 **    notice, this list of conditions and the following disclaimer.
14 ** 2. Redistributions in binary form must reproduce the above copyright
15 **    notice, this list of conditions and the following disclaimer in the
16 **    documentation and/or other materials provided with the distribution.
17 ** 3. The name of the author may not be used to endorse or promote products
18 **    derived from this software without specific prior written permission.
19 **
20 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 **---------------------------------------------------------------------------
31 **
32 */
33 
34 #ifndef __C_CVARS_H__
35 #define __C_CVARS_H__
36 
37 #include "doomtype.h"
38 #include "tarray.h"
39 
40 /*
41 ==========================================================
42 
43 CVARS (console variables)
44 
45 ==========================================================
46 */
47 
48 enum
49 {
50 	CVAR_ARCHIVE		= 1,	// set to cause it to be saved to config
51 	CVAR_USERINFO		= 2,	// added to userinfo  when changed
52 	CVAR_SERVERINFO		= 4,	// added to serverinfo when changed
53 	CVAR_NOSET			= 8,	// don't allow change from console at all,
54 								// but can be set from the command line
55 	CVAR_LATCH			= 16,	// save changes until server restart
56 	CVAR_UNSETTABLE		= 32,	// can unset this var from console
57 	CVAR_DEMOSAVE		= 64,	// save the value of this cvar in a demo
58 	CVAR_ISDEFAULT		= 128,	// is cvar unchanged since creation?
59 	CVAR_AUTO			= 256,	// allocated; needs to be freed when destroyed
60 	CVAR_NOINITCALL		= 512,	// don't call callback at game start
61 	CVAR_GLOBALCONFIG	= 1024,	// cvar is saved to global config section
62 	CVAR_VIDEOCONFIG	= 2048, // cvar is saved to video config section (not implemented)
63 	CVAR_NOSAVE			= 4096, // when used with CVAR_SERVERINFO, do not save var to savegame
64 	CVAR_MOD			= 8192,	// cvar was defined by a mod
65 	CVAR_IGNORE			= 16384,// do not send cvar across the network/inaccesible from ACS (dummy mod cvar)
66 };
67 
68 union UCVarValue
69 {
70 	bool Bool;
71 	int Int;
72 	float Float;
73 	const char *String;
74 	const GUID *pGUID;
75 };
76 
77 enum ECVarType
78 {
79 	CVAR_Bool,
80 	CVAR_Int,
81 	CVAR_Float,
82 	CVAR_String,
83 	CVAR_Color,		// stored as CVAR_Int
84 	CVAR_Dummy,		// just redirects to another cvar
85 	CVAR_GUID
86 };
87 
88 class FConfigFile;
89 class AActor;
90 
91 class FBaseCVar
92 {
93 public:
94 	FBaseCVar (const char *name, uint32 flags, void (*callback)(FBaseCVar &));
95 	virtual ~FBaseCVar ();
96 
Callback()97 	inline void Callback () { if (m_Callback) m_Callback (*this); }
98 
GetName()99 	inline const char *GetName () const { return Name; }
GetFlags()100 	inline uint32 GetFlags () const { return Flags; }
GetNext()101 	inline FBaseCVar *GetNext() const { return m_Next; }
102 
103 	void CmdSet (const char *newval);
104 	void ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend=false);
105 	void SetGenericRep (UCVarValue value, ECVarType type);
106 	void ResetToDefault ();
SetArchiveBit()107 	void SetArchiveBit () { Flags |= CVAR_ARCHIVE; }
108 
109 	virtual ECVarType GetRealType () const = 0;
110 
111 	virtual UCVarValue GetGenericRep (ECVarType type) const = 0;
112 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const = 0;
113 
114 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const = 0;
115 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const = 0;
116 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type) = 0;
117 
118 	FBaseCVar &operator= (const FBaseCVar &var)
119 		{ UCVarValue val; ECVarType type; val = var.GetFavoriteRep (&type); SetGenericRep (val, type); return *this; }
120 
121 	static void EnableNoSet ();		// enable the honoring of CVAR_NOSET
122 	static void EnableCallbacks ();
123 	static void DisableCallbacks ();
124 	static void ResetColors ();		// recalc color cvars' indices after screen change
125 
126 	static void ListVars (const char *filter, bool plain);
127 
128 protected:
FBaseCVar()129 	FBaseCVar () {}
130 	virtual void DoSet (UCVarValue value, ECVarType type) = 0;
131 
132 	static bool ToBool (UCVarValue value, ECVarType type);
133 	static int ToInt (UCVarValue value, ECVarType type);
134 	static float ToFloat (UCVarValue value, ECVarType type);
135 	static const char *ToString (UCVarValue value, ECVarType type);
136 	static const GUID *ToGUID (UCVarValue value, ECVarType type);
137 	static UCVarValue FromBool (bool value, ECVarType type);
138 	static UCVarValue FromInt (int value, ECVarType type);
139 	static UCVarValue FromFloat (float value, ECVarType type);
140 	static UCVarValue FromString (const char *value, ECVarType type);
141 	static UCVarValue FromGUID (const GUID &value, ECVarType type);
142 
143 	char *Name;
144 	uint32 Flags;
145 
146 private:
147 	FBaseCVar (const FBaseCVar &var);
148 	FBaseCVar (const char *name, uint32 flags);
149 
150 	void (*m_Callback)(FBaseCVar &);
151 	FBaseCVar *m_Next;
152 
153 	static bool m_UseCallback;
154 	static bool m_DoNoSet;
155 
156 	friend FString C_GetMassCVarString (uint32 filter, bool compact);
157 	friend void C_ReadCVars (BYTE **demo_p);
158 	friend void C_BackupCVars (void);
159 	friend FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev);
160 	friend FBaseCVar *FindCVarSub (const char *var_name, int namelen);
161 	friend void UnlatchCVars (void);
162 	friend void DestroyCVarsFlagged (DWORD flags);
163 	friend void C_ArchiveCVars (FConfigFile *f, uint32 filter);
164 	friend void C_SetCVarsToDefaults (void);
165 	friend void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32 filter);
166 	friend void C_DeinitConsole();
167 };
168 
169 // Returns a string with all cvars whose flags match filter. In compact mode,
170 // the cvar names are omitted to save space.
171 FString C_GetMassCVarString (uint32 filter, bool compact=false);
172 
173 // Writes all cvars that could effect demo sync to *demo_p. These are
174 // cvars that have either CVAR_SERVERINFO or CVAR_DEMOSAVE set.
175 void C_WriteCVars (BYTE **demo_p, uint32 filter, bool compact=false);
176 
177 // Read all cvars from *demo_p and set them appropriately.
178 void C_ReadCVars (BYTE **demo_p);
179 
180 // Backup demo cvars. Called before a demo starts playing to save all
181 // cvars the demo might change.
182 void C_BackupCVars (void);
183 
184 // Finds a named cvar
185 FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev);
186 FBaseCVar *FindCVarSub (const char *var_name, int namelen);
187 
188 // Create a new cvar with the specified name and type
189 FBaseCVar *C_CreateCVar(const char *var_name, ECVarType var_type, DWORD flags);
190 
191 // Called from G_InitNew()
192 void UnlatchCVars (void);
193 
194 // Destroy CVars with the matching flags; called from CCMD(restart)
195 void DestroyCVarsFlagged (DWORD flags);
196 
197 // archive cvars to FILE f
198 void C_ArchiveCVars (FConfigFile *f, uint32 filter);
199 
200 // initialize cvars to default values after they are created
201 void C_SetCVarsToDefaults (void);
202 
203 void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32 filter);
204 
205 void C_DeinitConsole();
206 
207 class FBoolCVar : public FBaseCVar
208 {
209 public:
210 	FBoolCVar (const char *name, bool def, uint32 flags, void (*callback)(FBoolCVar &)=NULL);
211 
212 	virtual ECVarType GetRealType () const;
213 
214 	virtual UCVarValue GetGenericRep (ECVarType type) const;
215 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const;
216 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
217 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const;
218 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
219 
220 	inline bool operator= (bool boolval)
221 		{ UCVarValue val; val.Bool = boolval; SetGenericRep (val, CVAR_Bool); return boolval; }
222 	inline operator bool () const { return Value; }
223 	inline bool operator *() const { return Value; }
224 
225 protected:
226 	virtual void DoSet (UCVarValue value, ECVarType type);
227 
228 	bool Value;
229 	bool DefaultValue;
230 };
231 
232 class FIntCVar : public FBaseCVar
233 {
234 public:
235 	FIntCVar (const char *name, int def, uint32 flags, void (*callback)(FIntCVar &)=NULL);
236 
237 	virtual ECVarType GetRealType () const;
238 
239 	virtual UCVarValue GetGenericRep (ECVarType type) const;
240 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const;
241 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
242 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const;
243 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
244 
245 	int operator= (int intval)
246 		{ UCVarValue val; val.Int = intval; SetGenericRep (val, CVAR_Int); return intval; }
247 	inline operator int () const { return Value; }
248 	inline int operator *() const { return Value; }
249 
250 protected:
251 	virtual void DoSet (UCVarValue value, ECVarType type);
252 
253 	int Value;
254 	int DefaultValue;
255 
256 	friend class FFlagCVar;
257 };
258 
259 class FFloatCVar : public FBaseCVar
260 {
261 public:
262 	FFloatCVar (const char *name, float def, uint32 flags, void (*callback)(FFloatCVar &)=NULL);
263 
264 	virtual ECVarType GetRealType () const;
265 
266 	virtual UCVarValue GetGenericRep (ECVarType type) const;
267 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const;
268 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
269 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const;
270 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
271 
272 	float operator= (float floatval)
273 		{ UCVarValue val; val.Float = floatval; SetGenericRep (val, CVAR_Float); return floatval; }
274 	inline operator float () const { return Value; }
275 	inline float operator *() const { return Value; }
276 
277 protected:
278 	virtual void DoSet (UCVarValue value, ECVarType type);
279 
280 	float Value;
281 	float DefaultValue;
282 };
283 
284 class FStringCVar : public FBaseCVar
285 {
286 public:
287 	FStringCVar (const char *name, const char *def, uint32 flags, void (*callback)(FStringCVar &)=NULL);
288 	~FStringCVar ();
289 
290 	virtual ECVarType GetRealType () const;
291 
292 	virtual UCVarValue GetGenericRep (ECVarType type) const;
293 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const;
294 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
295 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const;
296 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
297 
298 	const char *operator= (const char *stringrep)
299 		{ UCVarValue val; val.String = const_cast<char *>(stringrep); SetGenericRep (val, CVAR_String); return stringrep; }
300 	inline operator const char * () const { return Value; }
301 	inline const char *operator *() const { return Value; }
302 
303 protected:
304 	virtual void DoSet (UCVarValue value, ECVarType type);
305 
306 	char *Value;
307 	char *DefaultValue;
308 };
309 
310 class FColorCVar : public FIntCVar
311 {
312 public:
313 	FColorCVar (const char *name, int def, uint32 flags, void (*callback)(FColorCVar &)=NULL);
314 
315 	virtual ECVarType GetRealType () const;
316 
317 	virtual UCVarValue GetGenericRep (ECVarType type) const;
318 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
319 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
320 
uint32()321 	inline operator uint32 () const { return Value; }
322 	inline uint32 operator *() const { return Value; }
GetIndex()323 	inline int GetIndex () const { return Index; }
324 
325 protected:
326 	virtual void DoSet (UCVarValue value, ECVarType type);
327 
328 	static UCVarValue FromInt2 (int value, ECVarType type);
329 	static int ToInt2 (UCVarValue value, ECVarType type);
330 
331 	int Index;
332 };
333 
334 class FFlagCVar : public FBaseCVar
335 {
336 public:
337 	FFlagCVar (const char *name, FIntCVar &realvar, uint32 bitval);
338 
339 	virtual ECVarType GetRealType () const;
340 
341 	virtual UCVarValue GetGenericRep (ECVarType type) const;
342 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const;
343 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
344 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const;
345 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
346 
347 	bool operator= (bool boolval)
348 		{ UCVarValue val; val.Bool = boolval; SetGenericRep (val, CVAR_Bool); return boolval; }
349 	bool operator= (FFlagCVar &flag)
350 		{ UCVarValue val; val.Bool = !!flag; SetGenericRep (val, CVAR_Bool); return val.Bool; }
351 	inline operator int () const { return (ValueVar & BitVal); }
352 	inline int operator *() const { return (ValueVar & BitVal); }
353 
354 protected:
355 	virtual void DoSet (UCVarValue value, ECVarType type);
356 
357 	FIntCVar &ValueVar;
358 	uint32 BitVal;
359 	int BitNum;
360 };
361 
362 class FMaskCVar : public FBaseCVar
363 {
364 public:
365 	FMaskCVar (const char *name, FIntCVar &realvar, uint32 bitval);
366 
367 	virtual ECVarType GetRealType () const;
368 
369 	virtual UCVarValue GetGenericRep (ECVarType type) const;
370 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const;
371 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
372 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const;
373 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
374 
375 	inline operator int () const { return (ValueVar & BitVal) >> BitNum; }
376 	inline int operator *() const { return (ValueVar & BitVal) >> BitNum; }
377 
378 protected:
379 	virtual void DoSet (UCVarValue value, ECVarType type);
380 
381 	FIntCVar &ValueVar;
382 	uint32 BitVal;
383 	int BitNum;
384 };
385 
386 class FGUIDCVar : public FBaseCVar
387 {
388 public:
389 	FGUIDCVar (const char *name, const GUID *defguid, uint32 flags, void (*callback)(FGUIDCVar &)=NULL);
390 
391 	virtual ECVarType GetRealType () const;
392 
393 	virtual UCVarValue GetGenericRep (ECVarType type) const;
394 	virtual UCVarValue GetFavoriteRep (ECVarType *type) const;
395 	virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
396 	virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const;
397 	virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
398 
399 	const GUID &operator= (const GUID &guidval)
400 		{ UCVarValue val; val.pGUID = &guidval; SetGenericRep (val, CVAR_GUID); return guidval; }
401 	inline operator const GUID & () const { return Value; }
402 	inline const GUID &operator *() const { return Value; }
403 
404 protected:
405 	virtual void DoSet (UCVarValue value, ECVarType type);
406 
407 	GUID Value;
408 	GUID DefaultValue;
409 };
410 
411 extern int cvar_defflags;
412 
413 FBaseCVar *cvar_set (const char *var_name, const char *value);
414 FBaseCVar *cvar_forceset (const char *var_name, const char *value);
415 
cvar_set(const char * var_name,const BYTE * value)416 inline FBaseCVar *cvar_set (const char *var_name, const BYTE *value) { return cvar_set (var_name, (const char *)value); }
cvar_forceset(const char * var_name,const BYTE * value)417 inline FBaseCVar *cvar_forceset (const char *var_name, const BYTE *value) { return cvar_forceset (var_name, (const char *)value); }
418 
419 
420 
421 // Restore demo cvars. Called after demo playback to restore all cvars
422 // that might possibly have been changed during the course of demo playback.
423 void C_RestoreCVars (void);
424 
425 void C_ForgetCVars (void);
426 
427 
428 #define CUSTOM_CVAR(type,name,def,flags) \
429 	static void cvarfunc_##name(F##type##CVar &); \
430 	F##type##CVar name (#name, def, flags, cvarfunc_##name); \
431 	static void cvarfunc_##name(F##type##CVar &self)
432 
433 #define CVAR(type,name,def,flags) \
434 	F##type##CVar name (#name, def, flags);
435 
436 #define EXTERN_CVAR(type,name) extern F##type##CVar name;
437 
438 extern FBaseCVar *CVars;
439 
440 #endif //__C_CVARS_H__
441