1 /**
2  * @file
3  * @brief Cvar (console variable) header file
4  *
5  * cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly
6  * in C code.
7  * The user can access cvars from the console in three ways:
8  * r_draworder			prints the current value
9  * r_draworder 0		sets the current value to 0
10  * set r_draworder 0	as above, but creates the cvar if not present
11  * Cvars are restricted from having the same names as commands to keep this
12  * interface from being ambiguous.
13  */
14 
15 /*
16 Copyright (C) 1997-2001 Id Software, Inc.
17 
18 This program is free software; you can redistribute it and/or
19 modify it under the terms of the GNU General Public License
20 as published by the Free Software Foundation; either version 2
21 of the License, or (at your option) any later version.
22 
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 
27 See the GNU General Public License for more details.
28 
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32 
33 */
34 
35 #pragma once
36 
37 #include "../shared/shared.h"
38 
39 #define CVAR_ARCHIVE    1       /**< set to cause it to be saved to vars.rc */
40 #define CVAR_USERINFO   2       /**< added to userinfo  when changed */
41 #define CVAR_SERVERINFO 4       /**< added to serverinfo when changed */
42 #define CVAR_NOSET      8       /**< don't allow change from console at all, but can be set from the command line */
43 #define CVAR_LATCH      16      /**< save changes until server restart */
44 #define CVAR_DEVELOPER  32      /**< set from commandline (not from within the game) and hide from console */
45 #define CVAR_CHEAT      64      /**< clamp to the default value when cheats are off */
46 #define CVAR_R_IMAGES   128     /**< effects image filtering */
47 #define CVAR_R_CONTEXT    256     /**< vid shutdown if such a cvar was modified */
48 #define CVAR_R_PROGRAMS 512		/**< if changed, shaders are restarted */
49 
50 #define CVAR_R_MASK (CVAR_R_IMAGES | CVAR_R_CONTEXT | CVAR_R_PROGRAMS)
51 
52 /**
53  * @brief Callback for the change listener
54  * @param cvarName The name of the cvar that was changed.
55  * @param oldValue The old value of the cvar - this is never @c nullptr, but can be empty.
56  * @param newValue The new value of the cvar - this is never @c nullptr, but can be empty.
57  */
58 typedef void (*cvarChangeListenerFunc_t) (const char* cvarName, const char* oldValue, const char* newValue, void* data);
59 
60 typedef struct cvarChangeListener_s {
61 	cvarChangeListenerFunc_t exec;
62 	struct cvarChangeListener_s* next;
63 	void* data;
64 } cvarChangeListener_t;
65 
66 /**
67  * @brief This is a cvar definition. Cvars can be user modified and used in our menus e.g.
68  * @note nothing outside the Cvar_*() functions should modify these fields!
69  */
70 typedef struct cvar_s {
71 	char* name;				/**< cvar name */
72 	char* string;			/**< value as string */
73 	char* latchedString;	/**< for CVAR_LATCH vars */
74 	char* defaultString;	/**< default string set on first init - only set for CVAR_CHEAT */
75 	char* oldString;		/**< value of the cvar before we changed it */
76 	char* description;		/**< cvar description */
77 	int flags;				/**< cvar flags CVAR_ARCHIVE|CVAR_NOSET.... */
78 	bool modified;			/**< set each time the cvar is changed */
79 	float value;			/**< value as float */
80 	int integer;			/**< value as integer */
81 	bool (*check) (struct cvar_s* cvar);	/**< cvar check function */
82 	cvarChangeListener_t* changeListener;
83 	struct cvar_s* next;
84 	struct cvar_s* prev;
85 	struct cvar_s* hash_next;
86 } cvar_t;
87 
88 typedef struct cvarList_s {
89 	const char* name;
90 	const char* value;
91 } cvarList_t;
92 
93 /**
94  * @brief Listener for cvar changes
95  * @param cvar The cvar that was created.
96  */
97 class CvarListener {
98 public:
~CvarListener()99 	virtual ~CvarListener() {}
100 	virtual void onCreate (const struct cvar_s* cvar) = 0;
101 	virtual void onDelete (const struct cvar_s* cvar) = 0;
102 };
103 
104 typedef SharedPtr<CvarListener> CvarListenerPtr;
105 
106 /**
107  * @brief Return the first cvar of the cvar list
108  */
109 cvar_t* Cvar_GetFirst(void);
110 
111 /**
112  * @brief creates the variable if it doesn't exist, or returns the existing one
113  * if it exists, the value will not be changed, but flags will be ORed in
114  * that allows variables to be unarchived without needing bitflags
115  */
116 cvar_t* Cvar_Get(const char* varName, const char* value = "", int flags = 0, const char* desc = nullptr);
117 
118 /**
119  * @brief will create the variable if it doesn't exist
120  */
121 cvar_t* Cvar_Set(const char* varName, const char* value, ...) __attribute__((format(__printf__, 2, 3)));
122 
123 /**
124  * @brief will set the variable even if NOSET or LATCH
125  */
126 cvar_t* Cvar_ForceSet(const char* varName, const char* value);
127 
128 cvar_t* Cvar_FullSet(const char* varName, const char* value, int flags);
129 
130 /**
131  * @brief expands value to a string and calls Cvar_Set
132  */
133 void Cvar_SetValue(const char* varName, float value);
134 
135 /**
136  * @brief returns 0 if not defined or non numeric
137  */
138 int Cvar_GetInteger(const char* varName);
139 
140 /**
141  * @brief returns 0.0 if not defined or non numeric
142  */
143 float Cvar_GetValue(const char* varName);
144 
145 /**
146  * @brief returns an empty string if not defined
147  */
148 const char* Cvar_GetString(const char* varName);
149 
150 /**
151  * @brief returns an empty string if not defined
152  */
153 const char* Cvar_VariableStringOld(const char* varName);
154 
155 /**
156  * @brief attempts to match a partial variable name for command line completion
157  * returns nullptr if nothing fits
158  */
159 int Cvar_CompleteVariable(const char* partial, const char** match);
160 
161 /**
162  * @brief any CVAR_LATCHED variables that have been set will now take effect
163  */
164 void Cvar_UpdateLatchedVars(void);
165 
166 /**
167  * @brief called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known
168  * command.  Returns true if the command was a variable reference that
169  * was handled. (print or change)
170  */
171 bool Cvar_Command(void);
172 
173 void Cvar_Init(void);
174 void Cvar_Shutdown(void);
175 
176 /**
177  * @brief returns an info string containing all the CVAR_USERINFO cvars
178  */
179 const char* Cvar_Userinfo(char* info, size_t infoSize);
180 
181 /**
182  * @brief returns an info string containing all the CVAR_SERVERINFO cvars
183  */
184 const char* Cvar_Serverinfo(char* info, size_t infoSize);
185 
186 /**
187  * @brief this function checks cvar ranges and integral values
188  */
189 bool Cvar_AssertValue(cvar_t* cvar, float minVal, float maxVal, bool shouldBeIntegral);
190 
191 /**
192  * @brief Sets the check functions for a cvar (e.g. Cvar_Assert)
193  */
194 bool Cvar_SetCheckFunction(const char* varName, bool (*check) (cvar_t* cvar));
195 
196 /**
197  * @brief Registers a listener that is executed each time a cvar changed its value.
198  * @sa Cvar_ExecuteChangeListener
199  * @param varName The cvar name to register the listener for
200  * @param listenerFunc The listener callback to register
201  */
202 cvarChangeListener_t* Cvar_RegisterChangeListener(const char* varName, cvarChangeListenerFunc_t listenerFunc);
203 
204 /**
205  * @brief Unregisters a cvar change listener
206  * @param varName The cvar name to register the listener for
207  * @param listenerFunc The listener callback to unregister
208  */
209 void Cvar_UnRegisterChangeListener(const char* varName, cvarChangeListenerFunc_t listenerFunc);
210 
211 /**
212  * @brief Registers a cvar listener
213  * @param listener The listener callback to register
214  */
215 void Cvar_RegisterCvarListener(CvarListenerPtr listener);
216 
217 /**
218  * @brief Unregisters a cvar listener
219  * @param listener The listener callback to unregister
220  */
221 void Cvar_UnRegisterCvarListener(CvarListenerPtr listener);
222 
223 /**
224  * @brief Reset cheat cvar values to default
225  */
226 void Cvar_FixCheatVars(void);
227 
228 /**
229  * @brief Function to remove the cvar and free the space
230  */
231 bool Cvar_Delete(const char* varName);
232 
233 /**
234  * @brief Searches for a cvar given by parameter
235  */
236 cvar_t* Cvar_FindVar(const char* varName);
237 
238 /**
239  * @brief Checks whether there are pending cvars for the given flags
240  * @param flags The CVAR_* flags
241  * @return true if there are pending cvars, false otherwise
242  */
243 bool Cvar_PendingCvars(int flags);
244 
245 void Com_SetUserinfoModified(bool modified);
246 
247 bool Com_IsUserinfoModified(void);
248 
249 void Com_SetRenderModified(bool modified);
250 
251 bool Com_IsRenderModified(void);
252 
253 void Cvar_ClearVars(int flags);
254 
255 void Cvar_Reset(cvar_t* cvar);
256 
257 #ifdef DEBUG
258 void Cvar_PrintDebugCvars(void);
259 #endif
260