- 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 forcebackground;
bool defined; // only for mod specific colorsets: must be true to be usable 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++) for(int i=0;i<AlmostBackgroundColor; i++)
{ {
c[i].FromCVar(*values[i]); c[i].FromCVar(*(values[i]->get()));
} }
uint32_t ba = *(values[0]); 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_backcolor,
&am_yourcolor, &am_yourcolor,
&am_wallcolor, &am_wallcolor,
@ -540,7 +540,7 @@ static FColorCVar *cv_standard[] = {
&am_portalcolor &am_portalcolor
}; };
static FColorCVar *cv_overlay[] = { static FColorCVarRef *cv_overlay[] = {
&am_backcolor, // this will not be used in overlay mode &am_backcolor, // this will not be used in overlay mode
&am_ovyourcolor, &am_ovyourcolor,
&am_ovwallcolor, &am_ovwallcolor,
@ -571,11 +571,11 @@ CCMD(am_restorecolors)
{ {
for (unsigned i = 0; i < countof(cv_standard); i++) 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++) 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->top = INT_MAX;
parms->destwidth = INT_MAX; parms->destwidth = INT_MAX;
parms->destheight = 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->fillcolor = type == DrawTexture_Fill ? fill : PalEntry(~0u);
parms->TranslationId = -1; parms->TranslationId = -1;
parms->colorOverlay = 0; parms->colorOverlay = 0;

View file

@ -222,11 +222,11 @@ void I_InitMusic(void)
{ {
I_InitSoundFonts(); I_InitSoundFonts();
snd_musicvolume.Callback (); snd_musicvolume->Callback ();
nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound"); nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound");
snd_mididevice.Callback(); snd_mididevice->Callback();
ZMusicCallbacks callbacks{}; ZMusicCallbacks callbacks{};
@ -257,7 +257,7 @@ void I_SetRelativeVolume(float vol)
{ {
relative_volume = (float)vol; relative_volume = (float)vol;
ChangeMusicSetting(zmusic_relative_volume, nullptr, (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); ZMusic_Stop(song);
// make sure the volume modifiers update properly in case replay gain settings have changed. // make sure the volume modifiers update properly in case replay gain settings have changed.
fluid_gain.Callback(); fluid_gain->Callback();
mod_dumb_mastervolume.Callback(); mod_dumb_mastervolume->Callback();
if (!ZMusic_Start(song, subsong, loop)) if (!ZMusic_Start(song, subsong, loop))
{ {
return false; return false;
} }
// Notify the sound system of the changed relative volume // Notify the sound system of the changed relative volume
snd_musicvolume.Callback(); snd_musicvolume->Callback();
return true; return true;
} }
@ -517,8 +517,8 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
{ {
mus_playing.replayGain = 0.f; mus_playing.replayGain = 0.f;
mus_playing.replayGainFactor = dBToAmplitude(mus_gainoffset); mus_playing.replayGainFactor = dBToAmplitude(mus_gainoffset);
fluid_gain.Callback(); fluid_gain->Callback();
mod_dumb_mastervolume.Callback(); mod_dumb_mastervolume->Callback();
if (!mus_usereplaygain) return; if (!mus_usereplaygain) return;
FileReader reader = mus_cb.OpenMusic(musicname); 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; self = 1.f;
ChangeMusicSetting(zmusic_snd_mastervolume, nullptr, self); ChangeMusicSetting(zmusic_snd_mastervolume, nullptr, self);
snd_sfxvolume.Callback(); snd_sfxvolume->Callback();
snd_musicvolume.Callback(); snd_musicvolume->Callback();
} }
//========================================================================== //==========================================================================
@ -283,7 +283,7 @@ void I_InitSound ()
GSnd = new NullSoundRenderer; GSnd = new NullSoundRenderer;
Printf (TEXTCOLOR_RED"Sound init failed. Using nosound.\n"); 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); int newid = FirstFreeID(env->ID, env->Builtin);
UCVarValue cv; UCVarValue cv;
cv.Int = HIBYTE(newid); cv.Int = HIBYTE(newid);
reverbedit_id1.ForceSet(cv, CVAR_Int); reverbedit_id1->ForceSet(cv, CVAR_Int);
cv.Int = LOBYTE(newid); cv.Int = LOBYTE(newid);
reverbedit_id2.ForceSet(cv, CVAR_Int); reverbedit_id2->ForceSet(cv, CVAR_Int);
FString selectname = SuggestNewName(env); FString selectname = SuggestNewName(env);
cv.String = selectname.GetChars(); cv.String = selectname.GetChars();
reverbedit_name.ForceSet(cv, CVAR_String); reverbedit_name->ForceSet(cv, CVAR_String);
return; return;
} }
} }

View file

@ -95,7 +95,6 @@ static FTextureID conflat;
static uint32_t conshade; static uint32_t conshade;
static bool conline; static bool conline;
extern FBaseCVar *CVars;
extern FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; extern FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE];
int ConWidth; int ConWidth;
@ -178,7 +177,7 @@ static void setmsgcolor (int index, int color);
FILE *Logfile = NULL; 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) CUSTOM_CVAR (Int, msg0color, CR_UNTRANSLATED, CVAR_ARCHIVE)
{ {
@ -312,22 +311,6 @@ void C_DeinitConsole ()
} }
HistTail = HistHead = HistPos = NULL; 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 // Free alias commands. (i.e. The "commands" that can be allocated
// at runtime.) // at runtime.)
for (size_t i = 0; i < countof(Commands); ++i) for (size_t i = 0; i < countof(Commands); ++i)

View file

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

View file

@ -35,6 +35,8 @@
#define __C_CVARS_H__ #define __C_CVARS_H__
#include "zstring.h" #include "zstring.h"
#include "tarray.h" #include "tarray.h"
#include "autosegs.h"
#include "name.h"
class FSerializer; // this needs to go away. 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. CVAR_CONFIG_ONLY = 1 << 18, // do not save var to savegame and do not send it across network.
}; };
class FIntCVarRef;
union UCVarValue union UCVarValue
{ {
bool Bool; bool Bool;
int Int; int Int;
float Float; float Float;
const char* String; const char* String;
FIntCVarRef* Pointer;
UCVarValue() = default; UCVarValue() = default;
UCVarValue(bool v) { Bool = v; } constexpr UCVarValue(bool v) : Bool(v) { }
UCVarValue(int v) { Int = v; } constexpr UCVarValue(int v) : Int(v) { }
UCVarValue(float v) { Float = v; } constexpr UCVarValue(float v) : Float(v) { }
UCVarValue(const char * v) { String = v; } constexpr UCVarValue(double v) : Float(float(v)) { }
constexpr UCVarValue(const char * v) : String(v) { }
constexpr UCVarValue(FIntCVarRef& v);
}; };
enum ECVarType enum ECVarType
@ -93,9 +99,9 @@ enum ECVarType
CVAR_Float, CVAR_Float,
CVAR_String, CVAR_String,
CVAR_Color, // stored as CVAR_Int CVAR_Color, // stored as CVAR_Int
CVAR_DummyBool, // just redirects to another cvar CVAR_Flag, // just redirects to another cvar
CVAR_DummyInt, // just redirects to another cvar CVAR_Mask, // just redirects to another cvar
CVAR_Dummy // Unknown CVAR_Dummy, // Unknown
}; };
class FConfigFile; class FConfigFile;
@ -104,6 +110,9 @@ class FxCVar;
class FBaseCVar; 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 // 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. // for reusing the CVAR module outside of ZDoom. So now they get called through this struct for easier reusability.
struct ConsoleCallbacks struct ConsoleCallbacks
@ -134,7 +143,6 @@ public:
inline const char *GetName () const { return VarName.GetChars(); } inline const char *GetName () const { return VarName.GetChars(); }
inline uint32_t GetFlags () const { return Flags; } inline uint32_t GetFlags () const { return Flags; }
inline FBaseCVar *GetNext() const { return m_Next; }
void CmdSet (const char *newval); void CmdSet (const char *newval);
void ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend=false); void ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend=false);
@ -214,7 +222,6 @@ private:
FBaseCVar (const FBaseCVar &var) = delete; FBaseCVar (const FBaseCVar &var) = delete;
FBaseCVar (const char *name, uint32_t flags); FBaseCVar (const char *name, uint32_t flags);
void (*m_Callback)(FBaseCVar &); void (*m_Callback)(FBaseCVar &);
FBaseCVar *m_Next;
static inline bool m_UseCallback = false; static inline bool m_UseCallback = false;
static inline bool m_DoNoSet = false; static inline bool m_DoNoSet = false;
@ -279,6 +286,8 @@ void C_SetCVarsToDefaults (void);
void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter); void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter);
void C_DeinitConsole(); void C_DeinitConsole();
void C_InitCVars(int which);
void C_UninitCVars();
class FBoolCVar : public FBaseCVar class FBoolCVar : public FBaseCVar
{ {
@ -465,6 +474,88 @@ protected:
int BitNum; 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; extern int cvar_defflags;
FBaseCVar *cvar_set (const char *var_name, const char *value); 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_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); } 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 // Restore demo cvars. Called after demo playback to restore all cvars
@ -482,35 +585,59 @@ void C_RestoreCVars (void);
void C_ForgetCVars (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) \ #define CUSTOM_CVAR(type,name,def,flags) \
static void cvarfunc_##name(F##type##CVar &); \ 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) static void cvarfunc_##name(F##type##CVar &self)
#define CUSTOM_CVAR_NAMED(type,name,cname,def,flags) \ #define CUSTOM_CVAR_NAMED(type,name,cname,def,flags) \
static void cvarfunc_##name(F##type##CVar &); \ 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) static void cvarfunc_##name(F##type##CVar &self)
#define CVAR(type,name,def,flags) \ #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) \ #define CUSTOM_CVARD(type,name,def,flags,descr) \
static void cvarfunc_##name(F##type##CVar &); \ 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) static void cvarfunc_##name(F##type##CVar &self)
#define CVARD(type,name,def,flags, descr) \ #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) \ #define CVARD_NAMED(type,name,varname,def,flags, descr) \
F##type##CVar varname (#name, def, flags, nullptr, descr); F##type##CVarRef name; \
static FCVarDecl cvardecl_##name = { &name, CVAR_##type, (flags), #varname, def, descr, nullptr}; \
#define CVAR_UNAMED(type,varname) \ extern FCVarDecl const *const cvardeclref_##name; \
F##type##CVar varname (nullptr, 0, 0, nullptr, nullptr); MSVC_VSEG FCVarDecl const *const cvardeclref_##name GCC_VSEG = &cvardecl_##name;
extern FBaseCVar *CVars;
#endif //__C_CVARS_H__ #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") CUSTOM_CVARD(Bool, use_joystick, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL, "enables input from the joystick if it is present")
{ {
#ifdef _WIN32 #ifdef _WIN32
joy_ps2raw.Callback(); joy_ps2raw->Callback();
joy_dinput.Callback(); joy_dinput->Callback();
joy_xinput.Callback(); joy_xinput->Callback();
#endif #endif
} }

View file

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

View file

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

View file

@ -112,7 +112,7 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : Syst
EXTERN_CVAR(Bool, vid_vsync); EXTERN_CVAR(Bool, vid_vsync);
CUSTOM_CVAR(Bool, gl_control_tear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CUSTOM_CVAR(Bool, gl_control_tear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{ {
vid_vsync.Callback(); vid_vsync->Callback();
} }
void SystemGLFrameBuffer::SetVSync (bool vsync) 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 regional settings were changed, reget preferred languages
if (wParam == 0 && lParam != 0 && strcmp ((const char *)lParam, "intl") == 0) if (wParam == 0 && lParam != 0 && strcmp ((const char *)lParam, "intl") == 0)
{ {
language.Callback (); language->Callback ();
} }
return 0; return 0;

View file

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

View file

@ -6715,12 +6715,12 @@ FxExpression *FxCVar::Resolve(FCompileContext &ctx)
switch (CVar->GetRealType()) switch (CVar->GetRealType())
{ {
case CVAR_Bool: case CVAR_Bool:
case CVAR_DummyBool: case CVAR_Flag:
ValueType = TypeBool; ValueType = TypeBool;
break; break;
case CVAR_Int: case CVAR_Int:
case CVAR_DummyInt: case CVAR_Mask:
ValueType = TypeSInt32; ValueType = TypeSInt32;
break; break;
@ -6776,7 +6776,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
build->Emit(OP_LS, dest.RegNum, addr.RegNum, nul); build->Emit(OP_LS, dest.RegNum, addr.RegNum, nul);
break; break;
case CVAR_DummyBool: case CVAR_Flag:
{ {
int *pVal; int *pVal;
auto cv = static_cast<FFlagCVar *>(CVar); auto cv = static_cast<FFlagCVar *>(CVar);
@ -6789,7 +6789,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
break; break;
} }
case CVAR_DummyInt: case CVAR_Mask:
{ {
auto cv = static_cast<FMaskCVar *>(CVar); auto cv = static_cast<FMaskCVar *>(CVar);
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value)); 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, chatmacro9, "Yes", CVAR_ARCHIVE)
CVAR (String, chatmacro0, "No", CVAR_ARCHIVE) CVAR (String, chatmacro0, "No", CVAR_ARCHIVE)
FStringCVar *chat_macros[10] = FStringCVarRef *chat_macros[10] =
{ {
&chatmacro0, &chatmacro0,
&chatmacro1, &chatmacro1,

View file

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

View file

@ -396,8 +396,11 @@ void D_SetupUserInfo ()
// Initialize the console player's user info // Initialize the console player's user info
coninfo = &players[consoleplayer].userinfo; 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) if ((cvar->GetFlags() & (CVAR_USERINFO|CVAR_IGNORE)) == CVAR_USERINFO)
{ {
FBaseCVar **newcvar; FBaseCVar **newcvar;
@ -434,8 +437,11 @@ void userinfo_t::Reset()
Clear(); Clear();
// Create userinfo vars for this player, initialized to their defaults. // 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) if ((cvar->GetFlags() & (CVAR_USERINFO|CVAR_IGNORE)) == CVAR_USERINFO)
{ {
ECVarType type; ECVarType type;
@ -528,7 +534,8 @@ void D_UserInfoChanged (FBaseCVar *cvar)
FString escaped_val; FString escaped_val;
char foo[256]; char foo[256];
if (cvar == &autoaim) #if 0
if (cvar == autoaim->get())
{ {
if (autoaim < 0.0f) if (autoaim < 0.0f)
{ {
@ -541,6 +548,7 @@ void D_UserInfoChanged (FBaseCVar *cvar)
return; return;
} }
} }
#endif
val = cvar->GetGenericRep (CVAR_String); val = cvar->GetGenericRep (CVAR_String);
escaped_val = D_EscapeUserInfo(val.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; delete[] value.String;
} }
if (var == &teamplay) #if 0
if (var == teamplay->get())
{ {
// Put players on teams if teamplay turned on // Put players on teams if teamplay turned on
for (int i = 0; i < MAXPLAYERS; ++i) 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) if (var)
{ {

View file

@ -102,7 +102,7 @@ enum ESkillLevels
#include "keydef.h" #include "keydef.h"
// [RH] dmflags bits (based on Q2's) // [RH] dmflags bits (based on Q2's)
enum enum : unsigned
{ {
DF_NO_HEALTH = 1 << 0, // Do not spawn health items (DM) DF_NO_HEALTH = 1 << 0, // Do not spawn health items (DM)
DF_NO_ITEMS = 1 << 1, // Do not spawn powerups (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_POWERUPS = 1 << 28, // Lose powerups when respawning in coop
DF_COOP_LOSE_AMMO = 1 << 29, // Lose ammo 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_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! // [BC] More dmflags. w00p!
enum enum : unsigned
{ {
// DF2_YES_IMPALING = 1 << 0, // Player gets impaled on MF2_IMPALE items // DF2_YES_IMPALING = 1 << 0, // Player gets impaled on MF2_IMPALE items
DF2_YES_WEAPONDROP = 1 << 1, // Drop current weapon upon death 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_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_ALWAYS_SPAWN_MULTI = 1 << 29, // Always spawn multiplayer items
DF2_NOVERTSPREAD = 1 << 30, // Don't allow vertical spread for hitscan weapons (excluding ssg) 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. // [RH] Compatibility flags.

View file

@ -113,7 +113,7 @@ void G_DoQuickSave ();
void STAT_Serialize(FSerializer &file); void STAT_Serialize(FSerializer &file);
bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompressedBuffer> &content); 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(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 (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH);
CVAR (Bool, chasedemo, false, 0); CVAR (Bool, chasedemo, false, 0);
@ -196,7 +196,7 @@ EXTERN_CVAR (Int, turnspeedwalkslow)
EXTERN_CVAR (Int, turnspeedsprintslow) EXTERN_CVAR (Int, turnspeedsprintslow)
int forwardmove[2], sidemove[2]; 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 flyspeed[2] = {1*256, 3*256};
int lookspeed[2] = {450, 512}; int lookspeed[2] = {450, 512};
@ -1925,8 +1925,12 @@ void C_SerializeCVars(FSerializer& arc, const char* label, uint32_t filter)
{ {
if (arc.isWriting()) 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))) if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_CONFIG_ONLY)))
{ {
UCVarValue val = cvar->GetGenericRep(CVAR_String); UCVarValue val = cvar->GetGenericRep(CVAR_String);
@ -1937,8 +1941,11 @@ void C_SerializeCVars(FSerializer& arc, const char* label, uint32_t filter)
} }
else 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))) if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_CONFIG_ONLY)))
{ {
UCVarValue val; UCVarValue val;
@ -2255,7 +2262,7 @@ void G_DoAutoSave ()
} }
num.Int = nextautosave; num.Int = nextautosave;
autosavenum.ForceSet (num, CVAR_Int); autosavenum->ForceSet (num, CVAR_Int);
file = G_BuildSaveName ("auto", nextautosave); file = G_BuildSaveName ("auto", nextautosave);
@ -2294,7 +2301,7 @@ void G_DoQuickSave ()
} }
num.Int = lastquicksave; num.Int = lastquicksave;
quicksavenum.ForceSet (num, CVAR_Int); quicksavenum->ForceSet (num, CVAR_Int);
file = G_BuildSaveName ("quick", lastquicksave); file = G_BuildSaveName ("quick", lastquicksave);

View file

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

View file

@ -85,7 +85,6 @@ EXTERN_CVAR (Bool, am_showsecrets)
EXTERN_CVAR (Bool, am_showitems) EXTERN_CVAR (Bool, am_showitems)
EXTERN_CVAR (Bool, am_showtime) EXTERN_CVAR (Bool, am_showtime)
EXTERN_CVAR (Bool, am_showtotaltime) EXTERN_CVAR (Bool, am_showtotaltime)
EXTERN_CVAR (Bool, noisedebug)
EXTERN_CVAR(Bool, inter_subtitles) EXTERN_CVAR(Bool, inter_subtitles)
EXTERN_CVAR(Bool, ui_screenborder_classic_scaling) EXTERN_CVAR(Bool, ui_screenborder_classic_scaling)
@ -1225,11 +1224,6 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
DrawConsistancy (); DrawConsistancy ();
DrawWaiting (); DrawWaiting ();
if ((ShowLog && MustDrawLog(state)) || (inter_subtitles && CPlayer->SubtitleCounter > 0)) DrawLog (); 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; UCVarValue val;
val.Bool = false; val.Bool = false;
wi_percents.SetGenericRepDefault (val, CVAR_Bool); wi_percents->SetGenericRepDefault (val, CVAR_Bool);
val.Bool = true; val.Bool = true;
con_centernotify.SetGenericRepDefault (val, CVAR_Bool); con_centernotify->SetGenericRepDefault (val, CVAR_Bool);
snd_pitched.SetGenericRepDefault (val, CVAR_Bool); snd_pitched->SetGenericRepDefault (val, CVAR_Bool);
val.Int = 9; val.Int = 9;
msg0color.SetGenericRepDefault (val, CVAR_Int); msg0color->SetGenericRepDefault (val, CVAR_Int);
val.Int = CR_WHITE; val.Int = CR_WHITE;
msgmidcolor.SetGenericRepDefault (val, CVAR_Int); msgmidcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = CR_YELLOW; val.Int = CR_YELLOW;
msgmidcolor2.SetGenericRepDefault (val, CVAR_Int); msgmidcolor2->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0x543b17; val.Int = 0x543b17;
am_wallcolor.SetGenericRepDefault (val, CVAR_Int); am_wallcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0xd0b085; val.Int = 0xd0b085;
am_fdwallcolor.SetGenericRepDefault (val, CVAR_Int); am_fdwallcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0x734323; val.Int = 0x734323;
am_cdwallcolor.SetGenericRepDefault (val, CVAR_Int); am_cdwallcolor->SetGenericRepDefault (val, CVAR_Int);
val.Int = 0; val.Int = 0;
wipetype.SetGenericRepDefault(val, CVAR_Int); wipetype->SetGenericRepDefault(val, CVAR_Int);
// Fix the Heretic/Hexen automap colors so they are correct. // Fix the Heretic/Hexen automap colors so they are correct.
// (They were wrong on older versions.) // (They were wrong on older versions.)
if (*am_wallcolor == 0x2c1808 && *am_fdwallcolor == 0x887058 && *am_cdwallcolor == 0x4c3820) if (*am_wallcolor == 0x2c1808 && *am_fdwallcolor == 0x887058 && *am_cdwallcolor == 0x4c3820)
{ {
am_wallcolor.ResetToDefault (); am_wallcolor->ResetToDefault ();
am_fdwallcolor.ResetToDefault (); am_fdwallcolor->ResetToDefault ();
am_cdwallcolor.ResetToDefault (); am_cdwallcolor->ResetToDefault ();
} }
if (!isHexen) if (!isHexen)
{ {
val.Int = 0x3f6040; val.Int = 0x3f6040;
color.SetGenericRepDefault (val, CVAR_Int); color->SetGenericRepDefault (val, CVAR_Int);
} }
} }
@ -963,7 +963,7 @@ void FGameConfigFile::SetStrifeDefaults ()
{ {
UCVarValue val; UCVarValue val;
val.Int = 3; val.Int = 3;
wipetype.SetGenericRepDefault(val, CVAR_Int); wipetype->SetGenericRepDefault(val, CVAR_Int);
} }
CCMD (whereisini) CCMD (whereisini)

View file

@ -470,7 +470,7 @@ void FMapInfoParser::ParseGameInfo()
SkipToNext(); SkipToNext();
} }
} }
turbo.Callback(); turbo->Callback();
} }
const char *gameinfo_t::GetFinalePage(unsigned int num) const 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); mysnprintf(temp, countof(temp), "%d x %d", viewwidth, viewheight);
value.String = temp; 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 fuzzviewheight = viewheight - 2; // Maximum row the fuzzer can draw to

View file

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

View file

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