- reworked CVARs to not use a linked list and to be initialized manually.

This solves two problems:

* The linked list is too slow, a map is better. A map cannot be used with statically allocated CVARs because order of initialization is undefined.
* The current CVAR system is an unordered mishmash of static variables and dynamically allocated ones and the means of identification are unsafe. With this everything is allocated on the heap so it can all be handled the same by the cleanup code.
This commit is contained in:
Christoph Oelckers 2022-10-21 18:28:28 +02:00
parent ef887403cf
commit 453688ccc6
28 changed files with 369 additions and 203 deletions

View file

@ -421,11 +421,11 @@ struct AMColorset
bool forcebackground;
bool defined; // only for mod specific colorsets: must be true to be usable
void initFromCVars(FColorCVar **values)
void initFromCVars(FColorCVarRef **values)
{
for(int i=0;i<AlmostBackgroundColor; i++)
{
c[i].FromCVar(*values[i]);
c[i].FromCVar(*(values[i]->get()));
}
uint32_t ba = *(values[0]);
@ -513,7 +513,7 @@ static const int AUTOMAP_LINE_COLORS[AMLS_COUNT] =
//
//=============================================================================
static FColorCVar *cv_standard[] = {
static FColorCVarRef *cv_standard[] = {
&am_backcolor,
&am_yourcolor,
&am_wallcolor,
@ -540,7 +540,7 @@ static FColorCVar *cv_standard[] = {
&am_portalcolor
};
static FColorCVar *cv_overlay[] = {
static FColorCVarRef *cv_overlay[] = {
&am_backcolor, // this will not be used in overlay mode
&am_ovyourcolor,
&am_ovwallcolor,
@ -571,11 +571,11 @@ CCMD(am_restorecolors)
{
for (unsigned i = 0; i < countof(cv_standard); i++)
{
cv_standard[i]->ResetToDefault();
cv_standard[i]->get()->ResetToDefault();
}
for (unsigned i = 0; i < countof(cv_overlay); i++)
{
cv_overlay[i]->ResetToDefault();
cv_overlay[i]->get()->ResetToDefault();
}
}

View file

@ -864,7 +864,7 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
parms->top = INT_MAX;
parms->destwidth = INT_MAX;
parms->destheight = INT_MAX;
parms->Alpha = type == DrawTexture_Fill ? fillalpha : 1.f;
parms->Alpha = type == DrawTexture_Fill ? (float)fillalpha : 1.f;
parms->fillcolor = type == DrawTexture_Fill ? fill : PalEntry(~0u);
parms->TranslationId = -1;
parms->colorOverlay = 0;

View file

@ -222,11 +222,11 @@ void I_InitMusic(void)
{
I_InitSoundFonts();
snd_musicvolume.Callback ();
snd_musicvolume->Callback ();
nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound");
snd_mididevice.Callback();
snd_mididevice->Callback();
ZMusicCallbacks callbacks{};
@ -257,7 +257,7 @@ void I_SetRelativeVolume(float vol)
{
relative_volume = (float)vol;
ChangeMusicSetting(zmusic_relative_volume, nullptr, (float)vol);
snd_musicvolume.Callback();
snd_musicvolume->Callback();
}
//==========================================================================
//

View file

@ -241,15 +241,15 @@ static bool S_StartMusicPlaying(ZMusic_MusicStream song, bool loop, float rel_vo
}
ZMusic_Stop(song);
// make sure the volume modifiers update properly in case replay gain settings have changed.
fluid_gain.Callback();
mod_dumb_mastervolume.Callback();
fluid_gain->Callback();
mod_dumb_mastervolume->Callback();
if (!ZMusic_Start(song, subsong, loop))
{
return false;
}
// Notify the sound system of the changed relative volume
snd_musicvolume.Callback();
snd_musicvolume->Callback();
return true;
}
@ -517,8 +517,8 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
{
mus_playing.replayGain = 0.f;
mus_playing.replayGainFactor = dBToAmplitude(mus_gainoffset);
fluid_gain.Callback();
mod_dumb_mastervolume.Callback();
fluid_gain->Callback();
mod_dumb_mastervolume->Callback();
if (!mus_usereplaygain) return;
FileReader reader = mus_cb.OpenMusic(musicname);

View file

@ -99,8 +99,8 @@ CUSTOM_CVAR(Float, snd_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVA
self = 1.f;
ChangeMusicSetting(zmusic_snd_mastervolume, nullptr, self);
snd_sfxvolume.Callback();
snd_musicvolume.Callback();
snd_sfxvolume->Callback();
snd_musicvolume->Callback();
}
//==========================================================================
@ -283,7 +283,7 @@ void I_InitSound ()
GSnd = new NullSoundRenderer;
Printf (TEXTCOLOR_RED"Sound init failed. Using nosound.\n");
}
snd_sfxvolume.Callback ();
snd_sfxvolume->Callback ();
}

View file

@ -469,12 +469,12 @@ static void SelectEnvironment(const char *envname)
int newid = FirstFreeID(env->ID, env->Builtin);
UCVarValue cv;
cv.Int = HIBYTE(newid);
reverbedit_id1.ForceSet(cv, CVAR_Int);
reverbedit_id1->ForceSet(cv, CVAR_Int);
cv.Int = LOBYTE(newid);
reverbedit_id2.ForceSet(cv, CVAR_Int);
reverbedit_id2->ForceSet(cv, CVAR_Int);
FString selectname = SuggestNewName(env);
cv.String = selectname.GetChars();
reverbedit_name.ForceSet(cv, CVAR_String);
reverbedit_name->ForceSet(cv, CVAR_String);
return;
}
}

View file

@ -95,7 +95,6 @@ static FTextureID conflat;
static uint32_t conshade;
static bool conline;
extern FBaseCVar *CVars;
extern FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE];
int ConWidth;
@ -178,7 +177,7 @@ static void setmsgcolor (int index, int color);
FILE *Logfile = NULL;
FIntCVar msglevel ("msg", 0, CVAR_ARCHIVE);
CVARD_NAMED(Int, msglevel, "msg", 0, CVAR_ARCHIVE, "Filters HUD message by importance");
CUSTOM_CVAR (Int, msg0color, CR_UNTRANSLATED, CVAR_ARCHIVE)
{
@ -312,22 +311,6 @@ void C_DeinitConsole ()
}
HistTail = HistHead = HistPos = NULL;
// Free cvars allocated at runtime
FBaseCVar *var, *next, **nextp;
for (var = CVars, nextp = &CVars; var != NULL; var = next)
{
next = var->m_Next;
if (var->GetFlags() & CVAR_UNSETTABLE)
{
delete var;
*nextp = next;
}
else
{
nextp = &var->m_Next;
}
}
// Free alias commands. (i.e. The "commands" that can be allocated
// at runtime.)
for (size_t i = 0; i < countof(Commands); ++i)

View file

@ -56,8 +56,6 @@ struct FLatchedValue
static TArray<FLatchedValue> LatchedValues;
FBaseCVar *CVars = NULL;
int cvar_defflags;
@ -70,6 +68,74 @@ void C_InstallHandlers(ConsoleCallbacks* cb)
callbacks = cb;
}
void C_InitCVars(int which)
{
AutoSegs::CVarDecl.ForEach([](FCVarDecl* cvInfo)
{
FBaseCVar* newcvar;
switch(cvInfo->type)
{
default:
return;
case CVAR_Int:
{
using callbacktype = void (*)(FIntCVar &);
newcvar = new FIntCVar(cvInfo->name, cvInfo->defaultval.Int, cvInfo->flags, reinterpret_cast<callbacktype>(cvInfo->callbackp), cvInfo->description);
break;
}
case CVAR_Bool:
{
using callbacktype = void (*)(FBoolCVar &);
newcvar = new FBoolCVar(cvInfo->name, cvInfo->defaultval.Bool, cvInfo->flags, reinterpret_cast<callbacktype>(cvInfo->callbackp), cvInfo->description);
break;
}
case CVAR_Float:
{
using callbacktype = void (*)(FFloatCVar &);
newcvar = new FFloatCVar(cvInfo->name, cvInfo->defaultval.Float, cvInfo->flags, reinterpret_cast<callbacktype>(cvInfo->callbackp), cvInfo->description);
break;
}
case CVAR_String:
{
using callbacktype = void (*)(FStringCVar &);
newcvar = new FStringCVar(cvInfo->name, cvInfo->defaultval.String, cvInfo->flags, reinterpret_cast<callbacktype>(cvInfo->callbackp), cvInfo->description);
break;
}
case CVAR_Flag:
{
newcvar = new FFlagCVar(cvInfo->name, *cvInfo->defaultval.Pointer->get(), cvInfo->flags, cvInfo->description);
break;
}
case CVAR_Mask:
{
newcvar = new FMaskCVar(cvInfo->name, *cvInfo->defaultval.Pointer->get(), cvInfo->flags, cvInfo->description);
break;
}
case CVAR_Color:
{
using callbacktype = void (*)(FColorCVar &);
newcvar = new FColorCVar(cvInfo->name, cvInfo->defaultval.Int, cvInfo->flags, reinterpret_cast<callbacktype>(cvInfo->callbackp), cvInfo->description);
break;
}
}
*(void**)cvInfo->refAddr = newcvar;
});
}
void C_UninitCVars()
{
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair* pair;
while (it.NextPair(pair))
{
auto var = pair->Value;
pair->Value = nullptr;
delete var;
}
}
FBaseCVar::FBaseCVar (const char *var_name, uint32_t flags, void (*callback)(FBaseCVar &), const char *descr)
{
if (var_name != nullptr && (flags & CVAR_SERVERINFO))
@ -98,8 +164,7 @@ FBaseCVar::FBaseCVar (const char *var_name, uint32_t flags, void (*callback)(FBa
var = FindCVar(var_name, NULL);
C_AddTabCommand (var_name);
VarName = var_name;
m_Next = CVars;
CVars = this;
cvarMap.Insert(var_name, this);
}
if (var)
@ -109,11 +174,7 @@ FBaseCVar::FBaseCVar (const char *var_name, uint32_t flags, void (*callback)(FBa
value = var->GetFavoriteRep (&type);
ForceSet (value, type);
if (var->Flags & CVAR_AUTO)
delete var;
else
var->~FBaseCVar();
delete var;
Flags = flags;
}
@ -133,13 +194,9 @@ FBaseCVar::~FBaseCVar ()
if (var == this)
{
if (prev)
prev->m_Next = m_Next;
else
CVars = m_Next;
}
if (var->Flags & CVAR_AUTO)
cvarMap.Remove(var->VarName);
C_RemoveTabCommand(VarName);
}
}
}
@ -522,15 +579,15 @@ void FBaseCVar::EnableNoSet ()
void FBaseCVar::EnableCallbacks ()
{
m_UseCallback = true;
FBaseCVar *cvar = CVars;
while (cvar)
CVarMap::Iterator it(cvarMap);
CVarMap::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
if (!(cvar->Flags & CVAR_NOINITCALL))
{
cvar->Callback ();
}
cvar = cvar->m_Next;
}
}
@ -883,15 +940,16 @@ int FColorCVar::ToInt2 (UCVarValue value, ECVarType type)
void FBaseCVar::ResetColors ()
{
FBaseCVar *var = CVars;
while (var)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto var = pair->Value;
if (var->GetRealType () == CVAR_Color)
{
var->DoSet (var->GetGenericRep (CVAR_Int), CVAR_Int);
}
var = var->m_Next;
}
}
@ -948,7 +1006,7 @@ BitVal (bitval)
ECVarType FFlagCVar::GetRealType () const
{
return CVAR_DummyBool;
return CVAR_Flag;
}
UCVarValue FFlagCVar::GetGenericRep (ECVarType type) const
@ -1044,7 +1102,7 @@ BitVal (bitval)
ECVarType FMaskCVar::GetRealType () const
{
return CVAR_DummyInt;
return CVAR_Mask;
}
UCVarValue FMaskCVar::GetGenericRep (ECVarType type) const
@ -1131,8 +1189,11 @@ static int sortcvars (const void *a, const void *b)
void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter)
{
// Accumulate all cvars that match the filter flags.
for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
if ((cvar->Flags & filter) && !(cvar->Flags & CVAR_IGNORE))
cvars.Push(cvar);
}
@ -1154,7 +1215,7 @@ void C_WriteCVars (uint8_t **demo_p, uint32_t filter, bool compact)
FString C_GetMassCVarString (uint32_t filter, bool compact)
{
FBaseCVar *cvar;
FBaseCVar* cvar;
FString dump;
if (compact)
@ -1170,8 +1231,11 @@ FString C_GetMassCVarString (uint32_t filter, bool compact)
}
else
{
for (cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
cvar = pair->Value;
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE|CVAR_IGNORE)))
{
UCVarValue val = cvar->GetGenericRep(CVAR_String);
@ -1263,8 +1327,11 @@ void C_BackupCVars (void)
FCVarBackup backup;
for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
if ((cvar->Flags & (CVAR_SERVERINFO|CVAR_DEMOSAVE)) && !(cvar->Flags & CVAR_LATCH))
{
backup.Name = cvar->GetName();
@ -1290,47 +1357,24 @@ void C_ForgetCVars (void)
FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev)
{
FBaseCVar *var;
FBaseCVar *dummy;
if (var_name == nullptr)
return nullptr;
if (var_name == NULL)
return NULL;
if (prev == NULL)
prev = &dummy;
var = CVars;
*prev = NULL;
while (var)
{
if (stricmp (var->GetName (), var_name) == 0)
break;
*prev = var;
var = var->m_Next;
}
return var;
FName vname(var_name, true);
if (vname == NAME_None) return nullptr;
auto find = cvarMap.CheckKey(vname);
return find? *find : nullptr;
}
FBaseCVar *FindCVarSub (const char *var_name, int namelen)
{
FBaseCVar *var;
if (var_name == NULL)
return NULL;
var = CVars;
while (var)
{
const char *probename = var->GetName ();
if (strnicmp (probename, var_name, namelen) == 0 &&
probename[namelen] == 0)
{
break;
}
var = var->m_Next;
}
return var;
FName vname(var_name, namelen, true);
if (vname == NAME_None) return nullptr;
auto find = cvarMap.CheckKey(vname);
return find ? *find : nullptr;
}
FBaseCVar *GetCVar(int playernum, const char *cvarname)
@ -1395,26 +1439,24 @@ void UnlatchCVars (void)
void DestroyCVarsFlagged (uint32_t flags)
{
FBaseCVar *cvar = CVars;
FBaseCVar *next = cvar;
while(cvar)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
next = cvar->m_Next;
auto cvar = pair->Value;
if(cvar->Flags & flags)
delete cvar;
cvar = next;
}
}
void C_SetCVarsToDefaults (void)
{
FBaseCVar *cvar = CVars;
while (cvar)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
// Only default save-able cvars
if (cvar->Flags & CVAR_ARCHIVE)
{
@ -1423,7 +1465,6 @@ void C_SetCVarsToDefaults (void)
val = cvar->GetFavoriteRepDefault (&type);
cvar->SetGenericRep (val, type);
}
cvar = cvar->m_Next;
}
}
@ -1436,18 +1477,19 @@ static int cvarcmp(const void* a, const void* b)
void C_ArchiveCVars (FConfigFile *f, uint32_t filter)
{
FBaseCVar *cvar = CVars;
TArray<FBaseCVar*> cvarlist;
while (cvar)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
if ((cvar->Flags &
(CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_MOD|CVAR_AUTO|CVAR_USERINFO|CVAR_SERVERINFO|CVAR_NOSAVE|CVAR_CONFIG_ONLY))
== filter)
{
cvarlist.Push(cvar);
}
cvar = cvar->m_Next;
}
qsort(cvarlist.Data(), cvarlist.Size(), sizeof(FBaseCVar*), cvarcmp);
for (auto cv : cvarlist)
@ -1591,11 +1633,13 @@ CCMD (toggle)
void FBaseCVar::ListVars (const char *filter, bool plain)
{
FBaseCVar *var = CVars;
int count = 0;
while (var)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto var = pair->Value;
if (CheckWildcards (filter, var->GetName()))
{
uint32_t flags = var->GetFlags();
@ -1624,7 +1668,6 @@ void FBaseCVar::ListVars (const char *filter, bool plain)
var->GetHumanString());
}
}
var = var->m_Next;
}
Printf ("%d cvars\n", count);
}
@ -1666,15 +1709,15 @@ CCMD (archivecvar)
void C_ListCVarsWithoutDescription()
{
FBaseCVar* var = CVars;
while (var)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto var = pair->Value;
if (var->GetDescription().IsEmpty())
{
Printf("%s\n", var->GetName());
}
var = var->m_Next;
}
}

View file

@ -35,6 +35,8 @@
#define __C_CVARS_H__
#include "zstring.h"
#include "tarray.h"
#include "autosegs.h"
#include "name.h"
class FSerializer; // this needs to go away.
/*
@ -72,18 +74,22 @@ enum
CVAR_CONFIG_ONLY = 1 << 18, // do not save var to savegame and do not send it across network.
};
class FIntCVarRef;
union UCVarValue
{
bool Bool;
int Int;
float Float;
const char* String;
FIntCVarRef* Pointer;
UCVarValue() = default;
UCVarValue(bool v) { Bool = v; }
UCVarValue(int v) { Int = v; }
UCVarValue(float v) { Float = v; }
UCVarValue(const char * v) { String = v; }
constexpr UCVarValue(bool v) : Bool(v) { }
constexpr UCVarValue(int v) : Int(v) { }
constexpr UCVarValue(float v) : Float(v) { }
constexpr UCVarValue(double v) : Float(float(v)) { }
constexpr UCVarValue(const char * v) : String(v) { }
constexpr UCVarValue(FIntCVarRef& v);
};
enum ECVarType
@ -93,9 +99,9 @@ enum ECVarType
CVAR_Float,
CVAR_String,
CVAR_Color, // stored as CVAR_Int
CVAR_DummyBool, // just redirects to another cvar
CVAR_DummyInt, // just redirects to another cvar
CVAR_Dummy // Unknown
CVAR_Flag, // just redirects to another cvar
CVAR_Mask, // just redirects to another cvar
CVAR_Dummy, // Unknown
};
class FConfigFile;
@ -104,6 +110,9 @@ class FxCVar;
class FBaseCVar;
using CVarMap = TMap<FName, FBaseCVar*>;
inline CVarMap cvarMap;
// These are calls into the game code. Having these hard coded in the CVAR implementation has always been the biggest blocker
// for reusing the CVAR module outside of ZDoom. So now they get called through this struct for easier reusability.
struct ConsoleCallbacks
@ -134,7 +143,6 @@ public:
inline const char *GetName () const { return VarName.GetChars(); }
inline uint32_t GetFlags () const { return Flags; }
inline FBaseCVar *GetNext() const { return m_Next; }
void CmdSet (const char *newval);
void ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend=false);
@ -214,7 +222,6 @@ private:
FBaseCVar (const FBaseCVar &var) = delete;
FBaseCVar (const char *name, uint32_t flags);
void (*m_Callback)(FBaseCVar &);
FBaseCVar *m_Next;
static inline bool m_UseCallback = false;
static inline bool m_DoNoSet = false;
@ -279,6 +286,8 @@ void C_SetCVarsToDefaults (void);
void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter);
void C_DeinitConsole();
void C_InitCVars(int which);
void C_UninitCVars();
class FBoolCVar : public FBaseCVar
{
@ -465,6 +474,88 @@ protected:
int BitNum;
};
class FBoolCVarRef
{
FBoolCVar* ref;
public:
inline bool operator= (bool val) { *ref = val; return val; }
inline operator bool () const { return **ref; }
inline bool operator *() const { return **ref; }
inline FBoolCVar* operator->() { return ref; }
inline FBoolCVar* get() { return ref; }
};
class FIntCVarRef
{
FIntCVar* ref;
public:
int operator= (int val) { *ref = val; return val; }
inline operator int () const { return **ref; }
inline int operator *() const { return **ref; }
inline FIntCVar* operator->() { return ref; }
inline FIntCVar* get() { return ref; }
};
class FFloatCVarRef
{
FFloatCVar* ref;
public:
float operator= (float val) { *ref = val; return val; }
inline operator float () const { return **ref; }
inline float operator *() const { return **ref; }
inline FFloatCVar* operator->() { return ref; }
inline FFloatCVar* get() { return ref; }
};
class FStringCVarRef
{
FStringCVar* ref;
public:
const char* operator= (const char* val) { *ref = val; return val; }
inline operator const char* () const { return **ref; }
inline const char* operator *() const { return **ref; }
inline FStringCVar* operator->() { return ref; }
inline FStringCVar* get() { return ref; }
};
class FColorCVarRef
{
FColorCVar* ref;
public:
//uint32_t operator= (uint32_t val) { *ref = val; return val; }
inline operator uint32_t () const { return **ref; }
inline uint32_t operator *() const { return **ref; }
inline FColorCVar* operator->() { return ref; }
inline FColorCVar* get() { return ref; }
};
class FFlagCVarRef
{
FFlagCVar* ref;
public:
inline bool operator= (bool val) { *ref = val; return val; }
inline bool operator= (const FFlagCVar& val) { *ref = val; return val; }
inline operator int () const { return **ref; }
inline int operator *() const { return **ref; }
inline FFlagCVar& operator->() { return *ref; }
};
class FMaskCVarRef
{
FMaskCVar* ref;
public:
//int operator= (int val) { *ref = val; return val; }
inline operator int () const { return **ref; }
inline int operator *() const { return **ref; }
inline FMaskCVar& operator->() { return *ref; }
};
extern int cvar_defflags;
FBaseCVar *cvar_set (const char *var_name, const char *value);
@ -473,6 +564,18 @@ FBaseCVar *cvar_forceset (const char *var_name, const char *value);
inline FBaseCVar *cvar_set (const char *var_name, const uint8_t *value) { return cvar_set (var_name, (const char *)value); }
inline FBaseCVar *cvar_forceset (const char *var_name, const uint8_t *value) { return cvar_forceset (var_name, (const char *)value); }
constexpr UCVarValue::UCVarValue(FIntCVarRef& v) : Pointer(&v) { }
struct FCVarDecl
{
void * refAddr;
ECVarType type;
unsigned int flags;
const char * name;
UCVarValue defaultval;
const char *description;
void* callbackp; // actually a function pointer with unspecified arguments. C++ does not like that much...
};
// Restore demo cvars. Called after demo playback to restore all cvars
@ -482,35 +585,59 @@ void C_RestoreCVars (void);
void C_ForgetCVars (void);
#if defined(_MSC_VER)
#pragma section(SECTION_VREG,read)
#define MSVC_VSEG __declspec(allocate(SECTION_VREG))
#define GCC_VSEG
#else
#define MSVC_VSEG
#define GCC_VSEG __attribute__((section(SECTION_VREG))) __attribute__((used))
#endif
#define CUSTOM_CVAR(type,name,def,flags) \
static void cvarfunc_##name(F##type##CVar &); \
F##type##CVar name (#name, def, flags, cvarfunc_##name); \
F##type##CVarRef name; \
static FCVarDecl cvardecl_##name = { &name, CVAR_##type, (flags), #name, def, nullptr, reinterpret_cast<void*>(cvarfunc_##name) }; \
extern FCVarDecl const *const cvardeclref_##name; \
MSVC_VSEG FCVarDecl const *const cvardeclref_##name GCC_VSEG = &cvardecl_##name; \
static void cvarfunc_##name(F##type##CVar &self)
#define CUSTOM_CVAR_NAMED(type,name,cname,def,flags) \
static void cvarfunc_##name(F##type##CVar &); \
F##type##CVar name (#cname, def, flags, cvarfunc_##name); \
F##type##CVarRef name; \
static FCVarDecl cvardecl_##name = { &name, CVAR_##type, (flags), #cname, def, nullptr, reinterpret_cast<void*>(cvarfunc_##name) }; \
extern FCVarDecl const *const cvardeclref_##name; \
MSVC_VSEG FCVarDecl const *const cvardeclref_##name GCC_VSEG = &cvardecl_##name; \
static void cvarfunc_##name(F##type##CVar &self)
#define CVAR(type,name,def,flags) \
F##type##CVar name (#name, def, flags);
F##type##CVarRef name; \
static FCVarDecl cvardecl_##name = { &name, CVAR_##type, (flags), #name, def, nullptr, nullptr}; \
extern FCVarDecl const *const cvardeclref_##name; \
MSVC_VSEG FCVarDecl const *const cvardeclref_##name GCC_VSEG = &cvardecl_##name;
#define EXTERN_CVAR(type,name) extern F##type##CVar name;
#define EXTERN_CVAR(type,name) extern F##type##CVarRef name;
#define CUSTOM_CVARD(type,name,def,flags,descr) \
static void cvarfunc_##name(F##type##CVar &); \
F##type##CVar name (#name, def, flags, cvarfunc_##name, descr); \
F##type##CVarRef name; \
static FCVarDecl cvardecl_##name = { &name, CVAR_##type, (flags), #name, def, descr, reinterpret_cast<void*>(cvarfunc_##name) }; \
extern FCVarDecl const *const cvardeclref_##name; \
MSVC_VSEG FCVarDecl const *const cvardeclref_##name GCC_VSEG = &cvardecl_##name; \
static void cvarfunc_##name(F##type##CVar &self)
#define CVARD(type,name,def,flags, descr) \
F##type##CVar name (#name, def, flags, nullptr, descr);
F##type##CVarRef name; \
static FCVarDecl cvardecl_##name = { &name, CVAR_##type, (flags), #name, def, descr, nullptr}; \
extern FCVarDecl const *const cvardeclref_##name; \
MSVC_VSEG FCVarDecl const *const cvardeclref_##name GCC_VSEG = &cvardecl_##name;
#define CVARD_NAMED(type,name,varname,def,flags, descr) \
F##type##CVar varname (#name, def, flags, nullptr, descr);
#define CVAR_UNAMED(type,varname) \
F##type##CVar varname (nullptr, 0, 0, nullptr, nullptr);
extern FBaseCVar *CVars;
F##type##CVarRef name; \
static FCVarDecl cvardecl_##name = { &name, CVAR_##type, (flags), #varname, def, descr, nullptr}; \
extern FCVarDecl const *const cvardeclref_##name; \
MSVC_VSEG FCVarDecl const *const cvardeclref_##name GCC_VSEG = &cvardecl_##name;
#endif //__C_CVARS_H__

View file

@ -62,9 +62,9 @@ EXTERN_CVAR(Bool, joy_xinput)
CUSTOM_CVARD(Bool, use_joystick, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL, "enables input from the joystick if it is present")
{
#ifdef _WIN32
joy_ps2raw.Callback();
joy_dinput.Callback();
joy_xinput.Callback();
joy_ps2raw->Callback();
joy_dinput->Callback();
joy_xinput->Callback();
#endif
}

View file

@ -74,6 +74,7 @@ AUTOSEG_VARIABLE(TypeInfos, AUTOSEG_CREG)
AUTOSEG_VARIABLE(ClassFields, AUTOSEG_FREG)
AUTOSEG_VARIABLE(Properties, AUTOSEG_GREG)
AUTOSEG_VARIABLE(MapInfoOptions, AUTOSEG_YREG)
AUTOSEG_VARIABLE(CVarDecl, AUTOSEG_VREG)
#undef AUTOSEG_VARIABLE
#undef AUTOSEG_STOP

View file

@ -148,6 +148,7 @@ namespace AutoSegs
extern FAutoSeg ClassFields;
extern FAutoSeg Properties;
extern FAutoSeg MapInfoOptions;
extern FAutoSeg CVarDecl;
}
#define AUTOSEG_AREG areg
@ -155,6 +156,7 @@ namespace AutoSegs
#define AUTOSEG_FREG freg
#define AUTOSEG_GREG greg
#define AUTOSEG_YREG yreg
#define AUTOSEG_VREG vreg
#define AUTOSEG_STR(string) AUTOSEG_STR2(string)
#define AUTOSEG_STR2(string) #string
@ -167,12 +169,14 @@ namespace AutoSegs
#define SECTION_FREG AUTOSEG_MACH_SECTION(AUTOSEG_FREG)
#define SECTION_GREG AUTOSEG_MACH_SECTION(AUTOSEG_GREG)
#define SECTION_YREG AUTOSEG_MACH_SECTION(AUTOSEG_YREG)
#define SECTION_VREG AUTOSEG_MACH_SECTION(AUTOSEG_VREG)
#else
#define SECTION_AREG AUTOSEG_STR(AUTOSEG_AREG)
#define SECTION_CREG AUTOSEG_STR(AUTOSEG_CREG)
#define SECTION_FREG AUTOSEG_STR(AUTOSEG_FREG)
#define SECTION_GREG AUTOSEG_STR(AUTOSEG_GREG)
#define SECTION_YREG AUTOSEG_STR(AUTOSEG_YREG)
#define SECTION_VREG AUTOSEG_STR(AUTOSEG_VREG)
#endif
#endif

View file

@ -112,7 +112,7 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : Syst
EXTERN_CVAR(Bool, vid_vsync);
CUSTOM_CVAR(Bool, gl_control_tear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
vid_vsync.Callback();
vid_vsync->Callback();
}
void SystemGLFrameBuffer::SetVSync (bool vsync)

View file

@ -399,7 +399,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
// If regional settings were changed, reget preferred languages
if (wParam == 0 && lParam != 0 && strcmp ((const char *)lParam, "intl") == 0)
{
language.Callback ();
language->Callback ();
}
return 0;

View file

@ -394,7 +394,7 @@ void V_Init2()
UCVarValue val;
val.Bool = !!Args->CheckParm("-devparm");
ticker.SetGenericRepDefault(val, CVAR_Bool);
ticker->SetGenericRepDefault(val, CVAR_Bool);
I_InitGraphics();

View file

@ -6715,12 +6715,12 @@ FxExpression *FxCVar::Resolve(FCompileContext &ctx)
switch (CVar->GetRealType())
{
case CVAR_Bool:
case CVAR_DummyBool:
case CVAR_Flag:
ValueType = TypeBool;
break;
case CVAR_Int:
case CVAR_DummyInt:
case CVAR_Mask:
ValueType = TypeSInt32;
break;
@ -6776,7 +6776,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
build->Emit(OP_LS, dest.RegNum, addr.RegNum, nul);
break;
case CVAR_DummyBool:
case CVAR_Flag:
{
int *pVal;
auto cv = static_cast<FFlagCVar *>(CVar);
@ -6789,7 +6789,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
break;
}
case CVAR_DummyInt:
case CVAR_Mask:
{
auto cv = static_cast<FMaskCVar *>(CVar);
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value));

View file

@ -86,7 +86,7 @@ CVAR (String, chatmacro8, "I'll take care of it.", CVAR_ARCHIVE)
CVAR (String, chatmacro9, "Yes", CVAR_ARCHIVE)
CVAR (String, chatmacro0, "No", CVAR_ARCHIVE)
FStringCVar *chat_macros[10] =
FStringCVarRef *chat_macros[10] =
{
&chatmacro0,
&chatmacro1,

View file

@ -1181,7 +1181,7 @@ void D_DoomLoop ()
Subtitle = nullptr;
Advisory.SetInvalid();
vid_cursor.Callback();
vid_cursor->Callback();
for (;;)
{
@ -3697,7 +3697,7 @@ int GameMain()
G_GetUserCVar,
[]() { return gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP; }
};
C_InitCVars(0);
C_InstallHandlers(&cb);
SetConsoleNotifyBuffer();
@ -3728,6 +3728,7 @@ int GameMain()
I_ShutdownInput();
M_SaveDefaultsFinal();
DeleteStartupScreen();
C_UninitCVars(); // must come last so that nothing will access the CVARs anymore after deletion.
delete Args;
Args = nullptr;
return ret;

View file

@ -396,8 +396,11 @@ void D_SetupUserInfo ()
// Initialize the console player's user info
coninfo = &players[consoleplayer].userinfo;
for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->GetNext())
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
if ((cvar->GetFlags() & (CVAR_USERINFO|CVAR_IGNORE)) == CVAR_USERINFO)
{
FBaseCVar **newcvar;
@ -434,8 +437,11 @@ void userinfo_t::Reset()
Clear();
// Create userinfo vars for this player, initialized to their defaults.
for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->GetNext())
decltype(cvarMap)::Iterator it2(cvarMap);
decltype(cvarMap)::Pair *pair2;
while (it2.NextPair(pair2))
{
auto cvar = pair2->Value;
if ((cvar->GetFlags() & (CVAR_USERINFO|CVAR_IGNORE)) == CVAR_USERINFO)
{
ECVarType type;
@ -528,7 +534,8 @@ void D_UserInfoChanged (FBaseCVar *cvar)
FString escaped_val;
char foo[256];
if (cvar == &autoaim)
#if 0
if (cvar == autoaim->get())
{
if (autoaim < 0.0f)
{
@ -541,6 +548,7 @@ void D_UserInfoChanged (FBaseCVar *cvar)
return;
}
}
#endif
val = cvar->GetGenericRep (CVAR_String);
escaped_val = D_EscapeUserInfo(val.String);
@ -604,7 +612,8 @@ static const char *SetServerVar (char *name, ECVarType type, uint8_t **stream, b
delete[] value.String;
}
if (var == &teamplay)
#if 0
if (var == teamplay->get())
{
// Put players on teams if teamplay turned on
for (int i = 0; i < MAXPLAYERS; ++i)
@ -615,6 +624,7 @@ static const char *SetServerVar (char *name, ECVarType type, uint8_t **stream, b
}
}
}
#endif
if (var)
{

View file

@ -102,7 +102,7 @@ enum ESkillLevels
#include "keydef.h"
// [RH] dmflags bits (based on Q2's)
enum
enum : unsigned
{
DF_NO_HEALTH = 1 << 0, // Do not spawn health items (DM)
DF_NO_ITEMS = 1 << 1, // Do not spawn powerups (DM)
@ -136,11 +136,11 @@ enum
DF_COOP_LOSE_POWERUPS = 1 << 28, // Lose powerups when respawning in coop
DF_COOP_LOSE_AMMO = 1 << 29, // Lose ammo when respawning in coop
DF_COOP_HALVE_AMMO = 1 << 30, // Lose half your ammo when respawning in coop (but not less than the normal starting amount)
DF_INSTANT_REACTION = 1 << 31, // Monsters react instantly
DF_INSTANT_REACTION = 1u << 31, // Monsters react instantly
};
// [BC] More dmflags. w00p!
enum
enum : unsigned
{
// DF2_YES_IMPALING = 1 << 0, // Player gets impaled on MF2_IMPALE items
DF2_YES_WEAPONDROP = 1 << 1, // Drop current weapon upon death
@ -173,7 +173,7 @@ enum
DF2_NO_COOP_THING_SPAWN = 1 << 28, // Don't spawn multiplayer things in coop games
DF2_ALWAYS_SPAWN_MULTI = 1 << 29, // Always spawn multiplayer items
DF2_NOVERTSPREAD = 1 << 30, // Don't allow vertical spread for hitscan weapons (excluding ssg)
DF2_NO_EXTRA_AMMO = 1 << 31, // Don't add extra ammo when picking up weapons (like in original Doom)
DF2_NO_EXTRA_AMMO = 1u << 31, // Don't add extra ammo when picking up weapons (like in original Doom)
};
// [RH] Compatibility flags.

View file

@ -113,7 +113,7 @@ void G_DoQuickSave ();
void STAT_Serialize(FSerializer &file);
bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompressedBuffer> &content);
FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH);
CVARD_NAMED(Int, gameskill, skill, 2, CVAR_SERVERINFO|CVAR_LATCH, "sets the skill for the next newly started game")
CVAR(Bool, save_formatted, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // use formatted JSON for saves (more readable but a larger files and a bit slower.
CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH);
CVAR (Bool, chasedemo, false, 0);
@ -196,7 +196,7 @@ EXTERN_CVAR (Int, turnspeedwalkslow)
EXTERN_CVAR (Int, turnspeedsprintslow)
int forwardmove[2], sidemove[2];
FIntCVar *angleturn[4] = {&turnspeedwalkfast, &turnspeedsprintfast, &turnspeedwalkslow, &turnspeedsprintslow};
FIntCVarRef *angleturn[4] = {&turnspeedwalkfast, &turnspeedsprintfast, &turnspeedwalkslow, &turnspeedsprintslow};
int flyspeed[2] = {1*256, 3*256};
int lookspeed[2] = {450, 512};
@ -1925,8 +1925,12 @@ void C_SerializeCVars(FSerializer& arc, const char* label, uint32_t filter)
{
if (arc.isWriting())
{
for (cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_CONFIG_ONLY)))
{
UCVarValue val = cvar->GetGenericRep(CVAR_String);
@ -1937,8 +1941,11 @@ void C_SerializeCVars(FSerializer& arc, const char* label, uint32_t filter)
}
else
{
for (cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
decltype(cvarMap)::Iterator it(cvarMap);
decltype(cvarMap)::Pair *pair;
while (it.NextPair(pair))
{
auto cvar = pair->Value;
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_CONFIG_ONLY)))
{
UCVarValue val;
@ -2255,7 +2262,7 @@ void G_DoAutoSave ()
}
num.Int = nextautosave;
autosavenum.ForceSet (num, CVAR_Int);
autosavenum->ForceSet (num, CVAR_Int);
file = G_BuildSaveName ("auto", nextautosave);
@ -2294,7 +2301,7 @@ void G_DoQuickSave ()
}
num.Int = lastquicksave;
quicksavenum.ForceSet (num, CVAR_Int);
quicksavenum->ForceSet (num, CVAR_Int);
file = G_BuildSaveName ("quick", lastquicksave);

View file

@ -1369,7 +1369,7 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au
{
UCVarValue val;
val.Int = NextSkill;
gameskill.ForceSet (val, CVAR_Int);
gameskill->ForceSet (val, CVAR_Int);
NextSkill = -1;
}
@ -1861,8 +1861,8 @@ void FLevelLocals::Init()
pixelstretch = info->pixelstretch;
compatflags.Callback();
compatflags2.Callback();
compatflags->Callback();
compatflags2->Callback();
DefaultEnvironment = info->DefaultEnvironment;

View file

@ -85,7 +85,6 @@ EXTERN_CVAR (Bool, am_showsecrets)
EXTERN_CVAR (Bool, am_showitems)
EXTERN_CVAR (Bool, am_showtime)
EXTERN_CVAR (Bool, am_showtotaltime)
EXTERN_CVAR (Bool, noisedebug)
EXTERN_CVAR(Bool, inter_subtitles)
EXTERN_CVAR(Bool, ui_screenborder_classic_scaling)
@ -1225,11 +1224,6 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
DrawConsistancy ();
DrawWaiting ();
if ((ShowLog && MustDrawLog(state)) || (inter_subtitles && CPlayer->SubtitleCounter > 0)) DrawLog ();
if (noisedebug)
{
S_NoiseDebug ();
}
}

View file

@ -922,40 +922,40 @@ void FGameConfigFile::SetRavenDefaults (bool isHexen)
UCVarValue val;
val.Bool = false;
wi_percents.SetGenericRepDefault (val, CVAR_Bool);
wi_percents->SetGenericRepDefault (val, CVAR_Bool);
val.Bool = true;
con_centernotify.SetGenericRepDefault (val, CVAR_Bool);
snd_pitched.SetGenericRepDefault (val, CVAR_Bool);
con_centernotify->SetGenericRepDefault (val, CVAR_Bool);
snd_pitched->SetGenericRepDefault (val, CVAR_Bool);
val.Int = 9;
msg0color.SetGenericRepDefault (val, CVAR_Int);
msg0color->SetGenericRepDefault (val, CVAR_Int);
val.Int = CR_WHITE;
msgmidcolor.SetGenericRepDefault (val, CVAR_Int);
msgmidcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = CR_YELLOW;
msgmidcolor2.SetGenericRepDefault (val, CVAR_Int);
msgmidcolor2->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0x543b17;
am_wallcolor.SetGenericRepDefault (val, CVAR_Int);
am_wallcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0xd0b085;
am_fdwallcolor.SetGenericRepDefault (val, CVAR_Int);
am_fdwallcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0x734323;
am_cdwallcolor.SetGenericRepDefault (val, CVAR_Int);
am_cdwallcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0;
wipetype.SetGenericRepDefault(val, CVAR_Int);
wipetype->SetGenericRepDefault(val, CVAR_Int);
// Fix the Heretic/Hexen automap colors so they are correct.
// (They were wrong on older versions.)
if (*am_wallcolor == 0x2c1808 && *am_fdwallcolor == 0x887058 && *am_cdwallcolor == 0x4c3820)
{
am_wallcolor.ResetToDefault ();
am_fdwallcolor.ResetToDefault ();
am_cdwallcolor.ResetToDefault ();
am_wallcolor->ResetToDefault ();
am_fdwallcolor->ResetToDefault ();
am_cdwallcolor->ResetToDefault ();
}
if (!isHexen)
{
val.Int = 0x3f6040;
color.SetGenericRepDefault (val, CVAR_Int);
color->SetGenericRepDefault (val, CVAR_Int);
}
}
@ -963,7 +963,7 @@ void FGameConfigFile::SetStrifeDefaults ()
{
UCVarValue val;
val.Int = 3;
wipetype.SetGenericRepDefault(val, CVAR_Int);
wipetype->SetGenericRepDefault(val, CVAR_Int);
}
CCMD (whereisini)

View file

@ -470,7 +470,7 @@ void FMapInfoParser::ParseGameInfo()
SkipToNext();
}
}
turbo.Callback();
turbo->Callback();
}
const char *gameinfo_t::GetFinalePage(unsigned int num) const

View file

@ -134,7 +134,7 @@ namespace swrenderer
mysnprintf(temp, countof(temp), "%d x %d", viewwidth, viewheight);
value.String = temp;
r_viewsize.ForceSet(value, CVAR_String);
r_viewsize->ForceSet(value, CVAR_String);
}
fuzzviewheight = viewheight - 2; // Maximum row the fuzzer can draw to

View file

@ -70,9 +70,6 @@
// PUBLIC DATA DEFINITIONS -------------------------------------------------
FBoolCVar noisedebug("noise", false, 0); // [RH] Print sound debugging info?
static FString LastLocalSndInfo;
static FString LastLocalSndSeq;
void S_AddLocalSndInfo(int lump);
@ -1321,9 +1318,10 @@ void DoomSoundEngine::NoiseDebug()
}
}
void S_NoiseDebug(void)
ADD_STAT(sounddebug)
{
static_cast<DoomSoundEngine*>(soundEngine)->NoiseDebug();
return "";
}

View file

@ -38,7 +38,6 @@
#include "d_main.h"
EXTERN_CVAR (Bool, ticker);
EXTERN_CVAR (Bool, noisedebug);
EXTERN_CVAR (Int, am_cheat);
EXTERN_CVAR (Int, cl_blockcheats);
@ -525,7 +524,6 @@ static bool Cht_Ticker (cheatseq_t *cheat)
static bool Cht_Sound (cheatseq_t *cheat)
{
noisedebug = !noisedebug;
Printf ("%s\n", GStrings(noisedebug ? "TXT_CHEATSOUNDON" : "TXT_CHEATSOUNDOFF"));
AddCommandString("stat sounddebug");
return true;
}