mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-19 08:01:50 +00:00
Let custom CVar handlers to be called on cloned cvars
This commit is contained in:
parent
82b7e93d26
commit
b50d7f4db5
4 changed files with 184 additions and 31 deletions
|
@ -302,6 +302,7 @@ bool FBaseCVar::ToBool (UCVarValue value, ECVarType type)
|
||||||
case CVAR_Bool:
|
case CVAR_Bool:
|
||||||
return value.Bool;
|
return value.Bool;
|
||||||
|
|
||||||
|
case CVAR_Color:
|
||||||
case CVAR_Int:
|
case CVAR_Int:
|
||||||
return !!value.Int;
|
return !!value.Int;
|
||||||
|
|
||||||
|
@ -331,6 +332,7 @@ int FBaseCVar::ToInt (UCVarValue value, ECVarType type)
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case CVAR_Bool: res = (int)value.Bool; break;
|
case CVAR_Bool: res = (int)value.Bool; break;
|
||||||
|
case CVAR_Color:
|
||||||
case CVAR_Int: res = value.Int; break;
|
case CVAR_Int: res = value.Int; break;
|
||||||
#if __GNUC__ <= 2
|
#if __GNUC__ <= 2
|
||||||
case CVAR_Float: tmp = value.Float; res = (int)tmp; break;
|
case CVAR_Float: tmp = value.Float; res = (int)tmp; break;
|
||||||
|
@ -359,6 +361,7 @@ float FBaseCVar::ToFloat (UCVarValue value, ECVarType type)
|
||||||
case CVAR_Bool:
|
case CVAR_Bool:
|
||||||
return (float)value.Bool;
|
return (float)value.Bool;
|
||||||
|
|
||||||
|
case CVAR_Color:
|
||||||
case CVAR_Int:
|
case CVAR_Int:
|
||||||
return (float)value.Int;
|
return (float)value.Int;
|
||||||
|
|
||||||
|
@ -388,6 +391,7 @@ const char *FBaseCVar::ToString (UCVarValue value, ECVarType type)
|
||||||
case CVAR_String:
|
case CVAR_String:
|
||||||
return value.String;
|
return value.String;
|
||||||
|
|
||||||
|
case CVAR_Color:
|
||||||
case CVAR_Int:
|
case CVAR_Int:
|
||||||
mysnprintf (cstrbuf, countof(cstrbuf), "%i", value.Int);
|
mysnprintf (cstrbuf, countof(cstrbuf), "%i", value.Int);
|
||||||
break;
|
break;
|
||||||
|
@ -1830,6 +1834,21 @@ void FZSIntCVar::MarkZSCVar()
|
||||||
GC::Mark(customCVarHandler);
|
GC::Mark(customCVarHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UCVarValue FZSIntCVar::GenericZSCVarCallback(UCVarValue value, ECVarType type) {
|
||||||
|
int val = ToInt(value, type);
|
||||||
|
|
||||||
|
IFVIRTUALPTRNAME(customCVarHandler, "CustomIntCVar", ModifyValue)
|
||||||
|
{
|
||||||
|
VMValue param[] = { customCVarHandler.Get() , cvarName.GetIndex() , val };
|
||||||
|
VMReturn ret(&val);
|
||||||
|
VMCall(func, param, 3, &ret, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
UCVarValue v;
|
||||||
|
v.Int = val;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -1849,11 +1868,11 @@ void FZSFloatCVar::CallCVarCallback(FZSFloatCVar &self)
|
||||||
}
|
}
|
||||||
IFVIRTUALPTRNAME(self.customCVarHandler, "CustomFloatCVar", ModifyValue)
|
IFVIRTUALPTRNAME(self.customCVarHandler, "CustomFloatCVar", ModifyValue)
|
||||||
{
|
{
|
||||||
VMValue param[] = { self.customCVarHandler.Get() , self.cvarName.GetIndex() , (double)self.Value };
|
VMValue param[] = { self.customCVarHandler.Get() , self.cvarName.GetIndex() , (double) self.Value };
|
||||||
double v;
|
double v;
|
||||||
VMReturn ret(&v);
|
VMReturn ret(&v);
|
||||||
VMCall(func, param, 3, &ret, 1);
|
VMCall(func, param, 3, &ret, 1);
|
||||||
self.Value = float(v);
|
self.Value = (float) v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1875,6 +1894,23 @@ void FZSFloatCVar::MarkZSCVar()
|
||||||
GC::Mark(customCVarHandler);
|
GC::Mark(customCVarHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UCVarValue FZSFloatCVar::GenericZSCVarCallback(UCVarValue value, ECVarType type) {
|
||||||
|
float val = ToFloat(value, type);
|
||||||
|
|
||||||
|
IFVIRTUALPTRNAME(customCVarHandler, "CustomFloatCVar", ModifyValue)
|
||||||
|
{
|
||||||
|
VMValue param[] = { customCVarHandler.Get() , cvarName.GetIndex() , (double) val };
|
||||||
|
double v;
|
||||||
|
VMReturn ret(&v);
|
||||||
|
VMCall(func, param, 3, &ret, 1);
|
||||||
|
val = (float) v;
|
||||||
|
}
|
||||||
|
|
||||||
|
UCVarValue v;
|
||||||
|
v.Float = val;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -1918,6 +1954,25 @@ void FZSStringCVar::MarkZSCVar()
|
||||||
GC::Mark(customCVarHandler);
|
GC::Mark(customCVarHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UCVarValue FZSStringCVar::GenericZSCVarCallback(UCVarValue value, ECVarType type) {
|
||||||
|
FString val = ToString(value, type);
|
||||||
|
|
||||||
|
IFVIRTUALPTRNAME(customCVarHandler, "CustomStringCVar", ModifyValue)
|
||||||
|
{
|
||||||
|
VMValue param[] = { customCVarHandler.Get() , cvarName.GetIndex() , &val };
|
||||||
|
VMReturn ret(&val);
|
||||||
|
VMCall(func, param, 3, &ret, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * str = new char[val.Len() + 1];
|
||||||
|
memcpy(str, val.GetChars(), val.Len() * sizeof(char));
|
||||||
|
str[val.Len()] = '\0';
|
||||||
|
|
||||||
|
UCVarValue v;
|
||||||
|
v.String = str;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -1963,10 +2018,27 @@ void FZSBoolCVar::MarkZSCVar()
|
||||||
GC::Mark(customCVarHandler);
|
GC::Mark(customCVarHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UCVarValue FZSBoolCVar::GenericZSCVarCallback(UCVarValue value, ECVarType type) {
|
||||||
|
bool val = ToFloat(value, type);
|
||||||
|
|
||||||
|
IFVIRTUALPTRNAME(customCVarHandler, "CustomBoolCVar", ModifyValue)
|
||||||
|
{
|
||||||
|
VMValue param[] = { customCVarHandler.Get() , cvarName.GetIndex() , val };
|
||||||
|
int v;
|
||||||
|
VMReturn ret(&v);
|
||||||
|
VMCall(func, param, 3, &ret, 1);
|
||||||
|
val = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
UCVarValue v;
|
||||||
|
v.Bool = val;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FZSIntCVar
|
// FZSColorCVar
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
@ -2004,4 +2076,19 @@ void FZSColorCVar::InstantiateZSCVar()
|
||||||
void FZSColorCVar::MarkZSCVar()
|
void FZSColorCVar::MarkZSCVar()
|
||||||
{
|
{
|
||||||
GC::Mark(customCVarHandler);
|
GC::Mark(customCVarHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
UCVarValue FZSColorCVar::GenericZSCVarCallback(UCVarValue value, ECVarType type) {
|
||||||
|
int val = ToInt(value, type);
|
||||||
|
|
||||||
|
IFVIRTUALPTRNAME(customCVarHandler, "CustomColorCVar", ModifyValue)
|
||||||
|
{
|
||||||
|
VMValue param[] = { customCVarHandler.Get() , cvarName.GetIndex() , val };
|
||||||
|
VMReturn ret(&val);
|
||||||
|
VMCall(func, param, 3, &ret, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
UCVarValue v;
|
||||||
|
v.Int = val;
|
||||||
|
return v;
|
||||||
}
|
}
|
|
@ -50,30 +50,31 @@ CVARS (console variables)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CVAR_ARCHIVE = 1, // set to cause it to be saved to config.
|
CVAR_ARCHIVE = 1, // set to cause it to be saved to config.
|
||||||
CVAR_USERINFO = 1 << 1, // added to userinfo when changed.
|
CVAR_USERINFO = 1 << 1, // added to userinfo when changed.
|
||||||
CVAR_SERVERINFO = 1 << 2, // added to serverinfo when changed.
|
CVAR_SERVERINFO = 1 << 2, // added to serverinfo when changed.
|
||||||
CVAR_NOSET = 1 << 3, // don't allow change from console at all,
|
CVAR_NOSET = 1 << 3, // don't allow change from console at all,
|
||||||
// but can be set from the command line.
|
// but can be set from the command line.
|
||||||
CVAR_LATCH = 1 << 4, // save changes until server restart.
|
CVAR_LATCH = 1 << 4, // save changes until server restart.
|
||||||
CVAR_UNSETTABLE = 1 << 5, // can unset this var from console.
|
CVAR_UNSETTABLE = 1 << 5, // can unset this var from console.
|
||||||
CVAR_DEMOSAVE = 1 << 6, // save the value of this cvar in a demo.
|
CVAR_DEMOSAVE = 1 << 6, // save the value of this cvar in a demo.
|
||||||
CVAR_ISDEFAULT = 1 << 7, // is cvar unchanged since creation?
|
CVAR_ISDEFAULT = 1 << 7, // is cvar unchanged since creation?
|
||||||
CVAR_AUTO = 1 << 8, // allocated; needs to be freed when destroyed.
|
CVAR_AUTO = 1 << 8, // allocated; needs to be freed when destroyed.
|
||||||
CVAR_NOINITCALL = 1 << 9, // don't call callback at game start.
|
CVAR_NOINITCALL = 1 << 9, // don't call callback at game start.
|
||||||
CVAR_GLOBALCONFIG = 1 << 10, // cvar is saved to global config section.
|
CVAR_GLOBALCONFIG = 1 << 10, // cvar is saved to global config section.
|
||||||
CVAR_VIDEOCONFIG = 1 << 11, // cvar is saved to video config section (not implemented).
|
CVAR_VIDEOCONFIG = 1 << 11, // cvar is saved to video config section (not implemented).
|
||||||
CVAR_NOSAVE = 1 << 12, // when used with CVAR_SERVERINFO, do not save var to savegame
|
CVAR_NOSAVE = 1 << 12, // when used with CVAR_SERVERINFO, do not save var to savegame
|
||||||
// and config.
|
// and config.
|
||||||
CVAR_MOD = 1 << 13, // cvar was defined by a mod.
|
CVAR_MOD = 1 << 13, // cvar was defined by a mod.
|
||||||
CVAR_IGNORE = 1 << 14, // do not send cvar across the network/inaccesible from ACS
|
CVAR_IGNORE = 1 << 14, // do not send cvar across the network/inaccesible from ACS
|
||||||
// (dummy mod cvar).
|
// (dummy mod cvar).
|
||||||
CVAR_CHEAT = 1 << 15, // can be set only when sv_cheats is enabled.
|
CVAR_CHEAT = 1 << 15, // can be set only when sv_cheats is enabled.
|
||||||
CVAR_UNSAFECONTEXT = 1 << 16, // cvar value came from unsafe context.
|
CVAR_UNSAFECONTEXT = 1 << 16, // cvar value came from unsafe context.
|
||||||
CVAR_VIRTUAL = 1 << 17, // do not invoke the callback recursively so it can be used to
|
CVAR_VIRTUAL = 1 << 17, // do not invoke the callback recursively so it can be used to
|
||||||
// mirror an external variable.
|
// mirror an external variable.
|
||||||
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.
|
||||||
CVAR_ZS_CUSTOM = 1 << 19, // Custom CVar backed by a ZScript class
|
CVAR_ZS_CUSTOM = 1 << 19, // Custom CVar backed by a ZScript class
|
||||||
|
CVAR_ZS_CUSTOM_CLONE = 1 << 20, // Clone of a Custom ZScript CVar
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ECVarType
|
enum ECVarType
|
||||||
|
@ -184,6 +185,12 @@ public:
|
||||||
virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const = 0;
|
virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const = 0;
|
||||||
virtual void SetGenericRepDefault (UCVarValue value, ECVarType type) = 0;
|
virtual void SetGenericRepDefault (UCVarValue value, ECVarType type) = 0;
|
||||||
|
|
||||||
|
virtual UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type)
|
||||||
|
{ // not valid for cvars that aren't custom zscript cvars, doesn't modify the actual cvar directly, just transforms the value
|
||||||
|
// FZSStringCVar allocates a buffer for the returned string that must be freed by the caller
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
FBaseCVar &operator= (const FBaseCVar &var)
|
FBaseCVar &operator= (const FBaseCVar &var)
|
||||||
{ UCVarValue val; ECVarType type; val = var.GetFavoriteRep (&type); SetGenericRep (val, type); return *this; }
|
{ UCVarValue val; ECVarType type; val = var.GetFavoriteRep (&type); SetGenericRep (val, type); return *this; }
|
||||||
|
|
||||||
|
@ -502,6 +509,7 @@ public:
|
||||||
FZSIntCVar(const char *name, int def, uint32_t flags, FName className, const char* descr = nullptr);
|
FZSIntCVar(const char *name, int def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||||
void InstantiateZSCVar() override;
|
void InstantiateZSCVar() override;
|
||||||
void MarkZSCVar() override;
|
void MarkZSCVar() override;
|
||||||
|
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FZSFloatCVar : public FFloatCVar
|
class FZSFloatCVar : public FFloatCVar
|
||||||
|
@ -515,6 +523,7 @@ public:
|
||||||
FZSFloatCVar(const char *name, float def, uint32_t flags, FName className, const char* descr = nullptr);
|
FZSFloatCVar(const char *name, float def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||||
void InstantiateZSCVar() override;
|
void InstantiateZSCVar() override;
|
||||||
void MarkZSCVar() override;
|
void MarkZSCVar() override;
|
||||||
|
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FZSStringCVar : public FStringCVar
|
class FZSStringCVar : public FStringCVar
|
||||||
|
@ -528,6 +537,7 @@ public:
|
||||||
FZSStringCVar(const char *name, const char * def, uint32_t flags, FName className, const char* descr = nullptr);
|
FZSStringCVar(const char *name, const char * def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||||
void InstantiateZSCVar() override;
|
void InstantiateZSCVar() override;
|
||||||
void MarkZSCVar() override;
|
void MarkZSCVar() override;
|
||||||
|
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FZSBoolCVar : public FBoolCVar
|
class FZSBoolCVar : public FBoolCVar
|
||||||
|
@ -541,6 +551,7 @@ public:
|
||||||
FZSBoolCVar(const char *name, bool def, uint32_t flags, FName className, const char* descr = nullptr);
|
FZSBoolCVar(const char *name, bool def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||||
void InstantiateZSCVar() override;
|
void InstantiateZSCVar() override;
|
||||||
void MarkZSCVar() override;
|
void MarkZSCVar() override;
|
||||||
|
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FZSColorCVar : public FColorCVar
|
class FZSColorCVar : public FColorCVar
|
||||||
|
@ -554,6 +565,7 @@ public:
|
||||||
FZSColorCVar(const char *name, int def, uint32_t flags, FName className, const char* descr = nullptr);
|
FZSColorCVar(const char *name, int def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||||
void InstantiateZSCVar() override;
|
void InstantiateZSCVar() override;
|
||||||
void MarkZSCVar() override;
|
void MarkZSCVar() override;
|
||||||
|
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FBoolCVarRef
|
class FBoolCVarRef
|
||||||
|
|
|
@ -852,7 +852,22 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt)
|
||||||
PARAM_INT(val);
|
PARAM_INT(val);
|
||||||
UCVarValue v;
|
UCVarValue v;
|
||||||
v.Int = val;
|
v.Int = val;
|
||||||
self->SetGenericRep(v, CVAR_Int);
|
|
||||||
|
if(self->GetFlags() & CVAR_ZS_CUSTOM_CLONE)
|
||||||
|
{
|
||||||
|
auto realCVar = (FBaseCVar*)(self->GetExtraDataPointer());
|
||||||
|
assert(realCVar->GetFlags() & CVAR_ZS_CUSTOM);
|
||||||
|
|
||||||
|
v = realCVar->GenericZSCVarCallback(v, CVAR_Int);
|
||||||
|
self->SetGenericRep(v, realCVar->GetRealType());
|
||||||
|
|
||||||
|
if(realCVar->GetRealType() == CVAR_String) delete[] v.String;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->SetGenericRep(v, CVAR_Int);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -870,7 +885,22 @@ DEFINE_ACTION_FUNCTION(_CVar, SetFloat)
|
||||||
PARAM_FLOAT(val);
|
PARAM_FLOAT(val);
|
||||||
UCVarValue v;
|
UCVarValue v;
|
||||||
v.Float = (float)val;
|
v.Float = (float)val;
|
||||||
self->SetGenericRep(v, CVAR_Float);
|
|
||||||
|
if(self->GetFlags() & CVAR_ZS_CUSTOM_CLONE)
|
||||||
|
{
|
||||||
|
auto realCVar = (FBaseCVar*)(self->GetExtraDataPointer());
|
||||||
|
assert(realCVar->GetFlags() & CVAR_ZS_CUSTOM);
|
||||||
|
|
||||||
|
v = realCVar->GenericZSCVarCallback(v, CVAR_Float);
|
||||||
|
self->SetGenericRep(v, realCVar->GetRealType());
|
||||||
|
|
||||||
|
if(realCVar->GetRealType() == CVAR_String) delete[] v.String;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->SetGenericRep(v, CVAR_Float);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -889,7 +919,22 @@ DEFINE_ACTION_FUNCTION(_CVar, SetString)
|
||||||
PARAM_STRING(val);
|
PARAM_STRING(val);
|
||||||
UCVarValue v;
|
UCVarValue v;
|
||||||
v.String = val.GetChars();
|
v.String = val.GetChars();
|
||||||
self->SetGenericRep(v, CVAR_String);
|
|
||||||
|
if(self->GetFlags() & CVAR_ZS_CUSTOM_CLONE)
|
||||||
|
{
|
||||||
|
auto realCVar = (FBaseCVar*)(self->GetExtraDataPointer());
|
||||||
|
assert(realCVar->GetFlags() & CVAR_ZS_CUSTOM);
|
||||||
|
|
||||||
|
v = realCVar->GenericZSCVarCallback(v, CVAR_String);
|
||||||
|
self->SetGenericRep(v, realCVar->GetRealType());
|
||||||
|
|
||||||
|
if(realCVar->GetRealType() == CVAR_String) delete[] v.String;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->SetGenericRep(v, CVAR_String);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -458,8 +458,17 @@ void userinfo_t::Reset()
|
||||||
case NAME_PlayerClass: type = CVAR_Int; break;
|
case NAME_PlayerClass: type = CVAR_Int; break;
|
||||||
default: type = cvar->GetRealType(); break;
|
default: type = cvar->GetRealType(); break;
|
||||||
}
|
}
|
||||||
newcvar = C_CreateCVar(NULL, type, cvar->GetFlags() & CVAR_MOD);
|
|
||||||
|
int flags = cvar->GetFlags();
|
||||||
|
|
||||||
|
newcvar = C_CreateCVar(NULL, type, (flags & CVAR_MOD) | ((flags & CVAR_ZS_CUSTOM) << 1) );
|
||||||
newcvar->SetGenericRepDefault(cvar->GetGenericRepDefault(CVAR_String), CVAR_String);
|
newcvar->SetGenericRepDefault(cvar->GetGenericRepDefault(CVAR_String), CVAR_String);
|
||||||
|
|
||||||
|
if(flags & CVAR_ZS_CUSTOM)
|
||||||
|
{
|
||||||
|
newcvar->SetExtraDataPointer(cvar); // store backing cvar
|
||||||
|
}
|
||||||
|
|
||||||
Insert(cvarname, newcvar);
|
Insert(cvarname, newcvar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue