mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-12 23:54:17 +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:
|
||||
return value.Bool;
|
||||
|
||||
case CVAR_Color:
|
||||
case CVAR_Int:
|
||||
return !!value.Int;
|
||||
|
||||
|
@ -331,6 +332,7 @@ int FBaseCVar::ToInt (UCVarValue value, ECVarType type)
|
|||
switch (type)
|
||||
{
|
||||
case CVAR_Bool: res = (int)value.Bool; break;
|
||||
case CVAR_Color:
|
||||
case CVAR_Int: res = value.Int; break;
|
||||
#if __GNUC__ <= 2
|
||||
case CVAR_Float: tmp = value.Float; res = (int)tmp; break;
|
||||
|
@ -359,6 +361,7 @@ float FBaseCVar::ToFloat (UCVarValue value, ECVarType type)
|
|||
case CVAR_Bool:
|
||||
return (float)value.Bool;
|
||||
|
||||
case CVAR_Color:
|
||||
case CVAR_Int:
|
||||
return (float)value.Int;
|
||||
|
||||
|
@ -388,6 +391,7 @@ const char *FBaseCVar::ToString (UCVarValue value, ECVarType type)
|
|||
case CVAR_String:
|
||||
return value.String;
|
||||
|
||||
case CVAR_Color:
|
||||
case CVAR_Int:
|
||||
mysnprintf (cstrbuf, countof(cstrbuf), "%i", value.Int);
|
||||
break;
|
||||
|
@ -1830,6 +1834,21 @@ void FZSIntCVar::MarkZSCVar()
|
|||
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)
|
||||
{
|
||||
VMValue param[] = { self.customCVarHandler.Get() , self.cvarName.GetIndex() , (double)self.Value };
|
||||
VMValue param[] = { self.customCVarHandler.Get() , self.cvarName.GetIndex() , (double) self.Value };
|
||||
double v;
|
||||
VMReturn ret(&v);
|
||||
VMCall(func, param, 3, &ret, 1);
|
||||
self.Value = float(v);
|
||||
self.Value = (float) v;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1875,6 +1894,23 @@ void FZSFloatCVar::MarkZSCVar()
|
|||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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
|
||||
{
|
||||
CVAR_ARCHIVE = 1, // set to cause it to be saved to config.
|
||||
CVAR_USERINFO = 1 << 1, // added to userinfo when changed.
|
||||
CVAR_SERVERINFO = 1 << 2, // added to serverinfo when changed.
|
||||
CVAR_NOSET = 1 << 3, // don't allow change from console at all,
|
||||
// but can be set from the command line.
|
||||
CVAR_LATCH = 1 << 4, // save changes until server restart.
|
||||
CVAR_UNSETTABLE = 1 << 5, // can unset this var from console.
|
||||
CVAR_DEMOSAVE = 1 << 6, // save the value of this cvar in a demo.
|
||||
CVAR_ISDEFAULT = 1 << 7, // is cvar unchanged since creation?
|
||||
CVAR_AUTO = 1 << 8, // allocated; needs to be freed when destroyed.
|
||||
CVAR_NOINITCALL = 1 << 9, // don't call callback at game start.
|
||||
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_NOSAVE = 1 << 12, // when used with CVAR_SERVERINFO, do not save var to savegame
|
||||
// and config.
|
||||
CVAR_MOD = 1 << 13, // cvar was defined by a mod.
|
||||
CVAR_IGNORE = 1 << 14, // do not send cvar across the network/inaccesible from ACS
|
||||
// (dummy mod cvar).
|
||||
CVAR_CHEAT = 1 << 15, // can be set only when sv_cheats is enabled.
|
||||
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
|
||||
// mirror an external variable.
|
||||
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_ARCHIVE = 1, // set to cause it to be saved to config.
|
||||
CVAR_USERINFO = 1 << 1, // added to userinfo when changed.
|
||||
CVAR_SERVERINFO = 1 << 2, // added to serverinfo when changed.
|
||||
CVAR_NOSET = 1 << 3, // don't allow change from console at all,
|
||||
// but can be set from the command line.
|
||||
CVAR_LATCH = 1 << 4, // save changes until server restart.
|
||||
CVAR_UNSETTABLE = 1 << 5, // can unset this var from console.
|
||||
CVAR_DEMOSAVE = 1 << 6, // save the value of this cvar in a demo.
|
||||
CVAR_ISDEFAULT = 1 << 7, // is cvar unchanged since creation?
|
||||
CVAR_AUTO = 1 << 8, // allocated; needs to be freed when destroyed.
|
||||
CVAR_NOINITCALL = 1 << 9, // don't call callback at game start.
|
||||
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_NOSAVE = 1 << 12, // when used with CVAR_SERVERINFO, do not save var to savegame
|
||||
// and config.
|
||||
CVAR_MOD = 1 << 13, // cvar was defined by a mod.
|
||||
CVAR_IGNORE = 1 << 14, // do not send cvar across the network/inaccesible from ACS
|
||||
// (dummy mod cvar).
|
||||
CVAR_CHEAT = 1 << 15, // can be set only when sv_cheats is enabled.
|
||||
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
|
||||
// mirror an external variable.
|
||||
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_CLONE = 1 << 20, // Clone of a Custom ZScript CVar
|
||||
};
|
||||
|
||||
enum ECVarType
|
||||
|
@ -184,6 +185,12 @@ public:
|
|||
virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const = 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)
|
||||
{ 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);
|
||||
void InstantiateZSCVar() override;
|
||||
void MarkZSCVar() override;
|
||||
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||
};
|
||||
|
||||
class FZSFloatCVar : public FFloatCVar
|
||||
|
@ -515,6 +523,7 @@ public:
|
|||
FZSFloatCVar(const char *name, float def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||
void InstantiateZSCVar() override;
|
||||
void MarkZSCVar() override;
|
||||
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||
};
|
||||
|
||||
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);
|
||||
void InstantiateZSCVar() override;
|
||||
void MarkZSCVar() override;
|
||||
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||
};
|
||||
|
||||
class FZSBoolCVar : public FBoolCVar
|
||||
|
@ -541,6 +551,7 @@ public:
|
|||
FZSBoolCVar(const char *name, bool def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||
void InstantiateZSCVar() override;
|
||||
void MarkZSCVar() override;
|
||||
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||
};
|
||||
|
||||
class FZSColorCVar : public FColorCVar
|
||||
|
@ -554,6 +565,7 @@ public:
|
|||
FZSColorCVar(const char *name, int def, uint32_t flags, FName className, const char* descr = nullptr);
|
||||
void InstantiateZSCVar() override;
|
||||
void MarkZSCVar() override;
|
||||
UCVarValue GenericZSCVarCallback(UCVarValue value, ECVarType type) override;
|
||||
};
|
||||
|
||||
class FBoolCVarRef
|
||||
|
|
|
@ -852,7 +852,22 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt)
|
|||
PARAM_INT(val);
|
||||
UCVarValue v;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -870,7 +885,22 @@ DEFINE_ACTION_FUNCTION(_CVar, SetFloat)
|
|||
PARAM_FLOAT(val);
|
||||
UCVarValue v;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -889,7 +919,22 @@ DEFINE_ACTION_FUNCTION(_CVar, SetString)
|
|||
PARAM_STRING(val);
|
||||
UCVarValue v;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -458,8 +458,17 @@ void userinfo_t::Reset()
|
|||
case NAME_PlayerClass: type = CVAR_Int; 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);
|
||||
|
||||
if(flags & CVAR_ZS_CUSTOM)
|
||||
{
|
||||
newcvar->SetExtraDataPointer(cvar); // store backing cvar
|
||||
}
|
||||
|
||||
Insert(cvarname, newcvar);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue