From ed0b49b0e8071e10272d030556859d916950e285 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Thu, 5 Oct 2023 00:13:00 +0200 Subject: [PATCH 01/36] progress report --- public/tier1/convar.h | 191 ++++++++++++++++++++---------------------- tier1/convar.cpp | 111 ++++++++++++++++++++++-- 2 files changed, 195 insertions(+), 107 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 45cd85523..947e7c446 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -1,4 +1,4 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -19,6 +19,7 @@ #include "tier0/dbg.h" #include "tier1/utlvector.h" #include "tier1/utlstring.h" +#include "tier1/characterset.h" #include "Color.h" #include "mathlib/vector4d.h" #include "playerslot.h" @@ -49,21 +50,39 @@ class ConCommand; class ConCommandBase; class ConVarRefAbstract; class ConCommandRefAbstract; -struct characterset_t; class ALIGN8 ConVarHandle { public: - bool IsValid() { return value != kInvalidConVarHandle; } - uint32 Get() { return value; } - void Set( uint32 _value ) { value = _value; } + ConVarHandle() { m_value = 0xFFFFFFFF; }; -private: - uint32 value = kInvalidConVarHandle; + bool IsValid() const; + void Invalidate(); private: - static const uint32 kInvalidConVarHandle = 0xFFFFFFFF; + friend bool operator!=(const ConVarHandle& lhs, const ConVarHandle& rhs); + friend bool operator==(const ConVarHandle& lhs, const ConVarHandle& rhs); + + uint32 GetValue() const { return m_value; }; + + uint32 m_value; } ALIGN8_POST; + +inline bool operator!=(const ConVarHandle& lhs, const ConVarHandle& rhs) { return lhs.m_value != rhs.m_value; } +inline bool operator==(const ConVarHandle& lhs, const ConVarHandle& rhs) { return lhs.m_value == rhs.m_value; } + +static const ConVarHandle INVALID_CONVAR_HANDLE = ConVarHandle(); + +inline bool ConVarHandle::IsValid() const +{ + return *this != INVALID_CONVAR_HANDLE; +} + +inline void ConVarHandle::Invalidate() +{ + m_value = INVALID_CONVAR_HANDLE.GetValue(); +} + enum CommandTarget_t { CT_NO_TARGET = -1, @@ -97,6 +116,8 @@ class CCommandContext class ALIGN8 ConCommandHandle { public: + ConCommandHandle() { value = kInvalidConCommandHandle; }; + bool IsValid() { return value != kInvalidConCommandHandle; } uint16 Get() { return value; } void Set( uint16 _value ) { value = _value; } @@ -198,7 +219,8 @@ enum EConVarType : short EConVarType_Vector2, EConVarType_Vector3, EConVarType_Vector4, - EConVarType_Qangle + EConVarType_Qangle, + EConVarType_MAX }; union CVValue_t @@ -224,7 +246,6 @@ union CVValue_t // Called when a ConVar changes value //----------------------------------------------------------------------------- typedef void(*FnChangeCallbackGlobal_t)(ConVarRefAbstract *cvar, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); -typedef void(*FnChangeCallback_t)(ConVarRefAbstract *cvar, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); //----------------------------------------------------------------------------- // ConVar & ConCommand creation listener callbacks @@ -478,6 +499,7 @@ friend class ConCommandHandle; //----------------------------------------------------------------------------- // Purpose: A console variable //----------------------------------------------------------------------------- +#if false class ConVar { friend class CCvar; @@ -485,7 +507,6 @@ friend class ConVarRef; friend class SplitScreenConVarRef; public: -#ifdef CONVAR_WORK_FINISHED ConVar( const char *pName, const char *pDefaultValue, int64 flags = 0); ConVar( const char *pName, const char *pDefaultValue, int64 flags, @@ -584,51 +605,70 @@ friend class SplitScreenConVarRef; protected: -#if 0 - // Next ConVar in chain - // Prior to register, it points to the next convar in the DLL. - // Once registered, though, m_pNext is reset to point to the next - // convar in the global list - ConCommandBase* m_pNext; - - // Has the cvar been added to the global list? - bool m_bRegistered; - - // Static data const char* m_pszName; + CVValue_t* m_cvvDefaultValue; + CVValue_t* m_cvvMinValue; + CVValue_t* m_cvvMaxValue; const char* m_pszHelpString; + EConVarType m_eVarType; - // ConVar flags - int64 m_nFlags; + // This gets copied from the ConVarDesc_t on creation + short unk1; -protected: - // ConVars add themselves to this list for the executable. - // Then ConVar_Register runs through all the console variables - // and registers them into a global list stored in vstdlib.dll - static ConCommandBase* s_pConCommandBases; - - // ConVars in this executable use this 'global' to access values. - static IConCommandBaseAccessor* s_pAccessor; - // This either points to "this" or it points to the original declaration of a ConVar. - // This allows ConVars to exist in separate modules, and they all use the first one to be declared. - // m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar). - ConVar *m_pParent; + unsigned int timesChanged; + int64 flags; + unsigned int callback_index; - // Static data - const char *m_pszDefaultValue; - - CVValue_t m_Value; + // Used when setting default, max, min values from the ConVarDesc_t + // although that's not the only place of usage + // flags seems to be: + // (1 << 0) Skip setting value to split screen slots and also something keyvalues related + // (1 << 1) Skip setting default value + // (1 << 2) Skip setting min/max values + int allocation_flag_of_some_sort; - // Min/Max values - bool m_bHasMin; - float m_fMinVal; - bool m_bHasMax; - float m_fMaxVal; - - // Call this function when ConVar changes - CUtlVector< FnChangeCallback_t > m_fnChangeCallbacks; + CVValue_t** values; +}; #endif -#endif // CONVAR_WORK_FINISHED + +//----------------------------------------------------------------- +// Used to read/write/create? convars (replaces the FindVar method) +//----------------------------------------------------------------- +class ConVarRefAbstract +{ +public: + // sub_6A66B0 + ConVarRefAbstract(const char* name, int32 flags, const char* description, int64 obj, float value) + { + this->Init(INVALID_CONVAR_HANDLE, EConVarType_Float32); + + *(char *)(obj + 4) = 1; + *(float *)(obj + 7) = value; + this->sub_10B7C70(name, flags & 0xFB, description, obj); + } + +private: + // sub_10B7BC0 + void Init(ConVarHandle defaultHandle, EConVarType type); + + // sub_10B7C70 + void sub_10B7C70(const char* name, int32 flags, const char* description, int64 obj); + + // High-speed method to read convar data + ConVarHandle m_Handle; + ConVar* m_ConVar; +}; + +// sub_10B7760 +ConVar* ConVar_Invalid(EConVarType type); + +class ConVar +{ +friend class ConVarRegList; +friend class ConVarRefAbstract; +public: + ConVar(EConVarType type); +protected: const char* m_pszName; CVValue_t* m_cvvDefaultValue; CVValue_t* m_cvvMinValue; @@ -640,7 +680,7 @@ friend class SplitScreenConVarRef; short unk1; unsigned int timesChanged; - int64 flags; + int64 m_flags; unsigned int callback_index; // Used when setting default, max, min values from the ConVarDesc_t @@ -651,10 +691,9 @@ friend class SplitScreenConVarRef; // (1 << 2) Skip setting min/max values int allocation_flag_of_some_sort; - CVValue_t** values; + CVValue_t* m_value[4]; }; - #ifdef CONVAR_WORK_FINISHED //----------------------------------------------------------------------------- // Purpose: Return ConVar value as a float @@ -773,54 +812,6 @@ FORCEINLINE_CVAR int CSplitScreenAddedConVar::GetSplitScreenPlayerSlot() const return m_nSplitScreenSlot; } -#endif // CONVAR_WORK_FINISHED - -//----------------------------------------------------------------------------- -// Used to read/write convars that already exist (replaces the FindVar method) -//----------------------------------------------------------------------------- -class ConVarRefAbstract -{ -public: -#ifdef CONVAR_WORK_FINISHED - ConVarRefAbstract( const char *pName ); - ConVarRefAbstract( const char *pName, bool bIgnoreMissing ); - ConVarRefAbstract( IConVar *pConVar ); - - void Init( const char *pName, bool bIgnoreMissing ); - bool IsValid() const; - bool IsFlagSet( int64 nFlags ) const; - IConVar *GetLinkedConVar(); - - // Get/Set value - float GetFloat( void ) const; - int GetInt( void ) const; - Color GetColor( void ) const; - bool GetBool() const { return !!GetInt(); } - const char *GetString( void ) const; - - void SetValue( const char *pValue ); - void SetValue( float flValue ); - void SetValue( int nValue ); - void SetValue( Color value ); - void SetValue( bool bValue ); - - const char *GetName() const; - - const char *GetDefault() const; - - const char *GetBaseName() const; - - int GetSplitScreenPlayerSlot() const; - -private: -#endif // CONVAR_WORK_FINISHED - // High-speed method to read convar data - ConVarHandle m_Handle; - ConVar *m_pConVarState; -}; - - -#ifdef CONVAR_WORK_FINISHED //----------------------------------------------------------------------------- // Did we find an existing convar of that name? //----------------------------------------------------------------------------- diff --git a/tier1/convar.cpp b/tier1/convar.cpp index da72ad532..9144a6a88 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -1,5 +1,5 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -95,7 +95,6 @@ class ConCommandRegList bool ConCommandRegList::s_bConCommandsRegistered = false; -#ifdef CONVAR_WORK_FINISHED template void check_size() { static_assert(ExpectedSize == RealSize, "Size mismatch"); @@ -110,7 +109,7 @@ class ConVarRegList ConVarRegList() { check_size(); - check_size(); + //check_size(); } static bool AreConVarsRegistered() @@ -136,7 +135,7 @@ class ConVarRegList if (!hndl.IsValid()) { - Plat_FatalErrorFunc("RegisterConCommand: Unknown error registering convar \"%s\"!\n", pConVar->GetName()); + Plat_FatalErrorFunc("RegisterConCommand: Unknown error registering convar \"%s\"!\n", pConVar->m_pszName); DebuggerBreakIfDebugging(); } } @@ -157,7 +156,6 @@ class ConVarRegList }; bool ConVarRegList::s_bConVarsRegistered = false; -#endif // CONVAR_WORK_FINISHED //----------------------------------------------------------------------------- // Called by the framework to register ConCommandBases with the ICVar @@ -651,14 +649,113 @@ bool ConCommand::CanAutoComplete( void ) return m_bHasCompletionCallback; } - -#ifdef CONVAR_WORK_FINISHED //----------------------------------------------------------------------------- // // Console Variables // //----------------------------------------------------------------------------- +ConVar invalid_convar[EConVarType_MAX + 1] = { + EConVarType_Bool, + EConVarType_Int16, + EConVarType_UInt16, + EConVarType_Int32, + EConVarType_UInt32, + EConVarType_Int64, + EConVarType_UInt64, + EConVarType_Float32, + EConVarType_Float64, + EConVarType_String, + EConVarType_Color, + EConVarType_Vector2, + EConVarType_Vector3, + EConVarType_Vector4, + EConVarType_Qangle, + EConVarType_Invalid // EConVarType_MAX +}; + +// Strictly for invalid convar creation +ConVar::ConVar(EConVarType type) : + m_pszName(""), + m_cvvDefaultValue(nullptr), + m_cvvMinValue(nullptr), + m_cvvMaxValue(nullptr), + m_pszHelpString("This convar is being accessed prior to ConVar_Register being called"), + m_eVarType(type) +{ +} + +ConVar* ConVar_Invalid(EConVarType type) +{ + if (type == EConVarType_Invalid) + { + return &invalid_convar[EConVarType_MAX]; + } + return &invalid_convar[type]; +} + +void ConVarRefAbstract::Init(ConVarHandle defaultHandle, EConVarType type) +{ + this->m_Handle.Invalidate(); + this->m_ConVar = nullptr; + + // qword_191A3D8 + if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle)) == nullptr) + { + this->m_ConVar = ConVar_Invalid(type); + // technically this + //result = *(char ***)(sub_10B7760((unsigned int)a3) + 80); + } + this->m_Handle = defaultHandle; +} + +void ConVarRefAbstract::sub_10B7C70(const char* name, int32 flags, const char* description, int64 obj) +{ + char **v5; // rax + __m128i v9; // xmm0 + __int16 v10; // ax + __m128i v11; // xmm1 + __m128i v12; // xmm2 + __m128i v13; // xmm3 + __int64 v15; // rax + __int64 v16[3]; // [rsp+0h] [rbp-A0h] BYREF + __m128i v17; // [rsp+18h] [rbp-88h] + __m128i v18; // [rsp+28h] [rbp-78h] + __m128i v19; // [rsp+38h] [rbp-68h] + __m128i v20; // [rsp+48h] [rbp-58h] + __int16 v21; // [rsp+58h] [rbp-48h] + int v22; // [rsp+5Ah] [rbp-46h] + __int16 v23; // [rsp+5Eh] [rbp-42h] + _QWORD *v24; // [rsp+60h] [rbp-40h] + _QWORD *v25; // [rsp+68h] [rbp-38h] + + this->m_ConVar = ConVar_Invalid(a5[4].m128i_i16[0]); + this->m_Handle.Invalidate(); + if ( !CommandLine()->HasParam("-tools") && (flags & (0x13084282)) == 0 ) + flags |= FCVAR_DEVELOPMENTONLY; + + v9 = _mm_loadu_si128(a5); + v24 = a1; + v23 = 0; + v10 = a5[4].m128i_i16[0]; + v11 = _mm_loadu_si128(a5 + 1); + v16[0] = a2; + v12 = _mm_loadu_si128(a5 + 2); + v16[1] = a4; + v13 = _mm_loadu_si128(a5 + 3); + v16[2] = flags; + v21 = v10; + v22 = 0; + v17 = v9; + v18 = v11; + v19 = v12; + v20 = v13; + v25 = a1 + 1; + return sub_10B79F0(v16); +} + +#ifdef CONVAR_WORK_FINISHED + //----------------------------------------------------------------------------- // Various constructors //----------------------------------------------------------------------------- From 39d05aaf559d0fb4a8443d4c8442dbbfc48054f1 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Thu, 5 Oct 2023 09:06:59 +0200 Subject: [PATCH 02/36] clean up flags --- public/tier1/convar.h | 2 +- tier1/convar.cpp | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 947e7c446..c5e91eed9 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -644,7 +644,7 @@ class ConVarRefAbstract *(char *)(obj + 4) = 1; *(float *)(obj + 7) = value; - this->sub_10B7C70(name, flags & 0xFB, description, obj); + this->sub_10B7C70(name, flags &~ FCVAR_DEVELOPMENTONLY, description, obj); } private: diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 9144a6a88..dd94ae2ac 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -731,8 +731,18 @@ void ConVarRefAbstract::sub_10B7C70(const char* name, int32 flags, const char* d this->m_ConVar = ConVar_Invalid(a5[4].m128i_i16[0]); this->m_Handle.Invalidate(); - if ( !CommandLine()->HasParam("-tools") && (flags & (0x13084282)) == 0 ) + if (!CommandLine()->HasParam("-tools") + && (flags & (FCVAR_DEVELOPMENTONLY + |FCVAR_ARCHIVE + |FCVAR_USERINFO + |FCVAR_CHEAT + |FCVAR_RELEASE + |FCVAR_SERVER_CAN_EXECUTE + |FCVAR_CLIENT_CAN_EXECUTE + |FCVAR_CLIENTCMD_CAN_EXECUTE)) == 0) + { flags |= FCVAR_DEVELOPMENTONLY; + } v9 = _mm_loadu_si128(a5); v24 = a1; From f7f2c88ee4400b3cd1bada55515379ce1f183673 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Fri, 6 Oct 2023 00:15:35 +0200 Subject: [PATCH 03/36] progress report --- public/icvar.h | 2 +- public/tier0/icommandline.h | 2 +- public/tier1/convar.h | 75 ++++++++++++++-- tier1/convar.cpp | 166 +++++++++++++++++++++--------------- 4 files changed, 171 insertions(+), 74 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index b7c88d3f9..5f6381f57 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -72,7 +72,7 @@ abstract_class ICvar : public IAppSystem virtual void unk2() = 0; // Register, unregister vars - virtual void RegisterConVar( ConVar *pConVar, int64 nAdditionalFlags, ConVarHandle &pCvarRef, ConVar &pCvar ) = 0; + virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, ConVar** pCvar ) = 0; virtual void UnregisterConVar( ConVarHandle handle ) = 0; virtual ConVar* GetConVar( ConVarHandle handle ) = 0; diff --git a/public/tier0/icommandline.h b/public/tier0/icommandline.h index ee3a1469b..6b53c9932 100644 --- a/public/tier0/icommandline.h +++ b/public/tier0/icommandline.h @@ -1,4 +1,4 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // diff --git a/public/tier1/convar.h b/public/tier1/convar.h index c5e91eed9..8d0622bd4 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -225,6 +225,10 @@ enum EConVarType : short union CVValue_t { + CVValue_t() { memset(this, 0, sizeof(*this)); } + CVValue_t(CVValue_t const& cp) { memcpy(this, &cp, sizeof(*this)); }; + CVValue_t& operator=(CVValue_t other) { memcpy(this, &other, sizeof(*this)); return *this; } + bool m_bValue; short m_i16Value; uint16 m_u16Value; @@ -246,6 +250,8 @@ union CVValue_t // Called when a ConVar changes value //----------------------------------------------------------------------------- typedef void(*FnChangeCallbackGlobal_t)(ConVarRefAbstract *cvar, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); +using FnChangeCallback_t = void(*)(ConVarRefAbstract *cvar, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); +static_assert(sizeof(FnChangeCallback_t) == 0x8, "Wrong size for FnChangeCallback_t"); //----------------------------------------------------------------------------- // ConVar & ConCommand creation listener callbacks @@ -631,6 +637,61 @@ friend class SplitScreenConVarRef; }; #endif +#pragma pack(push,1) +struct ConVarSetup_t +{ + int32 unknown0; // 0x0 + + bool has_default; // 0x4 + bool has_min; // 0x5 + bool has_max; // 0x6 + + CVValue_t default_value; // 0x7 + + char pad3; // 0x17 + + FnChangeCallback_t callback; // 0x18 + EConVarType type; // 0x20 + + int32_t unk1; // 0x22 + int16_t unk2; // 0x26 +}; +#pragma pack(pop) + +static_assert(sizeof(ConVarSetup_t) == 0x28, "ConVarSetup_t is of the wrong size!"); +static_assert(sizeof(ConVarSetup_t) % 8 == 0x0, "ConVarSetup_t isn't 8 bytes aligned!"); + +#pragma pack(push,1) +struct ConVarCreation_t { + const char* name; // 0x0 + const char* description; // 0x8 + int64_t flags; // 0x10 + + int32_t unk1; // 0x18 + + bool has_default; // 0x1C + bool has_min; // 0x1D + bool has_max; // 0x1E + CVValue_t default_value; // 0x1F + + int8_t unk4[33]; // 0x2F + + FnChangeCallback_t callback; // 0x50 + + EConVarType type; // 0x58 + + int32_t unk9; // 0x5A + int16_t unk10; // 0x5E + + ConVarHandle* refHandle; // 0x60 + ConVar** refConVar; // 0x68 +}; +#pragma pack(pop) + +static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); +static_assert(sizeof(ConVarCreation_t) % 8 == 0x0, "ConVarCreation_t isn't 8 bytes aligned!"); +static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); + //----------------------------------------------------------------- // Used to read/write/create? convars (replaces the FindVar method) //----------------------------------------------------------------- @@ -638,12 +699,13 @@ class ConVarRefAbstract { public: // sub_6A66B0 - ConVarRefAbstract(const char* name, int32 flags, const char* description, int64 obj, float value) + ConVarRefAbstract(const char* name, int32 flags, const char* description, ConVarSetup_t obj, float value) : m_ConVar(nullptr) { this->Init(INVALID_CONVAR_HANDLE, EConVarType_Float32); - *(char *)(obj + 4) = 1; - *(float *)(obj + 7) = value; + obj.has_default = true; + obj.default_value.m_flValue = value; + this->sub_10B7C70(name, flags &~ FCVAR_DEVELOPMENTONLY, description, obj); } @@ -652,8 +714,8 @@ class ConVarRefAbstract void Init(ConVarHandle defaultHandle, EConVarType type); // sub_10B7C70 - void sub_10B7C70(const char* name, int32 flags, const char* description, int64 obj); - + void sub_10B7C70(const char* name, int32 flags, const char* description, ConVarSetup_t& obj); +public: // High-speed method to read convar data ConVarHandle m_Handle; ConVar* m_ConVar; @@ -662,6 +724,9 @@ class ConVarRefAbstract // sub_10B7760 ConVar* ConVar_Invalid(EConVarType type); +// sub_10B79F0 +void ConVar_Add(const ConVarCreation_t& setup); + class ConVar { friend class ConVarRegList; diff --git a/tier1/convar.cpp b/tier1/convar.cpp index dd94ae2ac..f320fcd3d 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -26,6 +26,20 @@ #endif #include "tier0/memdbgon.h" +template M get_member_type(M T::*); +template T get_class_type(M T::*); + +template +constexpr int32_t* offset_of() +{ + return (&(((T*)0)->*M)); +} + +#define OFFSET_OF(m) offset_of() // Comment this out when we release. //#define ALLOW_DEVELOPMENT_CVARS @@ -93,12 +107,20 @@ class ConCommandRegList static bool s_bConCommandsRegistered; }; -bool ConCommandRegList::s_bConCommandsRegistered = false; +#include +PLUGIN_GLOBALVARS(); +void RegisterConVar(ConVarCreation_t& setup) +{ + META_CONPRINTF( "Registering convar: %s!\n", setup.name); + g_pCVar->RegisterConVar(setup, s_nCVarFlag, setup.refHandle, setup.refConVar); + if (!setup.refHandle->IsValid()) + { + Plat_FatalErrorFunc("RegisterConCommand: Unknown error registering convar \"%s\"!\n", setup.name); + DebuggerBreakIfDebugging(); + } +} -template -void check_size() { - static_assert(ExpectedSize == RealSize, "Size mismatch"); -}; +bool ConCommandRegList::s_bConCommandsRegistered = false; class ConVarRegList; static ConVarRegList* s_pConVarRegList = nullptr; @@ -106,11 +128,7 @@ static ConVarRegList* s_pConVarRegList = nullptr; class ConVarRegList { public: - ConVarRegList() - { - check_size(); - //check_size(); - } + ConVarRegList() {} static bool AreConVarsRegistered() { @@ -128,16 +146,7 @@ class ConVarRegList { FOR_EACH_VEC(s_pConVarRegList->m_Vec, i) { - ConVar* pConVar = &pList->m_Vec[i]; - ConVarHandle hndl; - //g_pCVar->RegisterConVar(pConVar, s_nCVarFlag, hndl); - //pConVar->SetHandle(hndl); - - if (!hndl.IsValid()) - { - Plat_FatalErrorFunc("RegisterConCommand: Unknown error registering convar \"%s\"!\n", pConVar->m_pszName); - DebuggerBreakIfDebugging(); - } + RegisterConVar(pList->m_Vec[i]); } ConVarRegList *pNext = pList->m_pNext; @@ -148,19 +157,54 @@ class ConVarRegList s_pConVarRegList = nullptr; } } + + int Count() const + { + return m_Vec.Count(); + } + private: - CUtlVectorFixed m_Vec; + friend void ConVar_Add(const ConVarCreation_t& setup); + + void SetNextList(ConVarRegList* list) + { + m_pNext = list; + } + + void Add(const ConVarCreation_t& setup) + { + m_Vec.AddToTail(setup); + } + + CUtlVectorFixed m_Vec; ConVarRegList* m_pNext = nullptr; static bool s_bConVarsRegistered; }; - bool ConVarRegList::s_bConVarsRegistered = false; +static_assert(sizeof(ConVarRegList) == 0x2BD0, "Size mismatch"); + +void ConVar_Add(const ConVarCreation_t& setup) +{ + //if ( byte_1919861 ) + //return sub_10B7990(); + + if (!s_pConVarRegList || s_pConVarRegList->Count() == 100) + { + ConVarRegList* newList = new ConVarRegList; + newList->SetNextList(s_pConVarRegList); + + s_pConVarRegList = newList; + } + + s_pConVarRegList->Add(setup); +} + //----------------------------------------------------------------------------- // Called by the framework to register ConCommandBases with the ICVar //----------------------------------------------------------------------------- -void ConVar_Register( int64 nCVarFlag) +void ConVar_Register( int64 nCVarFlag ) { if ( !g_pCVar || s_bRegistered ) return; @@ -169,9 +213,7 @@ void ConVar_Register( int64 nCVarFlag) s_nCVarFlag = nCVarFlag; ConCommandRegList::RegisterAll(); -#ifdef CONVAR_WORK_FINISHED ConVarRegList::RegisterAll(); -#endif // CONVAR_WORK_FINISHED } void ConVar_Unregister( ) @@ -182,7 +224,6 @@ void ConVar_Unregister( ) s_bRegistered = false; } - //----------------------------------------------------------------------------- // Purpose: Default constructor //----------------------------------------------------------------------------- @@ -700,7 +741,7 @@ void ConVarRefAbstract::Init(ConVarHandle defaultHandle, EConVarType type) this->m_ConVar = nullptr; // qword_191A3D8 - if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle)) == nullptr) + if (g_pCVar && g_pCVar->GetConVar(defaultHandle) == nullptr) { this->m_ConVar = ConVar_Invalid(type); // technically this @@ -709,29 +750,14 @@ void ConVarRefAbstract::Init(ConVarHandle defaultHandle, EConVarType type) this->m_Handle = defaultHandle; } -void ConVarRefAbstract::sub_10B7C70(const char* name, int32 flags, const char* description, int64 obj) -{ - char **v5; // rax - __m128i v9; // xmm0 - __int16 v10; // ax - __m128i v11; // xmm1 - __m128i v12; // xmm2 - __m128i v13; // xmm3 - __int64 v15; // rax - __int64 v16[3]; // [rsp+0h] [rbp-A0h] BYREF - __m128i v17; // [rsp+18h] [rbp-88h] - __m128i v18; // [rsp+28h] [rbp-78h] - __m128i v19; // [rsp+38h] [rbp-68h] - __m128i v20; // [rsp+48h] [rbp-58h] - __int16 v21; // [rsp+58h] [rbp-48h] - int v22; // [rsp+5Ah] [rbp-46h] - __int16 v23; // [rsp+5Eh] [rbp-42h] - _QWORD *v24; // [rsp+60h] [rbp-40h] - _QWORD *v25; // [rsp+68h] [rbp-38h] - - this->m_ConVar = ConVar_Invalid(a5[4].m128i_i16[0]); +//std::exit((int64_t)(&((ConVarSetup_t*)nullptr)->type)); + +void ConVarRefAbstract::sub_10B7C70(const char* name, int32 flags, const char* description, ConVarSetup_t& obj) +{ + this->m_ConVar = ConVar_Invalid(obj.type); this->m_Handle.Invalidate(); - if (!CommandLine()->HasParam("-tools") + + if (!CommandLine()->HasParm("-tools") && (flags & (FCVAR_DEVELOPMENTONLY |FCVAR_ARCHIVE |FCVAR_USERINFO @@ -743,25 +769,31 @@ void ConVarRefAbstract::sub_10B7C70(const char* name, int32 flags, const char* d { flags |= FCVAR_DEVELOPMENTONLY; } + + ConVarCreation_t cvar; - v9 = _mm_loadu_si128(a5); - v24 = a1; - v23 = 0; - v10 = a5[4].m128i_i16[0]; - v11 = _mm_loadu_si128(a5 + 1); - v16[0] = a2; - v12 = _mm_loadu_si128(a5 + 2); - v16[1] = a4; - v13 = _mm_loadu_si128(a5 + 3); - v16[2] = flags; - v21 = v10; - v22 = 0; - v17 = v9; - v18 = v11; - v19 = v12; - v20 = v13; - v25 = a1 + 1; - return sub_10B79F0(v16); + cvar.name = name; + cvar.description = description; + cvar.flags = flags; + + // 0x0 through 0x28 + /* 0x18 */ cvar.unk1 = obj.unknown0; // 0x0 + /* 0x1C */ cvar.has_default = obj.has_default; // 0x4 + /* 0x1D */ cvar.has_min = obj.has_min; // 0x5 + /* 0x1E */ cvar.has_max = obj.has_min; // 0x6 + /* 0x1F */ cvar.default_value = obj.default_value; // 0x7 + + /* 0x2F */ // 0x17 ???????????? + + /* 0x50 */ cvar.callback = obj.callback; // 0x18 + /* 0x58 */ cvar.type = obj.type; // 0x20 + /* 0x5A */ cvar.unk9 = obj.unk1; // 0x22 + /* 0x5E */ cvar.unk10 = obj.unk2; // 0x28 + + cvar.refHandle = &this->m_Handle; + cvar.refConVar = &this->m_ConVar; + + ConVar_Add(cvar); } #ifdef CONVAR_WORK_FINISHED From 79b81f034eec4e342daaf9d209d72cc2b9f92bc0 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Fri, 6 Oct 2023 00:24:05 +0200 Subject: [PATCH 04/36] remove some debug --- tier1/convar.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/tier1/convar.cpp b/tier1/convar.cpp index f320fcd3d..e182b7ac3 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -26,25 +26,6 @@ #endif #include "tier0/memdbgon.h" -template M get_member_type(M T::*); -template T get_class_type(M T::*); - -template -constexpr int32_t* offset_of() -{ - return (&(((T*)0)->*M)); -} - -#define OFFSET_OF(m) offset_of() - -// Comment this out when we release. -//#define ALLOW_DEVELOPMENT_CVARS - - //----------------------------------------------------------------------------- // Statically constructed list of ConCommandBases, // used for registering them with the ICVar interface @@ -107,11 +88,8 @@ class ConCommandRegList static bool s_bConCommandsRegistered; }; -#include -PLUGIN_GLOBALVARS(); void RegisterConVar(ConVarCreation_t& setup) { - META_CONPRINTF( "Registering convar: %s!\n", setup.name); g_pCVar->RegisterConVar(setup, s_nCVarFlag, setup.refHandle, setup.refConVar); if (!setup.refHandle->IsValid()) { From da1669dfbc9cd3547baa955d8b119dc012ae3219 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sat, 7 Oct 2023 00:58:54 +0200 Subject: [PATCH 05/36] Template the convar class --- public/icvar.h | 11 ++-- public/tier1/convar.h | 146 +++++++++++++++++++++++++++--------------- tier1/convar.cpp | 124 +++++++++++------------------------ 3 files changed, 137 insertions(+), 144 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 5f6381f57..10f421c59 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -17,14 +17,13 @@ class ConCommandBase; class ConCommand; -class ConVar; class Color; class IConVarListener; +class IConVar; class CConVarDetail; struct ConVarSnapshot_t; union CVValue_t; class KeyValues; -class ConVarRefAbstract; //----------------------------------------------------------------------------- @@ -47,7 +46,7 @@ abstract_class ICvar : public IAppSystem // Install a global change callback (to be called when any convar changes) virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; virtual void RemoveGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; - virtual void CallGlobalChangeCallbacks( ConVarRefAbstract *var, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) = 0; + virtual void CallGlobalChangeCallbacks( ConVar* var, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) = 0; // Reverts cvars which contain a specific flag virtual void RevertFlaggedConVars( int nFlag ) = 0; @@ -72,16 +71,16 @@ abstract_class ICvar : public IAppSystem virtual void unk2() = 0; // Register, unregister vars - virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, ConVar** pCvar ) = 0; + virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, IConVar** pCvar ) = 0; virtual void UnregisterConVar( ConVarHandle handle ) = 0; - virtual ConVar* GetConVar( ConVarHandle handle ) = 0; + virtual IConVar* GetConVar( ConVarHandle handle ) = 0; // Register, unregister commands virtual ConCommandHandle RegisterConCommand( ConCommand *pCmd, int64 nAdditionalFlags = 0 ) = 0; virtual void UnregisterConCommand( ConCommandHandle handle ) = 0; virtual ConCommand* GetCommand( ConCommandHandle handle ) = 0; - virtual void QueueThreadSetValue( ConVarRefAbstract *ref, CSplitScreenSlot nSlot, CVValue_t *value ) = 0; + virtual void QueueThreadSetValue( ConVar* ref, CSplitScreenSlot nSlot, CVValue_t* value ) = 0; }; //----------------------------------------------------------------------------- diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 8d0622bd4..6bf4348ab 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -24,6 +24,8 @@ #include "mathlib/vector4d.h" #include "playerslot.h" +#include + #ifdef _WIN32 #define FORCEINLINE_CVAR FORCEINLINE #elif POSIX @@ -44,11 +46,11 @@ //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- -class ConVar; +class IConVar; class CCommand; class ConCommand; class ConCommandBase; -class ConVarRefAbstract; +class ConVar; class ConCommandRefAbstract; class ALIGN8 ConVarHandle @@ -229,28 +231,49 @@ union CVValue_t CVValue_t(CVValue_t const& cp) { memcpy(this, &cp, sizeof(*this)); }; CVValue_t& operator=(CVValue_t other) { memcpy(this, &other, sizeof(*this)); return *this; } + template + FORCEINLINE_CVAR CVValue_t& operator=(T other); + bool m_bValue; - short m_i16Value; - uint16 m_u16Value; - int m_i32Value; - uint m_u32Value; - int64 m_i64Value; - uint64 m_u64Value; + int16_t m_i16Value; + uint16_t m_u16Value; + int32_t m_i32Value; + uint32_t m_u32Value; + int64_t m_i64Value; + uint64_t m_u64Value; float m_flValue; double m_dbValue; - const char *m_szValue; + const char* m_szValue; Color m_clrValue; Vector2D m_vec2Value; Vector m_vec3Value; Vector4D m_vec4Value; QAngle m_angValue; }; +static_assert(sizeof(float) == sizeof(int32_t), "Wrong float type size for ConVar!"); +static_assert(sizeof(double) == sizeof(int64_t), "Wrong double type size for ConVar!"); + +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( bool other ) { m_bValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( int16_t other ) { m_i16Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( uint16_t other ) { m_u16Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( int32_t other ) { m_i32Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( uint32_t other ) { m_u32Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( int64_t other ) { m_i64Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( uint64_t other ) { m_u64Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( float other ) { m_flValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( double other ) { m_dbValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const char* other ) { m_szValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Color& other ) { m_clrValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector2D& other ) { m_vec2Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector& other ) { m_vec3Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector4D& other ) { m_vec4Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const QAngle& other ) { m_angValue = other; return *this; } //----------------------------------------------------------------------------- // Called when a ConVar changes value //----------------------------------------------------------------------------- -typedef void(*FnChangeCallbackGlobal_t)(ConVarRefAbstract *cvar, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); -using FnChangeCallback_t = void(*)(ConVarRefAbstract *cvar, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); +typedef void(*FnChangeCallbackGlobal_t)(ConVar* cvar, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); +using FnChangeCallback_t = void(*)(ConVar* cvar, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); static_assert(sizeof(FnChangeCallback_t) == 0x8, "Wrong size for FnChangeCallback_t"); //----------------------------------------------------------------------------- @@ -259,7 +282,7 @@ static_assert(sizeof(FnChangeCallback_t) == 0x8, "Wrong size for FnChangeCallbac class ICVarListenerCallbacks { public: - virtual void OnConVarCreated( ConVarRefAbstract *pNewCvar ) = 0; + virtual void OnConVarCreated( ConVar* pNewCvar ) = 0; virtual void OnConCommandCreated( ConCommandRefAbstract *pNewCommand ) = 0; }; @@ -509,7 +532,6 @@ friend class ConCommandHandle; class ConVar { friend class CCvar; -friend class ConVarRef; friend class SplitScreenConVarRef; public: @@ -640,6 +662,20 @@ friend class SplitScreenConVarRef; #pragma pack(push,1) struct ConVarSetup_t { + ConVarSetup_t() : + unknown0(0), + has_default(false), + has_min(false), + has_max(false), + default_value(), + min_value(), + max_value(), + callback(nullptr), + type(EConVarType_Invalid), + unk1(0), + unk2(0) + {} + int32 unknown0; // 0x0 bool has_default; // 0x4 @@ -647,44 +683,33 @@ struct ConVarSetup_t bool has_max; // 0x6 CVValue_t default_value; // 0x7 + CVValue_t min_value; // 0x17 + CVValue_t max_value; // 0x27 - char pad3; // 0x17 + char pad; // 0x37 - FnChangeCallback_t callback; // 0x18 - EConVarType type; // 0x20 + FnChangeCallback_t callback; // 0x38 + EConVarType type; // 0x40 - int32_t unk1; // 0x22 - int16_t unk2; // 0x26 + int32_t unk1; // 0x42 + int16_t unk2; // 0x46 }; #pragma pack(pop) - -static_assert(sizeof(ConVarSetup_t) == 0x28, "ConVarSetup_t is of the wrong size!"); +static_assert(sizeof(ConVarSetup_t) == 0x48, "ConVarSetup_t is of the wrong size!"); static_assert(sizeof(ConVarSetup_t) % 8 == 0x0, "ConVarSetup_t isn't 8 bytes aligned!"); #pragma pack(push,1) struct ConVarCreation_t { + ConVarCreation_t() { memset(this, 0, sizeof(*this)); } + const char* name; // 0x0 const char* description; // 0x8 int64_t flags; // 0x10 - int32_t unk1; // 0x18 - - bool has_default; // 0x1C - bool has_min; // 0x1D - bool has_max; // 0x1E - CVValue_t default_value; // 0x1F - - int8_t unk4[33]; // 0x2F - - FnChangeCallback_t callback; // 0x50 - - EConVarType type; // 0x58 - - int32_t unk9; // 0x5A - int16_t unk10; // 0x5E + ConVarSetup_t setup; // 0x18 ConVarHandle* refHandle; // 0x60 - ConVar** refConVar; // 0x68 + IConVar** refConVar; // 0x68 }; #pragma pack(pop) @@ -695,44 +720,63 @@ static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); //----------------------------------------------------------------- // Used to read/write/create? convars (replaces the FindVar method) //----------------------------------------------------------------- -class ConVarRefAbstract +class ConVar { public: // sub_6A66B0 - ConVarRefAbstract(const char* name, int32 flags, const char* description, ConVarSetup_t obj, float value) : m_ConVar(nullptr) + template + ConVar(const char* name, int32 flags, const char* description, T value) { - this->Init(INVALID_CONVAR_HANDLE, EConVarType_Float32); + this->Init(INVALID_CONVAR_HANDLE, TranslateType()); - obj.has_default = true; - obj.default_value.m_flValue = value; + ConVarSetup_t setup; + setup.has_default = true; + setup.default_value = value; + setup.type = TranslateType(); - this->sub_10B7C70(name, flags &~ FCVAR_DEVELOPMENTONLY, description, obj); + this->sub_10B7C70(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } private: + template + static constexpr EConVarType TranslateType(); + // sub_10B7BC0 void Init(ConVarHandle defaultHandle, EConVarType type); // sub_10B7C70 - void sub_10B7C70(const char* name, int32 flags, const char* description, ConVarSetup_t& obj); + void sub_10B7C70(const char* name, int32 flags, const char* description, const ConVarSetup_t& obj); public: // High-speed method to read convar data ConVarHandle m_Handle; - ConVar* m_ConVar; + IConVar* m_ConVar; }; -// sub_10B7760 -ConVar* ConVar_Invalid(EConVarType type); +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Bool; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Int16; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_UInt16; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Int32; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_UInt32; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Int64; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_UInt64; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Float32; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Float64; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_String; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Color; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Vector2; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Vector3; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Vector4; } +template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Qangle; } -// sub_10B79F0 -void ConVar_Add(const ConVarCreation_t& setup); +// sub_10B7760 +IConVar* ConVar_Invalid(EConVarType type); -class ConVar +class IConVar { friend class ConVarRegList; -friend class ConVarRefAbstract; +friend class ConVar; public: - ConVar(EConVarType type); + IConVar(EConVarType type); protected: const char* m_pszName; CVValue_t* m_cvvDefaultValue; diff --git a/tier1/convar.cpp b/tier1/convar.cpp index e182b7ac3..6fdc097a3 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -88,12 +88,12 @@ class ConCommandRegList static bool s_bConCommandsRegistered; }; -void RegisterConVar(ConVarCreation_t& setup) +void RegisterConVar( ConVarCreation_t& setup ) { - g_pCVar->RegisterConVar(setup, s_nCVarFlag, setup.refHandle, setup.refConVar); + g_pCVar->RegisterConVar( setup, s_nCVarFlag, setup.refHandle, setup.refConVar ); if (!setup.refHandle->IsValid()) { - Plat_FatalErrorFunc("RegisterConCommand: Unknown error registering convar \"%s\"!\n", setup.name); + Plat_FatalErrorFunc( "RegisterConCommand: Unknown error registering convar \"%s\"!\n", setup.name ); DebuggerBreakIfDebugging(); } } @@ -115,21 +115,21 @@ class ConVarRegList static void RegisterAll() { - if (!s_bConVarsRegistered && g_pCVar) + if ( !s_bConVarsRegistered && g_pCVar ) { s_bConVarsRegistered = true; - ConVarRegList* pList = s_pConVarRegList; - while (pList != nullptr) + ConVarRegList* list = s_pConVarRegList; + while ( list != nullptr ) { - FOR_EACH_VEC(s_pConVarRegList->m_Vec, i) + FOR_EACH_VEC( s_pConVarRegList->m_Vec, i ) { - RegisterConVar(pList->m_Vec[i]); + RegisterConVar( list->m_Vec[i] ); } - ConVarRegList *pNext = pList->m_pNext; - delete pList; - pList = pNext; + ConVarRegList *pNext = list->m_pNext; + delete list; + list = pNext; } s_pConVarRegList = nullptr; @@ -142,16 +142,16 @@ class ConVarRegList } private: - friend void ConVar_Add(const ConVarCreation_t& setup); + friend void SetupConVar( ConVarCreation_t& setup ); - void SetNextList(ConVarRegList* list) + void SetNextList( ConVarRegList* list ) { m_pNext = list; } - void Add(const ConVarCreation_t& setup) + void Add( const ConVarCreation_t& setup ) { - m_Vec.AddToTail(setup); + m_Vec.AddToTail( setup ); } CUtlVectorFixed m_Vec; @@ -159,24 +159,28 @@ class ConVarRegList static bool s_bConVarsRegistered; }; -bool ConVarRegList::s_bConVarsRegistered = false; - static_assert(sizeof(ConVarRegList) == 0x2BD0, "Size mismatch"); -void ConVar_Add(const ConVarCreation_t& setup) +bool ConVarRegList::s_bConVarsRegistered = false; + +// sub_10B79F0 +void SetupConVar( ConVarCreation_t& setup ) { - //if ( byte_1919861 ) - //return sub_10B7990(); + if ( s_bRegistered ) + { + RegisterConVar(setup); + return; + } - if (!s_pConVarRegList || s_pConVarRegList->Count() == 100) + if ( !s_pConVarRegList || s_pConVarRegList->Count() == 100 ) { ConVarRegList* newList = new ConVarRegList; - newList->SetNextList(s_pConVarRegList); + newList->SetNextList( s_pConVarRegList ); s_pConVarRegList = newList; } - s_pConVarRegList->Add(setup); + s_pConVarRegList->Add( setup ); } //----------------------------------------------------------------------------- @@ -185,7 +189,9 @@ void ConVar_Add(const ConVarCreation_t& setup) void ConVar_Register( int64 nCVarFlag ) { if ( !g_pCVar || s_bRegistered ) + { return; + } s_bRegistered = true; s_nCVarFlag = nCVarFlag; @@ -674,7 +680,7 @@ bool ConCommand::CanAutoComplete( void ) // //----------------------------------------------------------------------------- -ConVar invalid_convar[EConVarType_MAX + 1] = { +IConVar invalid_convar[EConVarType_MAX + 1] = { EConVarType_Bool, EConVarType_Int16, EConVarType_UInt16, @@ -694,7 +700,7 @@ ConVar invalid_convar[EConVarType_MAX + 1] = { }; // Strictly for invalid convar creation -ConVar::ConVar(EConVarType type) : +IConVar::IConVar(EConVarType type) : m_pszName(""), m_cvvDefaultValue(nullptr), m_cvvMinValue(nullptr), @@ -704,7 +710,7 @@ ConVar::ConVar(EConVarType type) : { } -ConVar* ConVar_Invalid(EConVarType type) +IConVar* ConVar_Invalid(EConVarType type) { if (type == EConVarType_Invalid) { @@ -713,7 +719,7 @@ ConVar* ConVar_Invalid(EConVarType type) return &invalid_convar[type]; } -void ConVarRefAbstract::Init(ConVarHandle defaultHandle, EConVarType type) +void ConVar::Init(ConVarHandle defaultHandle, EConVarType type) { this->m_Handle.Invalidate(); this->m_ConVar = nullptr; @@ -730,9 +736,9 @@ void ConVarRefAbstract::Init(ConVarHandle defaultHandle, EConVarType type) //std::exit((int64_t)(&((ConVarSetup_t*)nullptr)->type)); -void ConVarRefAbstract::sub_10B7C70(const char* name, int32 flags, const char* description, ConVarSetup_t& obj) +void ConVar::sub_10B7C70(const char* name, int32 flags, const char* description, const ConVarSetup_t& setup) { - this->m_ConVar = ConVar_Invalid(obj.type); + this->m_ConVar = ConVar_Invalid(setup.type); this->m_Handle.Invalidate(); if (!CommandLine()->HasParm("-tools") @@ -754,24 +760,12 @@ void ConVarRefAbstract::sub_10B7C70(const char* name, int32 flags, const char* d cvar.description = description; cvar.flags = flags; - // 0x0 through 0x28 - /* 0x18 */ cvar.unk1 = obj.unknown0; // 0x0 - /* 0x1C */ cvar.has_default = obj.has_default; // 0x4 - /* 0x1D */ cvar.has_min = obj.has_min; // 0x5 - /* 0x1E */ cvar.has_max = obj.has_min; // 0x6 - /* 0x1F */ cvar.default_value = obj.default_value; // 0x7 - - /* 0x2F */ // 0x17 ???????????? - - /* 0x50 */ cvar.callback = obj.callback; // 0x18 - /* 0x58 */ cvar.type = obj.type; // 0x20 - /* 0x5A */ cvar.unk9 = obj.unk1; // 0x22 - /* 0x5E */ cvar.unk10 = obj.unk2; // 0x28 + cvar.setup = setup; cvar.refHandle = &this->m_Handle; cvar.refConVar = &this->m_ConVar; - ConVar_Add(cvar); + SetupConVar(cvar); } #ifdef CONVAR_WORK_FINISHED @@ -1202,50 +1196,6 @@ class CEmptyConVar : public ConVar static CEmptyConVar s_EmptyConVar; -ConVarRef::ConVarRef( const char *pName ) -{ - Init( pName, false ); -} - -ConVarRef::ConVarRef( const char *pName, bool bIgnoreMissing ) -{ - Init( pName, bIgnoreMissing ); -} - -void ConVarRef::Init( const char *pName, bool bIgnoreMissing ) -{ - m_pConVar = g_pCVar ? g_pCVar->FindVar( pName ) : &s_EmptyConVar; - if ( !m_pConVar ) - { - m_pConVar = &s_EmptyConVar; - } - m_pConVarState = static_cast< ConVar * >( m_pConVar ); - if( !IsValid() ) - { - static bool bFirst = true; - if ( g_pCVar || bFirst ) - { - if ( !bIgnoreMissing ) - { - Warning( "ConVarRef %s doesn't point to an existing ConVar\n", pName ); - } - bFirst = false; - } - } -} - -ConVarRef::ConVarRef( IConVar *pConVar ) -{ - m_pConVar = pConVar ? pConVar : &s_EmptyConVar; - m_pConVarState = static_cast< ConVar * >( m_pConVar ); -} - -bool ConVarRef::IsValid() const -{ - return m_pConVar != &s_EmptyConVar; -} - - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- From 4ea9e4f7ea13b6664368b6e8ffafd0cffe451d80 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sat, 7 Oct 2023 22:49:43 +0200 Subject: [PATCH 06/36] progress report --- public/icvar.h | 21 +- public/tier1/convar.h | 396 ++++++++++++-------------------------- tier1/convar.cpp | 437 ++++++++++++++---------------------------- 3 files changed, 280 insertions(+), 574 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 10f421c59..62902501c 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -1,4 +1,4 @@ -//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -15,7 +15,6 @@ #include "tier1/utlvector.h" #include "tier0/memalloc.h" -class ConCommandBase; class ConCommand; class Color; class IConVarListener; @@ -38,10 +37,10 @@ abstract_class ICvar : public IAppSystem virtual ConVarHandle FindNextConVar( ConVarHandle prev ) = 0; virtual void SetConVarValue( ConVarHandle cvarid, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue ) = 0; - virtual ConCommandHandle FindCommand( const char *name ) = 0; - virtual ConCommandHandle FindFirstCommand() = 0; - virtual ConCommandHandle FindNextCommand( ConCommandHandle prev ) = 0; - virtual void DispatchConCommand( ConCommandHandle cmd, const CCommandContext &ctx, const CCommand &args ) = 0; + virtual ConVarHandle FindCommand( const char *name ) = 0; + virtual ConVarHandle FindFirstCommand() = 0; + virtual ConVarHandle FindNextCommand( ConVarHandle prev ) = 0; + virtual void DispatchConCommand( ConVarHandle cmd, const CCommandContext &ctx, const CCommand &args ) = 0; // Install a global change callback (to be called when any convar changes) virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; @@ -71,14 +70,14 @@ abstract_class ICvar : public IAppSystem virtual void unk2() = 0; // Register, unregister vars - virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, IConVar** pCvar ) = 0; - virtual void UnregisterConVar( ConVarHandle handle ) = 0; + virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, IConVar** pCvar ) = 0; + virtual void UnregisterConVar( ConVarHandle handle ) = 0; virtual IConVar* GetConVar( ConVarHandle handle ) = 0; // Register, unregister commands - virtual ConCommandHandle RegisterConCommand( ConCommand *pCmd, int64 nAdditionalFlags = 0 ) = 0; - virtual void UnregisterConCommand( ConCommandHandle handle ) = 0; - virtual ConCommand* GetCommand( ConCommandHandle handle ) = 0; + virtual ConVarHandle RegisterConCommand( const ConCommandCreation_t& setup, int64 nAdditionalFlags = 0 ) = 0; + virtual void UnregisterConCommand( ConVarHandle handle ) = 0; + virtual ConCommand* GetCommand( ConVarHandle handle ) = 0; virtual void QueueThreadSetValue( ConVar* ref, CSplitScreenSlot nSlot, CVValue_t* value ) = 0; }; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 6bf4348ab..a75e51735 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -1,4 +1,4 @@ -//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -49,40 +49,85 @@ class IConVar; class CCommand; class ConCommand; -class ConCommandBase; class ConVar; class ConCommandRefAbstract; -class ALIGN8 ConVarHandle +struct CVarCreationBase_t { -public: - ConVarHandle() { m_value = 0xFFFFFFFF; }; + CVarCreationBase_t( ) : + name( nullptr ), + description( nullptr ), + flags( 0 ) + {} - bool IsValid() const; - void Invalidate(); + bool IsFlagSet( int64_t flag ) const; + void AddFlags( int64_t flags ); + void RemoveFlags( int64_t flags ); + int64_t GetFlags() const; -private: - friend bool operator!=(const ConVarHandle& lhs, const ConVarHandle& rhs); - friend bool operator==(const ConVarHandle& lhs, const ConVarHandle& rhs); + const char* name; + const char* description; + int64_t flags; +}; + +inline bool CVarCreationBase_t::IsFlagSet( int64_t flag ) const +{ + return ( flag & this->flags ) ? true : false; +} + +inline void CVarCreationBase_t::AddFlags( int64_t flags ) +{ + this->flags |= flags; + +#ifdef ALLOW_DEVELOPMENT_CVARS + this->flags &= ~FCVAR_DEVELOPMENTONLY; +#endif +} + +inline void CVarCreationBase_t::RemoveFlags( int64_t flags ) +{ + this->flags &= ~flags; +} + +inline int64_t CVarCreationBase_t::GetFlags( void ) const +{ + return this->flags; +} - uint32 GetValue() const { return m_value; }; +class ConVarHandle +{ +public: + ConVarHandle( uint16_t convarIndex = -1, uint16_t unk = -1, uint32_t handle = -1) : + m_convarIndex(convarIndex), + m_unknown1(unk), + m_handleIndex(handle) + {} - uint32 m_value; -} ALIGN8_POST; + bool IsValid( ) const; + void Invalidate( ); -inline bool operator!=(const ConVarHandle& lhs, const ConVarHandle& rhs) { return lhs.m_value != rhs.m_value; } -inline bool operator==(const ConVarHandle& lhs, const ConVarHandle& rhs) { return lhs.m_value == rhs.m_value; } + uint16_t GetConVarIndex() const { return m_convarIndex; } + uint32_t GetIndex() const { return m_handleIndex; } + +private: + uint16_t m_convarIndex; + uint16_t m_unknown1; + uint32_t m_handleIndex; +}; +static_assert(sizeof(ConVarHandle) == 0x8, "ConVarHandle is of the wrong size!"); static const ConVarHandle INVALID_CONVAR_HANDLE = ConVarHandle(); inline bool ConVarHandle::IsValid() const { - return *this != INVALID_CONVAR_HANDLE; + return m_convarIndex != 0xFFFF; } inline void ConVarHandle::Invalidate() { - m_value = INVALID_CONVAR_HANDLE.GetValue(); + m_convarIndex = 0xFFFF; + m_unknown1 = 0xFFFF; + m_handleIndex = 0x0; } enum CommandTarget_t @@ -115,28 +160,6 @@ class CCommandContext CPlayerSlot m_nPlayerSlot; }; -class ALIGN8 ConCommandHandle -{ -public: - ConCommandHandle() { value = kInvalidConCommandHandle; }; - - bool IsValid() { return value != kInvalidConCommandHandle; } - uint16 Get() { return value; } - void Set( uint16 _value ) { value = _value; } - void Reset() { value = kInvalidConCommandHandle; } - - bool HasCallback() const; - void Dispatch( const CCommandContext& context, const CCommand& command ); - - void Unregister(); - -private: - uint16 value = kInvalidConCommandHandle; - -private: - static const uint16 kInvalidConCommandHandle = 0xFFFF; -} ALIGN8_POST; - struct CSplitScreenSlot { CSplitScreenSlot( int index ) @@ -286,8 +309,6 @@ class ICVarListenerCallbacks virtual void OnConCommandCreated( ConCommandRefAbstract *pNewCommand ) = 0; }; - - //----------------------------------------------------------------------------- // Called when a ConCommand needs to execute //----------------------------------------------------------------------------- @@ -319,47 +340,9 @@ class ICommandCompletionCallback class ConCommandRefAbstract { public: - ConCommandHandle handle; -}; - -//----------------------------------------------------------------------------- -// Purpose: The base console invoked command/cvar interface -//----------------------------------------------------------------------------- -class ConCommandBase -{ - friend class CCvar; - friend class ConCommand; - -protected: - ConCommandBase( void ); -public: - - ~ConCommandBase( void ); - // Check flag - bool IsFlagSet( int64 flag ) const; - // Set flag - void AddFlags( int64 flags ); - // Clear flag - void RemoveFlags( int64 flags ); - - int64 GetFlags() const; - - // Return name of cvar - const char *GetName( void ) const; - - // Return help text for cvar - const char *GetHelpText( void ) const; - -private: - // Static data - const char *m_pszName; - const char *m_pszHelpString; - - // ConVar flags - int64 m_nFlags; + ConVarHandle handle; }; - //----------------------------------------------------------------------------- // Command tokenizer //----------------------------------------------------------------------------- @@ -445,64 +428,37 @@ inline const char *CCommand::operator[]( int nIndex ) const //----------------------------------------------------------------------------- // Purpose: The console invoked command //----------------------------------------------------------------------------- -class ConCommand : public ConCommandBase +struct ConCommandCreation_t : CVarCreationBase_t { -friend class CCvar; -friend class ConCommandHandle; - -public: - typedef ConCommandBase BaseClass; - - ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallback_t callback, - const char *pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallbackVoid_t callback, - const char *pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( ConCommandRefAbstract* pReferenceOut, const char* pName, FnCommandCallbackNoContext_t callback, - const char* pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, ICommandCallback *pCallback, - const char *pHelpString = 0, int64 flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 ); - - ~ConCommand( void ); - - // Used internally by OneTimeInit to initialize/shutdown - void Init(); - void Shutdown(); - - void Create( const char *pName, const char *pHelpString = 0, - int64 flags = 0 ); - - int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands ); - - bool CanAutoComplete( void ); - - inline ConCommandRefAbstract *GetRef( void ) const - { - return m_pReference; - } - - inline void SetHandle( ConCommandHandle hndl ) - { - m_pReference->handle = hndl; - } + ConCommandCreation_t() : + has_complitioncallback(false), + is_interface(false), + refHandle(nullptr) + {} -private: // Call this function when executing the command - class CallbackInfo_t + struct CallbackInfo_t { - public: + CallbackInfo_t() : + fnCommandCallback(nullptr), + is_interface(false), + is_voidcallback(false), + is_contextless(false) + {} + union { - FnCommandCallback_t m_fnCommandCallback; - FnCommandCallbackVoid_t m_fnVoidCommandCallback; - FnCommandCallbackNoContext_t m_fnContextlessCommandCallback; - ICommandCallback* m_pCommandCallback; + FnCommandCallback_t fnCommandCallback; + FnCommandCallbackVoid_t fnVoidCommandCallback; + FnCommandCallbackNoContext_t fnContextlessCommandCallback; + ICommandCallback* pCommandCallback; }; - bool m_bUsingCommandCallbackInterface : 1; - bool m_bHasVoidCommandCallback : 1; - bool m_bHasContextlessCommandCallback : 1; + bool is_interface; + bool is_voidcallback; + bool is_contextless; }; - CallbackInfo_t m_Callback; + CallbackInfo_t callback; // NOTE: To maintain backward compat, we have to be very careful: // All public virtual methods must appear in the same order always @@ -514,150 +470,41 @@ friend class ConCommandHandle; union { - FnCommandCompletionCallback m_fnCompletionCallback; - ICommandCompletionCallback* m_pCommandCompletionCallback; + FnCommandCompletionCallback fnCompletionCallback; + ICommandCompletionCallback* pCommandCompletionCallback; }; - bool m_bHasCompletionCallback : 1; - bool m_bUsingCommandCompletionInterface : 1; - - ConCommandRefAbstract *m_pReference; -}; + bool has_complitioncallback; + bool is_interface; + ConVarHandle* refHandle; +}; +static_assert(sizeof(ConCommandCreation_t) == 0x40, "ConCommandCreation_t is of the wrong size!"); -//----------------------------------------------------------------------------- -// Purpose: A console variable -//----------------------------------------------------------------------------- -#if false -class ConVar +class ConCommandBase {}; // For metamod compatibility only!!!! +class ConCommand : public ConCommandBase { -friend class CCvar; -friend class SplitScreenConVarRef; - public: - ConVar( const char *pName, const char *pDefaultValue, int64 flags = 0); - - ConVar( const char *pName, const char *pDefaultValue, int64 flags, - const char *pHelpString ); - ConVar( const char *pName, const char *pDefaultValue, int64 flags, - const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax ); - ConVar( const char *pName, const char *pDefaultValue, int64 flags, - const char *pHelpString, FnChangeCallback_t callback ); - ConVar( const char *pName, const char *pDefaultValue, int64 flags, - const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax, - FnChangeCallback_t callback ); - - ~ConVar( void ); - - bool IsFlagSet( int64 flag ) const; - const char* GetHelpText( void ) const; - const char *GetName( void ) const; - // Return name of command (usually == GetName(), except in case of FCVAR_SS_ADDED vars - const char *GetBaseName( void ) const; - int GetSplitScreenPlayerSlot() const; - - void AddFlags( int64 flags ); - int64 GetFlags() const; - - // Install a change callback (there shouldn't already be one....) - void InstallChangeCallback( FnChangeCallback_t callback, bool bInvoke = true ); - void RemoveChangeCallback( FnChangeCallback_t callbackToRemove ); - - int GetChangeCallbackCount() const { return m_pParent->m_fnChangeCallbacks.Count(); } - FnChangeCallback_t GetChangeCallback( int slot ) const { return m_pParent->m_fnChangeCallbacks[ slot ]; } - - // Retrieve value - FORCEINLINE_CVAR float GetFloat( void ) const; - FORCEINLINE_CVAR int GetInt( void ) const; - FORCEINLINE_CVAR Color GetColor( void ) const; - FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); } - FORCEINLINE_CVAR char const *GetString( void ) const; - - // Compiler driven selection for template use - template T Get( void ) const; - template T Get( T * ) const; - - // Any function that allocates/frees memory needs to be virtual or else you'll have crashes - // from alloc/free across dll/exe boundaries. - - // These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue). - void SetValue( const char *value ); - void SetValue( float value ); - void SetValue( int value ); - void SetValue( Color value ); - - // Reset to default value - void Revert( void ); - - // True if it has a min/max setting - bool HasMin() const; - bool HasMax() const; - - bool GetMin( float& minVal ) const; - bool GetMax( float& maxVal ) const; - - float GetMinValue() const; - float GetMaxValue() const; - - const char *GetDefault( void ) const; - + ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallback_t callback, + const char *pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); + ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallbackVoid_t callback, + const char *pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); + ConCommand( ConCommandRefAbstract* pReferenceOut, const char* pName, FnCommandCallbackNoContext_t callback, + const char* pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); + ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, ICommandCallback *pCallback, + const char *pHelpString = 0, int64 flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 ); - FORCEINLINE_CVAR CVValue_t &GetRawValue() - { - return m_Value; - } - FORCEINLINE_CVAR const CVValue_t &GetRawValue() const + ~ConCommand() { - return m_Value; + this->Destroy(); } private: - bool InternalSetColorFromString( const char *value ); - // Called by CCvar when the value of a var is changing. - void InternalSetValue(const char *value); - // For CVARs marked FCVAR_NEVER_AS_STRING - void InternalSetFloatValue( float fNewValue ); - void InternalSetIntValue( int nValue ); - void InternalSetColorValue( Color value ); - - bool ClampValue( float& value ); - void ChangeStringValue( const char *tempVal, float flOldValue ); - - void Create( const char *pName, const char *pDefaultValue, int64 flags = 0, - const char *pHelpString = 0, bool bMin = false, float fMin = 0.0, - bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 ); - - // Used internally by OneTimeInit to initialize. - void Init(); + void Create( const char *pName, const char *pHelpString, int64_t flags, ConCommandCreation_t& setup ); + void Destroy( ); - - -protected: - const char* m_pszName; - CVValue_t* m_cvvDefaultValue; - CVValue_t* m_cvvMinValue; - CVValue_t* m_cvvMaxValue; - const char* m_pszHelpString; - EConVarType m_eVarType; - - // This gets copied from the ConVarDesc_t on creation - short unk1; - - unsigned int timesChanged; - int64 flags; - unsigned int callback_index; - - // Used when setting default, max, min values from the ConVarDesc_t - // although that's not the only place of usage - // flags seems to be: - // (1 << 0) Skip setting value to split screen slots and also something keyvalues related - // (1 << 1) Skip setting default value - // (1 << 2) Skip setting min/max values - int allocation_flag_of_some_sort; - - CVValue_t** values; + ConVarHandle m_Handle; }; -#endif #pragma pack(push,1) struct ConVarSetup_t @@ -695,23 +542,20 @@ struct ConVarSetup_t int16_t unk2; // 0x46 }; #pragma pack(pop) + static_assert(sizeof(ConVarSetup_t) == 0x48, "ConVarSetup_t is of the wrong size!"); static_assert(sizeof(ConVarSetup_t) % 8 == 0x0, "ConVarSetup_t isn't 8 bytes aligned!"); -#pragma pack(push,1) -struct ConVarCreation_t { - ConVarCreation_t() { memset(this, 0, sizeof(*this)); } - - const char* name; // 0x0 - const char* description; // 0x8 - int64_t flags; // 0x10 - +struct ConVarCreation_t : CVarCreationBase_t { + ConVarCreation_t() : + refHandle(nullptr), + refConVar(nullptr) + {} ConVarSetup_t setup; // 0x18 ConVarHandle* refHandle; // 0x60 IConVar** refConVar; // 0x68 }; -#pragma pack(pop) static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); static_assert(sizeof(ConVarCreation_t) % 8 == 0x0, "ConVarCreation_t isn't 8 bytes aligned!"); @@ -725,7 +569,7 @@ class ConVar public: // sub_6A66B0 template - ConVar(const char* name, int32 flags, const char* description, T value) + ConVar(const char* name, int32_t flags, const char* description, T value) { this->Init(INVALID_CONVAR_HANDLE, TranslateType()); @@ -734,18 +578,20 @@ class ConVar setup.default_value = value; setup.type = TranslateType(); - this->sub_10B7C70(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); + this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } + ~ConVar(); + private: template static constexpr EConVarType TranslateType(); - + // sub_10B7BC0 void Init(ConVarHandle defaultHandle, EConVarType type); // sub_10B7C70 - void sub_10B7C70(const char* name, int32 flags, const char* description, const ConVarSetup_t& obj); + void Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& obj); public: // High-speed method to read convar data ConVarHandle m_Handle; @@ -1151,7 +997,7 @@ void ConVar_Unregister( ); //----------------------------------------------------------------------------- // Utility methods //----------------------------------------------------------------------------- -void ConVar_PrintDescription( const ConCommandBase *pVar ); +void ConVar_PrintDescription( const CVarCreationBase_t* pVar ); //----------------------------------------------------------------------------- @@ -1180,7 +1026,7 @@ class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, pu ~CConCommandMemberAccessor() { - Shutdown(); + this->Destroy(); } void SetOwner( T* pOwner ) diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 6fdc097a3..9d79ee885 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -33,72 +33,117 @@ static int64 s_nCVarFlag = 0; static bool s_bRegistered = false; -class ConCommandRegList; -class ConCommandRegList +void RegisterCommand( ConCommandCreation_t& cmd ) { -public: - static void RegisterCommand(ConCommand* pCmd) + *cmd.refHandle = g_pCVar->RegisterConCommand( cmd, s_nCVarFlag ); + if ( !cmd.refHandle->IsValid() ) { - if (s_bConCommandsRegistered) - { - ConCommandHandle hndl = g_pCVar->RegisterConCommand(pCmd, s_nCVarFlag); - if (!hndl.IsValid()) - { - Plat_FatalErrorFunc("RegisterConCommand: Unknown error registering con command \"%s\"!\n", pCmd->GetName()); - DebuggerBreakIfDebugging(); - } + Plat_FatalErrorFunc( "RegisterConCommand: Unknown error registering con command \"%s\"!\n", cmd.name ); + DebuggerBreakIfDebugging( ); + } +} - pCmd->SetHandle(hndl); - } - else - { - GetCommandRegList()->AddToTail(pCmd); - } +void UnRegisterCommand( ConVarHandle& cmd ) +{ + if ( cmd.IsValid() ) + { + g_pCVar->UnregisterConCommand( cmd ); + + cmd.Invalidate(); } +} + +class ConCommandRegList; +static ConCommandRegList* s_pCommandRegList = nullptr; +class ConCommandRegList +{ +public: static void RegisterAll() { if (!s_bConCommandsRegistered && g_pCVar) { s_bConCommandsRegistered = true; - for(int i = 0; i < GetCommandRegList()->Count(); i++) + ConCommandRegList* list = s_pCommandRegList; + while ( list != nullptr ) { - ConCommand *pCmd = GetCommandRegList()->Element(i); - ConCommandHandle hndl = g_pCVar->RegisterConCommand(pCmd, s_nCVarFlag); - pCmd->SetHandle(hndl); - - if (!hndl.IsValid()) + FOR_EACH_VEC( list->m_Vec, i ) { - Plat_FatalErrorFunc("RegisterConCommand: Unknown error registering con command \"%s\"!\n", pCmd->GetName()); - DebuggerBreakIfDebugging(); + RegisterCommand( list->m_Vec[i] ); } + + ConCommandRegList *pNext = list->m_pNext; + delete list; + list = pNext; } } } private: + friend void AddCommand( ConCommandCreation_t& cmd ); + + void SetNextList( ConCommandRegList* list ) + { + m_pNext = list; + } - // GAMMACASE: Required to prevent static initialization order problem https://isocpp.org/wiki/faq/ctors#static-init-order - static CUtlVector *GetCommandRegList() + int Count() const + { + return m_Vec.Count(); + } + + void Add( const ConCommandCreation_t& cmd ) { - static CUtlVector s_ConCommandRegList; - return &s_ConCommandRegList; + m_Vec.AddToTail( cmd ); } + CUtlVectorFixed m_Vec; + ConCommandRegList* m_pNext = nullptr; +public: static bool s_bConCommandsRegistered; }; +bool ConCommandRegList::s_bConCommandsRegistered = false; + +void AddCommand( ConCommandCreation_t& cmd ) +{ + if (ConCommandRegList::s_bConCommandsRegistered && s_bRegistered) + { + RegisterCommand( cmd ); + return; + } + + if ( !s_pCommandRegList || s_pCommandRegList->Count() == 100 ) + { + ConCommandRegList* newList = new ConCommandRegList; + newList->SetNextList( s_pCommandRegList ); + + s_pCommandRegList = newList; + } + + s_pCommandRegList->Add( cmd ); +} -void RegisterConVar( ConVarCreation_t& setup ) +void RegisterConVar( ConVarCreation_t& cvar ) { - g_pCVar->RegisterConVar( setup, s_nCVarFlag, setup.refHandle, setup.refConVar ); - if (!setup.refHandle->IsValid()) + ConMsg( "Registering cvar %s\n", cvar.name ); + + g_pCVar->RegisterConVar( cvar, s_nCVarFlag, cvar.refHandle, cvar.refConVar ); + if (!cvar.refHandle->IsValid()) { - Plat_FatalErrorFunc( "RegisterConCommand: Unknown error registering convar \"%s\"!\n", setup.name ); + Plat_FatalErrorFunc( "RegisterConVar: Unknown error registering convar \"%s\"!\n", cvar.name ); DebuggerBreakIfDebugging(); } } -bool ConCommandRegList::s_bConCommandsRegistered = false; +void UnRegisterConVar( ConVarHandle& cvar ) +{ + if (cvar.IsValid()) + { + g_pCVar->UnregisterConVar( cvar ); + + cvar.Invalidate(); + } +} class ConVarRegList; static ConVarRegList* s_pConVarRegList = nullptr; @@ -108,11 +153,6 @@ class ConVarRegList public: ConVarRegList() {} - static bool AreConVarsRegistered() - { - return s_bConVarsRegistered; - } - static void RegisterAll() { if ( !s_bConVarsRegistered && g_pCVar ) @@ -120,9 +160,9 @@ class ConVarRegList s_bConVarsRegistered = true; ConVarRegList* list = s_pConVarRegList; - while ( list != nullptr ) + while ( list ) { - FOR_EACH_VEC( s_pConVarRegList->m_Vec, i ) + FOR_EACH_VEC( list->m_Vec, i ) { RegisterConVar( list->m_Vec[i] ); } @@ -131,32 +171,30 @@ class ConVarRegList delete list; list = pNext; } - - s_pConVarRegList = nullptr; } } - int Count() const - { - return m_Vec.Count(); - } - private: - friend void SetupConVar( ConVarCreation_t& setup ); + friend void SetupConVar( ConVarCreation_t& cvar ); void SetNextList( ConVarRegList* list ) { m_pNext = list; } - void Add( const ConVarCreation_t& setup ) + int Count() const + { + return m_Vec.Count(); + } + + void Add( const ConVarCreation_t& cvar ) { - m_Vec.AddToTail( setup ); + m_Vec.AddToTail( cvar ); } CUtlVectorFixed m_Vec; ConVarRegList* m_pNext = nullptr; - +public: static bool s_bConVarsRegistered; }; static_assert(sizeof(ConVarRegList) == 0x2BD0, "Size mismatch"); @@ -164,11 +202,11 @@ static_assert(sizeof(ConVarRegList) == 0x2BD0, "Size mismatch"); bool ConVarRegList::s_bConVarsRegistered = false; // sub_10B79F0 -void SetupConVar( ConVarCreation_t& setup ) +void SetupConVar( ConVarCreation_t& cvar ) { - if ( s_bRegistered ) + if ( ConVarRegList::s_bConVarsRegistered ) { - RegisterConVar(setup); + RegisterConVar(cvar); return; } @@ -180,7 +218,9 @@ void SetupConVar( ConVarCreation_t& setup ) s_pConVarRegList = newList; } - s_pConVarRegList->Add( setup ); + s_pConVarRegList->Add( cvar ); + + ConMsg( "Setting up cvar %s\n", cvar.name ); } //----------------------------------------------------------------------------- @@ -208,83 +248,6 @@ void ConVar_Unregister( ) s_bRegistered = false; } -//----------------------------------------------------------------------------- -// Purpose: Default constructor -//----------------------------------------------------------------------------- -ConCommandBase::ConCommandBase( void ) -{ - m_pszName = NULL; - m_pszHelpString = NULL; - - m_nFlags = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -ConCommandBase::~ConCommandBase( void ) -{ -} - -//----------------------------------------------------------------------------- -// Purpose: Return name of the command/var -// Output : const char -//----------------------------------------------------------------------------- -const char *ConCommandBase::GetName( void ) const -{ - return m_pszName; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : flag - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool ConCommandBase::IsFlagSet( int64 flag ) const -{ - return ( flag & m_nFlags ) ? true : false; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : flags - -//----------------------------------------------------------------------------- -void ConCommandBase::AddFlags( int64 flags ) -{ - m_nFlags |= flags; - -#ifdef ALLOW_DEVELOPMENT_CVARS - m_nFlags &= ~FCVAR_DEVELOPMENTONLY; -#endif -} - -void ConCommandBase::RemoveFlags( int64 flags ) -{ - m_nFlags &= ~flags; -} - -int64 ConCommandBase::GetFlags( void ) const -{ - return m_nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : const char -//----------------------------------------------------------------------------- -const char *ConCommandBase::GetHelpText( void ) const -{ - return m_pszHelpString; -} - -//----------------------------------------------------------------------------- -// -// Con Commands start here -// -//----------------------------------------------------------------------------- - - //----------------------------------------------------------------------------- // Global methods //----------------------------------------------------------------------------- @@ -474,98 +437,68 @@ int DefaultCompletionFunc( const char *partial, CUtlVector< CUtlString > &comman return 0; } - ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { - m_Callback.m_fnCommandCallback = callback; - m_Callback.m_bUsingCommandCallbackInterface = false; - m_Callback.m_bHasVoidCommandCallback = false; - m_Callback.m_bHasContextlessCommandCallback = false; - - m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - m_bHasCompletionCallback = completionFunc != 0 ? true : false; - m_bUsingCommandCompletionInterface = false; + ConCommandCreation_t creation; + creation.callback.fnCommandCallback = callback; + creation.callback.is_interface = false; + creation.callback.is_voidcallback = false; + creation.callback.is_contextless = false; - m_pReference = pReferenceOut; - m_pReference->handle.Reset(); + creation.fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; + creation.has_complitioncallback = completionFunc != 0 ? true : false; + creation.is_interface = false; // Setup the rest - Create( pName, pHelpString, flags ); + Create( pName, pHelpString, flags, creation ); } ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { - m_Callback.m_fnVoidCommandCallback = callback; - m_Callback.m_bUsingCommandCallbackInterface = false; - m_Callback.m_bHasVoidCommandCallback = true; - m_Callback.m_bHasContextlessCommandCallback = false; - - m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - m_bHasCompletionCallback = completionFunc != 0 ? true : false; - m_bUsingCommandCompletionInterface = false; + ConCommandCreation_t creation; + creation.callback.fnVoidCommandCallback = callback; + creation.callback.is_interface = false; + creation.callback.is_voidcallback = true; + creation.callback.is_contextless = false; - m_pReference = pReferenceOut; - m_pReference->handle.Reset(); + creation.fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; + creation.has_complitioncallback = completionFunc != nullptr ? true : false; + creation.is_interface = false; // Setup the rest - Create( pName, pHelpString, flags ); + Create( pName, pHelpString, flags, creation ); } ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallbackNoContext_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { - m_Callback.m_fnContextlessCommandCallback = callback; - m_Callback.m_bUsingCommandCallbackInterface = false; - m_Callback.m_bHasVoidCommandCallback = false; - m_Callback.m_bHasContextlessCommandCallback = true; + ConCommandCreation_t creation; + creation.callback.fnContextlessCommandCallback = callback; + creation.callback.is_interface = false; + creation.callback.is_voidcallback = false; + creation.callback.is_contextless = true; - m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - m_bHasCompletionCallback = completionFunc != 0 ? true : false; - m_bUsingCommandCompletionInterface = false; - - m_pReference = pReferenceOut; - m_pReference->handle.Reset(); + creation.fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; + creation.has_complitioncallback = completionFunc != nullptr ? true : false; + creation.is_interface = false; // Setup the rest - Create(pName, pHelpString, flags); + Create( pName, pHelpString, flags, creation ); } ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ ) { - m_Callback.m_pCommandCallback = pCallback; - m_Callback.m_bUsingCommandCallbackInterface = true; - m_Callback.m_bHasVoidCommandCallback = false; - m_Callback.m_bHasContextlessCommandCallback = false; - - m_pCommandCompletionCallback = pCompletionCallback; - m_bHasCompletionCallback = true; - m_bUsingCommandCompletionInterface = true; + ConCommandCreation_t creation; + creation.callback.pCommandCallback = pCallback; + creation.callback.is_interface = true; + creation.callback.is_voidcallback = false; + creation.callback.is_contextless = false; - m_pReference = pReferenceOut; - m_pReference->handle.Reset(); + creation.pCommandCompletionCallback = pCompletionCallback; + creation.has_complitioncallback = pCompletionCallback != nullptr ? true : false; + creation.is_interface = true; // Setup the rest - Create( pName, pHelpString, flags ); -} - -//----------------------------------------------------------------------------- -// Destructor -//----------------------------------------------------------------------------- -ConCommand::~ConCommand( void ) -{ - ConCommandRefAbstract *pRef = GetRef(); - if ( pRef ) - { - pRef->handle.Unregister(); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Used internally by OneTimeInit to initialize. -//----------------------------------------------------------------------------- -void ConCommand::Init() -{ - ConCommandRegList::RegisterCommand( this ); + Create( pName, pHelpString, flags, creation ); } //----------------------------------------------------------------------------- @@ -575,103 +508,28 @@ void ConCommand::Init() // *pHelpString - // flags - //----------------------------------------------------------------------------- -void ConCommand::Create( const char* pName, const char* pHelpString /*= 0*/, int64 flags /*= 0*/ ) +void ConCommand::Create( const char* pName, const char* pHelpString, int64_t flags, ConCommandCreation_t& setup ) { static const char* empty_string = ""; // Name should be static data Assert(pName); - m_pszName = pName; - m_pszHelpString = pHelpString ? pHelpString : empty_string; + setup.name = pName; + setup.description = pHelpString ? pHelpString : empty_string; - m_nFlags = flags; + setup.flags = flags; #ifdef ALLOW_DEVELOPMENT_CVARS - m_nFlags &= ~FCVAR_DEVELOPMENTONLY; + setup.flags &= ~FCVAR_DEVELOPMENTONLY; #endif + setup.refHandle = &this->m_Handle; - Init(); + AddCommand( setup ); } -void ConCommand::Shutdown() +void ConCommand::Destroy() { - GetRef()->handle.Unregister(); -} - - -//----------------------------------------------------------------------------- -// Purpose: Invoke the function if there is one -//----------------------------------------------------------------------------- -void ConCommandHandle::Dispatch( const CCommandContext &context, const CCommand &command ) -{ - ConCommand *pCommand = g_pCVar->GetCommand( *this ); - if ( pCommand->m_Callback.m_fnCommandCallback ) - { - if ( pCommand->m_Callback.m_bUsingCommandCallbackInterface ) - { - pCommand->m_Callback.m_pCommandCallback->CommandCallback( context, command ); - } - else if ( pCommand->m_Callback.m_bHasVoidCommandCallback ) - { - pCommand->m_Callback.m_fnVoidCommandCallback(); - } - else if ( pCommand->m_Callback.m_bHasContextlessCommandCallback ) - { - pCommand->m_Callback.m_fnContextlessCommandCallback( command ); - } - else - { - pCommand->m_Callback.m_fnCommandCallback( context, command ); - } - } - - // Command without callback!!! - AssertMsg(0, ("Encountered ConCommand without a callback!\n")); -} - -bool ConCommandHandle::HasCallback() const -{ - ConCommand *pCommand = g_pCVar->GetCommand( *this ); - return pCommand->m_Callback.m_fnCommandCallback != nullptr; -} - -void ConCommandHandle::Unregister() -{ - if (IsValid()) - { - if ( g_pCVar ) - g_pCVar->UnregisterConCommand( *this ); - - Reset(); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Calls the autocompletion method to get autocompletion suggestions -//----------------------------------------------------------------------------- -int ConCommand::AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands ) -{ - if (m_bUsingCommandCompletionInterface) - { - if ( !m_pCommandCompletionCallback ) - return 0; - return m_pCommandCompletionCallback->CommandCompletionCallback( partial, commands ); - } - - Assert( m_fnCompletionCallback ); - if ( !m_fnCompletionCallback ) - return 0; - - return m_fnCompletionCallback( partial, commands ); -} - - -//----------------------------------------------------------------------------- -// Returns true if the console command can autocomplete -//----------------------------------------------------------------------------- -bool ConCommand::CanAutoComplete( void ) -{ - return m_bHasCompletionCallback; + UnRegisterCommand(this->m_Handle); } //----------------------------------------------------------------------------- @@ -719,13 +577,18 @@ IConVar* ConVar_Invalid(EConVarType type) return &invalid_convar[type]; } +ConVar::~ConVar() +{ + UnRegisterConVar(this->m_Handle); +} + void ConVar::Init(ConVarHandle defaultHandle, EConVarType type) { this->m_Handle.Invalidate(); this->m_ConVar = nullptr; // qword_191A3D8 - if (g_pCVar && g_pCVar->GetConVar(defaultHandle) == nullptr) + if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle) == nullptr)) { this->m_ConVar = ConVar_Invalid(type); // technically this @@ -734,9 +597,7 @@ void ConVar::Init(ConVarHandle defaultHandle, EConVarType type) this->m_Handle = defaultHandle; } -//std::exit((int64_t)(&((ConVarSetup_t*)nullptr)->type)); - -void ConVar::sub_10B7C70(const char* name, int32 flags, const char* description, const ConVarSetup_t& setup) +void ConVar::Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& setup) { this->m_ConVar = ConVar_Invalid(setup.type); this->m_Handle.Invalidate(); From 401aa14f27382b2ee64903c17024c851d07c3024 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sat, 7 Oct 2023 22:53:36 +0200 Subject: [PATCH 07/36] undo automatic symbol change --- public/tier0/icommandline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/tier0/icommandline.h b/public/tier0/icommandline.h index 6b53c9932..9f30237cb 100644 --- a/public/tier0/icommandline.h +++ b/public/tier0/icommandline.h @@ -1,4 +1,4 @@ -//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // From a28f008ca7b00be2a32c9ad7784e9143c41efb81 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sat, 7 Oct 2023 22:59:47 +0200 Subject: [PATCH 08/36] Get rid of ConCommandRefAbstract --- public/tier1/convar.h | 51 ++++++++++++++----------------------------- tier1/convar.cpp | 10 ++++----- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index a75e51735..c8844ea74 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -50,7 +50,6 @@ class IConVar; class CCommand; class ConCommand; class ConVar; -class ConCommandRefAbstract; struct CVarCreationBase_t { @@ -266,7 +265,7 @@ union CVValue_t uint64_t m_u64Value; float m_flValue; double m_dbValue; - const char* m_szValue; + const char* m_szValue; Color m_clrValue; Vector2D m_vec2Value; Vector m_vec3Value; @@ -306,7 +305,7 @@ class ICVarListenerCallbacks { public: virtual void OnConVarCreated( ConVar* pNewCvar ) = 0; - virtual void OnConCommandCreated( ConCommandRefAbstract *pNewCommand ) = 0; + virtual void OnConCommandCreated( ConCommand* pNewCommand ) = 0; }; //----------------------------------------------------------------------------- @@ -337,12 +336,6 @@ class ICommandCompletionCallback virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0; }; -class ConCommandRefAbstract -{ -public: - ConVarHandle handle; -}; - //----------------------------------------------------------------------------- // Command tokenizer //----------------------------------------------------------------------------- @@ -485,13 +478,13 @@ class ConCommandBase {}; // For metamod compatibility only!!!! class ConCommand : public ConCommandBase { public: - ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallback_t callback, + ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallbackVoid_t callback, + ConCommand( const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( ConCommandRefAbstract* pReferenceOut, const char* pName, FnCommandCallbackNoContext_t callback, + ConCommand( const char* pName, FnCommandCallbackNoContext_t callback, const char* pHelpString = 0, int64 flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, ICommandCallback *pCallback, + ConCommand( const char *pName, ICommandCallback *pCallback, const char *pHelpString = 0, int64 flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 ); ~ConCommand() @@ -1017,7 +1010,7 @@ class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, pu public: CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0, int64 flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) : - BaseClass( &m_ConCommandRef, pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL ) + BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL ) { m_pOwner = pOwner; m_Func = callback; @@ -1050,7 +1043,6 @@ class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, pu T* m_pOwner; FnMemberCommandCallback_t m_Func; FnMemberCommandCompletionCallback_t m_CompletionFunc; - ConCommandRefAbstract m_ConCommandRef; }; #ifdef _MSC_VER @@ -1061,61 +1053,52 @@ class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, pu // Purpose: Utility macros to quicky generate a simple console command //----------------------------------------------------------------------------- #define CON_COMMAND( name, description ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommand &args ); \ - static ConCommand name##_command( &name##_ref, #name, name##_callback, description ); \ + static ConCommand name##_command( #name, name##_callback, description ); \ static void name##_callback( const CCommand &args ) #ifdef CLIENT_DLL #define CON_COMMAND_SHARED( name, description ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command_client( &name##_ref, #name "_client", name##_callback, description ); \ + static ConCommand name##_command_client( #name "_client", name##_callback, description ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) #else #define CON_COMMAND_SHARED( name, description ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command( &name##_ref, #name, name##_callback, description ); \ + static ConCommand name##_command( #name, name##_callback, description ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) #endif #define CON_COMMAND_F( name, description, flags ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command( &name##_ref, #name, name##_callback, description, flags ); \ + static ConCommand name##_command( #name, name##_callback, description, flags ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) #ifdef CLIENT_DLL #define CON_COMMAND_F_SHARED( name, description, flags ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command_client( &name##_ref, #name "_client", name##_callback, description, flags ); \ + static ConCommand name##_command_client( #name "_client", name##_callback, description, flags ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) #else #define CON_COMMAND_F_SHARED( name, description, flags ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command( &name##_ref, #name, name##_callback, description, flags ); \ + static ConCommand name##_command( #name, name##_callback, description, flags ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) #endif #define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command( &name##_ref, #name, name##_callback, description, flags, completion ); \ + static ConCommand name##_command( #name, name##_callback, description, flags, completion ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) #ifdef CLIENT_DLL #define CON_COMMAND_F_COMPLETION_SHARED( name, description, flags, completion ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ static ConCommand name##_command_client( name##_command, #name "_client", name##_callback, description, flags, completion ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) #else #define CON_COMMAND_F_COMPLETION_SHARED( name, description, flags, completion ) \ - static ConCommandRefAbstract name##_ref; \ static void name##_callback( const CCommandContext &context, const CCommand &args ); \ static ConCommand name##_command( name##_command, #name, name##_callback, description, flags, completion ); \ static void name##_callback( const CCommandContext &context, const CCommand &args ) @@ -1123,15 +1106,13 @@ class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, pu #define CON_COMMAND_EXTERN( name, _funcname, description ) \ - static ConCommandRefAbstract name##_ref; \ void _funcname( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command( &name##_ref, #name, _funcname, description ); \ + static ConCommand name##_command( #name, _funcname, description ); \ void _funcname( const CCommandContext &context, const CCommand &args ) #define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \ - static ConCommandRefAbstract name##_ref; \ void _funcname( const CCommandContext &context, const CCommand &args ); \ - static ConCommand name##_command( &name##_ref, #name, _funcname, description, flags ); \ + static ConCommand name##_command( #name, _funcname, description, flags ); \ void _funcname( const CCommandContext &context, const CCommand &args ) #define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \ diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 9d79ee885..672366b8d 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -437,7 +437,7 @@ int DefaultCompletionFunc( const char *partial, CUtlVector< CUtlString > &comman return 0; } -ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) +ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { ConCommandCreation_t creation; creation.callback.fnCommandCallback = callback; @@ -453,7 +453,7 @@ ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, Create( pName, pHelpString, flags, creation ); } -ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) +ConCommand::ConCommand( const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { ConCommandCreation_t creation; creation.callback.fnVoidCommandCallback = callback; @@ -469,7 +469,7 @@ ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, Create( pName, pHelpString, flags, creation ); } -ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, FnCommandCallbackNoContext_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) +ConCommand::ConCommand( const char *pName, FnCommandCallbackNoContext_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { ConCommandCreation_t creation; creation.callback.fnContextlessCommandCallback = callback; @@ -485,7 +485,7 @@ ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, Create( pName, pHelpString, flags, creation ); } -ConCommand::ConCommand( ConCommandRefAbstract *pReferenceOut, const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ ) +ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ ) { ConCommandCreation_t creation; creation.callback.pCommandCallback = pCallback; @@ -588,7 +588,7 @@ void ConVar::Init(ConVarHandle defaultHandle, EConVarType type) this->m_ConVar = nullptr; // qword_191A3D8 - if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle) == nullptr)) + if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle)) == nullptr) { this->m_ConVar = ConVar_Invalid(type); // technically this From 475b104d38909ba6437daae3f722234ceff1a98e Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sat, 7 Oct 2023 23:01:06 +0200 Subject: [PATCH 09/36] remove debug --- tier1/convar.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 672366b8d..73bd198e3 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -125,8 +125,6 @@ void AddCommand( ConCommandCreation_t& cmd ) void RegisterConVar( ConVarCreation_t& cvar ) { - ConMsg( "Registering cvar %s\n", cvar.name ); - g_pCVar->RegisterConVar( cvar, s_nCVarFlag, cvar.refHandle, cvar.refConVar ); if (!cvar.refHandle->IsValid()) { @@ -219,8 +217,6 @@ void SetupConVar( ConVarCreation_t& cvar ) } s_pConVarRegList->Add( cvar ); - - ConMsg( "Setting up cvar %s\n", cvar.name ); } //----------------------------------------------------------------------------- From 4639bd88db7321d600c87bc58288f10a781cd2cd Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 00:02:06 +0200 Subject: [PATCH 10/36] reorganise the headers, and add templated getter/setters --- public/icvar.h | 124 ++++++++++++++++++++++- public/tier1/convar.h | 225 ++++++++++++------------------------------ tier1/convar.cpp | 27 ++--- 3 files changed, 199 insertions(+), 177 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 62902501c..6fb1dad21 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -11,19 +11,135 @@ #endif #include "appframework/IAppSystem.h" -#include "tier1/convar.h" #include "tier1/utlvector.h" #include "tier0/memalloc.h" +#include class ConCommand; -class Color; +class CCommand; +class CCommandContext; +class ICVarListenerCallbacks; class IConVarListener; -class IConVar; -class CConVarDetail; +class ConVar; +struct ConVarCreation_t; +struct ConCommandCreation_t; struct ConVarSnapshot_t; union CVValue_t; class KeyValues; +struct CSplitScreenSlot +{ + CSplitScreenSlot( int index ) + { + m_Data = index; + } + + int Get() const + { + return m_Data; + } + + int m_Data; +}; + +//----------------------------------------------------------------------------- +// Called when a ConVar changes value +//----------------------------------------------------------------------------- +typedef void(*FnChangeCallbackGlobal_t)(ConVar* cvar, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); +using FnChangeCallback_t = void(*)(ConVar* cvar, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); +static_assert(sizeof(FnChangeCallback_t) == 0x8, "Wrong size for FnChangeCallback_t"); + +//----------------------------------------------------------------------------- +// Purpose: Replaces the ConVar* +//----------------------------------------------------------------------------- +class ConVarHandle +{ +public: + ConVarHandle( uint16_t convarIndex = -1, uint16_t unk = -1, uint32_t handle = -1) : + m_convarIndex(convarIndex), + m_unknown1(unk), + m_handleIndex(handle) + {} + + bool IsValid( ) const; + void Invalidate( ); + + uint16_t GetConVarIndex() const { return m_convarIndex; } + uint32_t GetIndex() const { return m_handleIndex; } + +private: + uint16_t m_convarIndex; + uint16_t m_unknown1; + uint32_t m_handleIndex; +}; +static_assert(sizeof(ConVarHandle) == 0x8, "ConVarHandle is of the wrong size!"); + +static const ConVarHandle INVALID_CONVAR_HANDLE = ConVarHandle(); + +inline bool ConVarHandle::IsValid() const +{ + return m_convarIndex != 0xFFFF; +} + +inline void ConVarHandle::Invalidate() +{ + m_convarIndex = 0xFFFF; + m_unknown1 = 0xFFFF; + m_handleIndex = 0x0; +} + +//----------------------------------------------------------------------------- +// Purpose: Internal structure of ConVar objects +//----------------------------------------------------------------------------- +enum EConVarType : short +{ + EConVarType_Invalid = -1, + EConVarType_Bool, + EConVarType_Int16, + EConVarType_UInt16, + EConVarType_Int32, + EConVarType_UInt32, + EConVarType_Int64, + EConVarType_UInt64, + EConVarType_Float32, + EConVarType_Float64, + EConVarType_String, + EConVarType_Color, + EConVarType_Vector2, + EConVarType_Vector3, + EConVarType_Vector4, + EConVarType_Qangle, + EConVarType_MAX +}; + +abstract_class IConVar +{ +friend class ConVar; +protected: + const char* m_pszName; + CVValue_t* m_cvvDefaultValue; + CVValue_t* m_cvvMinValue; + CVValue_t* m_cvvMaxValue; + const char* m_pszHelpString; + EConVarType m_eVarType; + + // This gets copied from the ConVarDesc_t on creation + short unk1; + + unsigned int timesChanged; + int64 m_flags; + unsigned int callback_index; + + // Used when setting default, max, min values from the ConVarDesc_t + // although that's not the only place of usage + // flags seems to be: + // (1 << 0) Skip setting value to split screen slots and also something keyvalues related + // (1 << 1) Skip setting default value + // (1 << 2) Skip setting min/max values + int allocation_flag_of_some_sort; + + CVValue_t* m_value[4]; +}; //----------------------------------------------------------------------------- // Purpose: DLL interface to ConVars/ConCommands diff --git a/public/tier1/convar.h b/public/tier1/convar.h index c8844ea74..7b25d33d4 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -21,6 +21,7 @@ #include "tier1/utlstring.h" #include "tier1/characterset.h" #include "Color.h" +#include "cvar.h" #include "mathlib/vector4d.h" #include "playerslot.h" @@ -93,42 +94,6 @@ inline int64_t CVarCreationBase_t::GetFlags( void ) const return this->flags; } -class ConVarHandle -{ -public: - ConVarHandle( uint16_t convarIndex = -1, uint16_t unk = -1, uint32_t handle = -1) : - m_convarIndex(convarIndex), - m_unknown1(unk), - m_handleIndex(handle) - {} - - bool IsValid( ) const; - void Invalidate( ); - - uint16_t GetConVarIndex() const { return m_convarIndex; } - uint32_t GetIndex() const { return m_handleIndex; } - -private: - uint16_t m_convarIndex; - uint16_t m_unknown1; - uint32_t m_handleIndex; -}; -static_assert(sizeof(ConVarHandle) == 0x8, "ConVarHandle is of the wrong size!"); - -static const ConVarHandle INVALID_CONVAR_HANDLE = ConVarHandle(); - -inline bool ConVarHandle::IsValid() const -{ - return m_convarIndex != 0xFFFF; -} - -inline void ConVarHandle::Invalidate() -{ - m_convarIndex = 0xFFFF; - m_unknown1 = 0xFFFF; - m_handleIndex = 0x0; -} - enum CommandTarget_t { CT_NO_TARGET = -1, @@ -159,21 +124,6 @@ class CCommandContext CPlayerSlot m_nPlayerSlot; }; -struct CSplitScreenSlot -{ - CSplitScreenSlot( int index ) - { - m_Data = index; - } - - int Get() const - { - return m_Data; - } - - int m_Data; -}; - //----------------------------------------------------------------------------- // ConVar flags //----------------------------------------------------------------------------- @@ -226,27 +176,6 @@ struct CSplitScreenSlot #define FCVAR_EXECUTE_PER_TICK (1<<29) -enum EConVarType : short -{ - EConVarType_Invalid = -1, - EConVarType_Bool, - EConVarType_Int16, - EConVarType_UInt16, - EConVarType_Int32, - EConVarType_UInt32, - EConVarType_Int64, - EConVarType_UInt64, - EConVarType_Float32, - EConVarType_Float64, - EConVarType_String, - EConVarType_Color, - EConVarType_Vector2, - EConVarType_Vector3, - EConVarType_Vector4, - EConVarType_Qangle, - EConVarType_MAX -}; - union CVValue_t { CVValue_t() { memset(this, 0, sizeof(*this)); } @@ -256,6 +185,22 @@ union CVValue_t template FORCEINLINE_CVAR CVValue_t& operator=(T other); + FORCEINLINE_CVAR operator bool() { return m_bValue; } + FORCEINLINE_CVAR operator int16_t() { return m_i16Value; } + FORCEINLINE_CVAR operator uint16_t() { return m_u16Value; } + FORCEINLINE_CVAR operator int32_t() { return m_i32Value; } + FORCEINLINE_CVAR operator uint32_t() { return m_u32Value; } + FORCEINLINE_CVAR operator int64_t() { return m_i64Value; } + FORCEINLINE_CVAR operator uint64_t() { return m_u64Value; } + FORCEINLINE_CVAR operator float() { return m_flValue; } + FORCEINLINE_CVAR operator double() { return m_dbValue; } + FORCEINLINE_CVAR operator const char*() { return m_szValue; } + FORCEINLINE_CVAR operator const Color&() { return m_clrValue; } + FORCEINLINE_CVAR operator const Vector2D&() { return m_vec2Value; } + FORCEINLINE_CVAR operator const Vector&() { return m_vec3Value; } + FORCEINLINE_CVAR operator const Vector4D&() { return m_vec4Value; } + FORCEINLINE_CVAR operator const QAngle&() { return m_angValue; } + bool m_bValue; int16_t m_i16Value; uint16_t m_u16Value; @@ -275,15 +220,15 @@ union CVValue_t static_assert(sizeof(float) == sizeof(int32_t), "Wrong float type size for ConVar!"); static_assert(sizeof(double) == sizeof(int64_t), "Wrong double type size for ConVar!"); -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( bool other ) { m_bValue = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( int16_t other ) { m_i16Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( uint16_t other ) { m_u16Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( int32_t other ) { m_i32Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( uint32_t other ) { m_u32Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( int64_t other ) { m_i64Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( uint64_t other ) { m_u64Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( float other ) { m_flValue = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( double other ) { m_dbValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const bool other ) { m_bValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const int16_t other ) { m_i16Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const uint16_t other ) { m_u16Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const int32_t other ) { m_i32Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const uint32_t other ) { m_u32Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const int64_t other ) { m_i64Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const uint64_t other ) { m_u64Value = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const float other ) { m_flValue = other; return *this; } +template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const double other ) { m_dbValue = other; return *this; } template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const char* other ) { m_szValue = other; return *this; } template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Color& other ) { m_clrValue = other; return *this; } template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector2D& other ) { m_vec2Value = other; return *this; } @@ -291,13 +236,6 @@ template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( cons template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector4D& other ) { m_vec4Value = other; return *this; } template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const QAngle& other ) { m_angValue = other; return *this; } -//----------------------------------------------------------------------------- -// Called when a ConVar changes value -//----------------------------------------------------------------------------- -typedef void(*FnChangeCallbackGlobal_t)(ConVar* cvar, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); -using FnChangeCallback_t = void(*)(ConVar* cvar, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); -static_assert(sizeof(FnChangeCallback_t) == 0x8, "Wrong size for FnChangeCallback_t"); - //----------------------------------------------------------------------------- // ConVar & ConCommand creation listener callbacks //----------------------------------------------------------------------------- @@ -562,13 +500,35 @@ class ConVar public: // sub_6A66B0 template - ConVar(const char* name, int32_t flags, const char* description, T value) + ConVar(const char* name, int32_t flags, const char* description, T value, FnChangeCallback_t cb = nullptr) + { + this->Init(INVALID_CONVAR_HANDLE, TranslateType()); + + ConVarSetup_t setup; + setup.has_default = true; + setup.default_value = value; + setup.type = TranslateType(); + setup.callback = cb; + + this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); + } + + template + ConVar(const char* name, int32_t flags, const char* description, T value, bool min, T minValue, bool max, T maxValue, FnChangeCallback_t cb = nullptr) { this->Init(INVALID_CONVAR_HANDLE, TranslateType()); ConVarSetup_t setup; setup.has_default = true; setup.default_value = value; + + setup.has_min = min; + setup.min_value = minValue; + + setup.has_max = max; + setup.max_value = maxValue; + + setup.callback = cb; setup.type = TranslateType(); this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); @@ -576,6 +536,19 @@ class ConVar ~ConVar(); + template + void Set(const T value) + { + *m_ConVar->m_cvvDefaultValue = value; + } + + template + T Get() + { + CVValue_t& val = *m_ConVar->m_cvvDefaultValue; + return val; + } + private: template static constexpr EConVarType TranslateType(); @@ -607,82 +580,12 @@ template<> constexpr EConVarType ConVar::TranslateType( void ) { return template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Vector4; } template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Qangle; } +//----------------------------------------------------------------------------- + // sub_10B7760 IConVar* ConVar_Invalid(EConVarType type); -class IConVar -{ -friend class ConVarRegList; -friend class ConVar; -public: - IConVar(EConVarType type); -protected: - const char* m_pszName; - CVValue_t* m_cvvDefaultValue; - CVValue_t* m_cvvMinValue; - CVValue_t* m_cvvMaxValue; - const char* m_pszHelpString; - EConVarType m_eVarType; - - // This gets copied from the ConVarDesc_t on creation - short unk1; - - unsigned int timesChanged; - int64 m_flags; - unsigned int callback_index; - - // Used when setting default, max, min values from the ConVarDesc_t - // although that's not the only place of usage - // flags seems to be: - // (1 << 0) Skip setting value to split screen slots and also something keyvalues related - // (1 << 1) Skip setting default value - // (1 << 2) Skip setting min/max values - int allocation_flag_of_some_sort; - - CVValue_t* m_value[4]; -}; - #ifdef CONVAR_WORK_FINISHED -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a float -// Output : float -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR float ConVar::GetFloat( void ) const -{ - return m_pParent->m_Value.m_fValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as an int -// Output : int -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR int ConVar::GetInt( void ) const -{ - return m_pParent->m_Value.m_nValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a color -// Output : Color -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR Color ConVar::GetColor( void ) const -{ - unsigned char *pColorElement = ((unsigned char *)&m_pParent->m_Value.m_nValue); - return Color( pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3] ); -} - - -//----------------------------------------------------------------------------- - -template <> FORCEINLINE_CVAR float ConVar::Get( void ) const { return GetFloat(); } -template <> FORCEINLINE_CVAR int ConVar::Get( void ) const { return GetInt(); } -template <> FORCEINLINE_CVAR bool ConVar::Get( void ) const { return GetBool(); } -template <> FORCEINLINE_CVAR const char * ConVar::Get( void ) const { return GetString(); } -template <> FORCEINLINE_CVAR float ConVar::Get( float *p ) const { return ( *p = GetFloat() ); } -template <> FORCEINLINE_CVAR int ConVar::Get( int *p ) const { return ( *p = GetInt() ); } -template <> FORCEINLINE_CVAR bool ConVar::Get( bool *p ) const { return ( *p = GetBool() ); } -template <> FORCEINLINE_CVAR const char * ConVar::Get( char const **p ) const { return ( *p = GetString() ); } - //----------------------------------------------------------------------------- // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. // Output : const char * diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 73bd198e3..66ecaf14d 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -534,7 +534,21 @@ void ConCommand::Destroy() // //----------------------------------------------------------------------------- -IConVar invalid_convar[EConVarType_MAX + 1] = { +class CInvalidConvar : public IConVar +{ +public: + CInvalidConvar(EConVarType type) + { + m_pszName = ""; + m_cvvDefaultValue = nullptr; + m_cvvMinValue = nullptr; + m_cvvMaxValue = nullptr; + m_pszHelpString = "This convar is being accessed prior to ConVar_Register being called"; + m_eVarType = type; + } +}; + +CInvalidConvar invalid_convar[EConVarType_MAX + 1] = { EConVarType_Bool, EConVarType_Int16, EConVarType_UInt16, @@ -553,17 +567,6 @@ IConVar invalid_convar[EConVarType_MAX + 1] = { EConVarType_Invalid // EConVarType_MAX }; -// Strictly for invalid convar creation -IConVar::IConVar(EConVarType type) : - m_pszName(""), - m_cvvDefaultValue(nullptr), - m_cvvMinValue(nullptr), - m_cvvMaxValue(nullptr), - m_pszHelpString("This convar is being accessed prior to ConVar_Register being called"), - m_eVarType(type) -{ -} - IConVar* ConVar_Invalid(EConVarType type) { if (type == EConVarType_Invalid) From 39d0934b21f29b935e20e3ea69d7621b407adf9f Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 00:38:26 +0200 Subject: [PATCH 11/36] finish templating job --- public/icvar.h | 90 ++++++++- public/tier1/convar.h | 201 +++----------------- tier1/convar.cpp | 426 ------------------------------------------ 3 files changed, 112 insertions(+), 605 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 6fb1dad21..bf2b43d24 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -13,6 +13,7 @@ #include "appframework/IAppSystem.h" #include "tier1/utlvector.h" #include "tier0/memalloc.h" +#include "mathlib/vector4d.h" #include class ConCommand; @@ -24,9 +25,68 @@ class ConVar; struct ConVarCreation_t; struct ConCommandCreation_t; struct ConVarSnapshot_t; -union CVValue_t; class KeyValues; +union CVValue_t +{ + CVValue_t() { memset(this, 0, sizeof(*this)); } + CVValue_t(CVValue_t const& cp) { memcpy(this, &cp, sizeof(*this)); }; + CVValue_t& operator=(CVValue_t other) { memcpy(this, &other, sizeof(*this)); return *this; } + + template + inline CVValue_t& operator=(T other); + + inline operator bool() const { return m_bValue; } + inline operator int16_t() const { return m_i16Value; } + inline operator uint16_t() const { return m_u16Value; } + inline operator int32_t() const { return m_i32Value; } + inline operator uint32_t() const { return m_u32Value; } + inline operator int64_t() const { return m_i64Value; } + inline operator uint64_t() const { return m_u64Value; } + inline operator float() const { return m_flValue; } + inline operator double() const { return m_dbValue; } + inline operator const char*() const { return m_szValue; } + inline operator const Color&() const { return m_clrValue; } + inline operator const Vector2D&() const { return m_vec2Value; } + inline operator const Vector&() const { return m_vec3Value; } + inline operator const Vector4D&() const { return m_vec4Value; } + inline operator const QAngle&() const { return m_angValue; } + + bool m_bValue; + int16_t m_i16Value; + uint16_t m_u16Value; + int32_t m_i32Value; + uint32_t m_u32Value; + int64_t m_i64Value; + uint64_t m_u64Value; + float m_flValue; + double m_dbValue; + const char* m_szValue; + Color m_clrValue; + Vector2D m_vec2Value; + Vector m_vec3Value; + Vector4D m_vec4Value; + QAngle m_angValue; +}; +static_assert(sizeof(float) == sizeof(int32_t), "Wrong float type size for ConVar!"); +static_assert(sizeof(double) == sizeof(int64_t), "Wrong double type size for ConVar!"); + +template<> inline CVValue_t& CVValue_t::operator=( const bool other ) { m_bValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const int16_t other ) { m_i16Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const uint16_t other ) { m_u16Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const int32_t other ) { m_i32Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const uint32_t other ) { m_u32Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const int64_t other ) { m_i64Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const uint64_t other ) { m_u64Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const float other ) { m_flValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const double other ) { m_dbValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const char* other ) { m_szValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Color& other ) { m_clrValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Vector2D& other ) { m_vec2Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Vector& other ) { m_vec3Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Vector4D& other ) { m_vec4Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const QAngle& other ) { m_angValue = other; return *this; } + struct CSplitScreenSlot { CSplitScreenSlot( int index ) @@ -115,6 +175,32 @@ enum EConVarType : short abstract_class IConVar { friend class ConVar; + inline const char* GetName( ) const { return m_pszName; } + inline const char* GetDescription( ) const { return m_pszHelpString; } + inline EConVarType GetType( ) const { return m_eVarType; } + + inline CVValue_t* GetDefaultValue( ) const { return m_cvvDefaultValue; } + inline CVValue_t* GetMinValue( ) const { return m_cvvMinValue; } + inline CVValue_t* GetMaxValue( ) const { return m_cvvMaxValue; } + + template + inline void SetDefaultValue(const T& value) { m_cvvDefaultValue = value; } + template + inline void SetMinValue(const T& value) { m_cvvMinValue = value; } + template + inline void SetMaxValue(const T& value) { m_cvvMaxValue = value; } + + template + inline const T GetValue( int index = 0 ) const { return m_value[index]; } + inline const CVValue_t& GetValue( int index = 0 ) const { return m_value[index]; } + template + inline void SetValue(const T& value, int index = 0) { m_value[index] = value; } + + inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_flags ) ? true : false; } + inline void AddFlags( int64_t flags ) { m_flags |= flags; } + inline void RemoveFlags( int64_t flags ) { m_flags &= ~flags; } + inline int64_t GetFlags( void ) const { return m_flags; } + protected: const char* m_pszName; CVValue_t* m_cvvDefaultValue; @@ -138,7 +224,7 @@ friend class ConVar; // (1 << 2) Skip setting min/max values int allocation_flag_of_some_sort; - CVValue_t* m_value[4]; + CVValue_t m_value[4]; }; //----------------------------------------------------------------------------- diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 7b25d33d4..cae56db03 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -22,7 +22,6 @@ #include "tier1/characterset.h" #include "Color.h" #include "cvar.h" -#include "mathlib/vector4d.h" #include "playerslot.h" #include @@ -176,66 +175,6 @@ class CCommandContext #define FCVAR_EXECUTE_PER_TICK (1<<29) -union CVValue_t -{ - CVValue_t() { memset(this, 0, sizeof(*this)); } - CVValue_t(CVValue_t const& cp) { memcpy(this, &cp, sizeof(*this)); }; - CVValue_t& operator=(CVValue_t other) { memcpy(this, &other, sizeof(*this)); return *this; } - - template - FORCEINLINE_CVAR CVValue_t& operator=(T other); - - FORCEINLINE_CVAR operator bool() { return m_bValue; } - FORCEINLINE_CVAR operator int16_t() { return m_i16Value; } - FORCEINLINE_CVAR operator uint16_t() { return m_u16Value; } - FORCEINLINE_CVAR operator int32_t() { return m_i32Value; } - FORCEINLINE_CVAR operator uint32_t() { return m_u32Value; } - FORCEINLINE_CVAR operator int64_t() { return m_i64Value; } - FORCEINLINE_CVAR operator uint64_t() { return m_u64Value; } - FORCEINLINE_CVAR operator float() { return m_flValue; } - FORCEINLINE_CVAR operator double() { return m_dbValue; } - FORCEINLINE_CVAR operator const char*() { return m_szValue; } - FORCEINLINE_CVAR operator const Color&() { return m_clrValue; } - FORCEINLINE_CVAR operator const Vector2D&() { return m_vec2Value; } - FORCEINLINE_CVAR operator const Vector&() { return m_vec3Value; } - FORCEINLINE_CVAR operator const Vector4D&() { return m_vec4Value; } - FORCEINLINE_CVAR operator const QAngle&() { return m_angValue; } - - bool m_bValue; - int16_t m_i16Value; - uint16_t m_u16Value; - int32_t m_i32Value; - uint32_t m_u32Value; - int64_t m_i64Value; - uint64_t m_u64Value; - float m_flValue; - double m_dbValue; - const char* m_szValue; - Color m_clrValue; - Vector2D m_vec2Value; - Vector m_vec3Value; - Vector4D m_vec4Value; - QAngle m_angValue; -}; -static_assert(sizeof(float) == sizeof(int32_t), "Wrong float type size for ConVar!"); -static_assert(sizeof(double) == sizeof(int64_t), "Wrong double type size for ConVar!"); - -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const bool other ) { m_bValue = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const int16_t other ) { m_i16Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const uint16_t other ) { m_u16Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const int32_t other ) { m_i32Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const uint32_t other ) { m_u32Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const int64_t other ) { m_i64Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const uint64_t other ) { m_u64Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const float other ) { m_flValue = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const double other ) { m_dbValue = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const char* other ) { m_szValue = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Color& other ) { m_clrValue = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector2D& other ) { m_vec2Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector& other ) { m_vec3Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const Vector4D& other ) { m_vec4Value = other; return *this; } -template<> FORCEINLINE_CVAR CVValue_t& CVValue_t::operator=( const QAngle& other ) { m_angValue = other; return *this; } - //----------------------------------------------------------------------------- // ConVar & ConCommand creation listener callbacks //----------------------------------------------------------------------------- @@ -536,18 +475,31 @@ class ConVar ~ConVar(); - template - void Set(const T value) - { - *m_ConVar->m_cvvDefaultValue = value; - } + inline const char* GetName( ) const { return m_ConVar->GetName( ); } + inline const char* GetDescription( ) const { return m_ConVar->GetDescription( ); } + inline EConVarType GetType( ) const { return m_ConVar->GetType( ); } + + inline CVValue_t* GetDefaultValue( ) const { return m_ConVar->GetDefaultValue( ); } + inline CVValue_t* GetMinValue( ) const { return m_ConVar->GetMinValue( ); } + inline CVValue_t* GetMaxValue( ) const { return m_ConVar->GetMaxValue( ); } template - T Get() - { - CVValue_t& val = *m_ConVar->m_cvvDefaultValue; - return val; - } + inline void SetDefaultValue(const T& value) { m_ConVar->SetDefaultValue( value ); } + template + inline void SetMinValue(const T& value) { m_ConVar->SetMinValue( value ); } + template + inline void SetMaxValue(const T& value) { m_ConVar->SetMaxValue( value ); } + + template + inline const T GetValue( int index = 0 ) const { return m_ConVar->GetValue( index ); } + inline const CVValue_t& GetValue( int index = 0 ) const { return m_ConVar->GetValue( index ); } + template + inline void SetValue(const T& value, int index = 0) { m_ConVar->SetValue( value, index ); } + + inline bool IsFlagSet( int64_t flag ) const { return m_ConVar->IsFlagSet( flag ); } + inline void AddFlags( int64_t flags ) { m_ConVar->AddFlags( flags ); } + inline void RemoveFlags( int64_t flags ) { return m_ConVar->RemoveFlags( flags ); } + inline int64_t GetFlags( void ) const { return m_ConVar->GetFlags( ); } private: template @@ -558,7 +510,7 @@ class ConVar // sub_10B7C70 void Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& obj); -public: + // High-speed method to read convar data ConVarHandle m_Handle; IConVar* m_ConVar; @@ -586,19 +538,6 @@ template<> constexpr EConVarType ConVar::TranslateType( void ) { return IConVar* ConVar_Invalid(EConVarType type); #ifdef CONVAR_WORK_FINISHED -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. -// Output : const char * -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR const char *ConVar::GetString( void ) const -{ - if ( m_nFlags & FCVAR_NEVER_AS_STRING ) - return "FCVAR_NEVER_AS_STRING"; - - char const *str = m_pParent->m_Value.m_pszString; - return str ? str : ""; -} - class CSplitScreenAddedConVar : public ConVar { typedef ConVar BaseClass; @@ -663,98 +602,6 @@ FORCEINLINE_CVAR int CSplitScreenAddedConVar::GetSplitScreenPlayerSlot() const return m_nSplitScreenSlot; } -//----------------------------------------------------------------------------- -// Did we find an existing convar of that name? -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR bool ConVarRefAbstract::IsFlagSet( int64 nFlags ) const -{ - return ( m_pConVar->IsFlagSet( nFlags ) != 0 ); -} - -FORCEINLINE_CVAR IConVar *ConVarRefAbstract::GetLinkedConVar() -{ - return m_pConVar; -} - -FORCEINLINE_CVAR const char *ConVarRefAbstract::GetName() const -{ - return m_pConVar->GetName(); -} - -FORCEINLINE_CVAR const char *ConVarRefAbstract::GetBaseName() const -{ - return m_pConVar->GetBaseName(); -} - -FORCEINLINE_CVAR int ConVarRefAbstract::GetSplitScreenPlayerSlot() const -{ - return m_pConVar->GetSplitScreenPlayerSlot(); -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a float -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR float ConVarRefAbstract::GetFloat( void ) const -{ - return m_pConVarState->m_Value.m_fValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as an int -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR int ConVarRefAbstract::GetInt( void ) const -{ - return m_pConVarState->m_Value.m_nValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a color -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR Color ConVarRefAbstract::GetColor( void ) const -{ - return m_pConVarState->GetColor(); -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR const char *ConVarRefAbstract::GetString( void ) const -{ - Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) ); - return m_pConVarState->m_Value.m_pszString; -} - - -FORCEINLINE_CVAR void ConVarRefAbstract::SetValue( const char *pValue ) -{ - m_pConVar->SetValue( pValue ); -} - -FORCEINLINE_CVAR void ConVarRefAbstract::SetValue( float flValue ) -{ - m_pConVar->SetValue( flValue ); -} - -FORCEINLINE_CVAR void ConVarRefAbstract::SetValue( int nValue ) -{ - m_pConVar->SetValue( nValue ); -} - -FORCEINLINE_CVAR void ConVarRefAbstract::SetValue( Color value ) -{ - m_pConVar->SetValue( value ); -} - -FORCEINLINE_CVAR void ConVarRefAbstract::SetValue( bool bValue ) -{ - m_pConVar->SetValue( bValue ? 1 : 0 ); -} - -FORCEINLINE_CVAR const char *ConVarRefAbstract::GetDefault() const -{ - return m_pConVarState->m_pszDefaultValue; -} - #if 0 //----------------------------------------------------------------------------- // Helper for referencing splitscreen convars (i.e., "name" and "name2") diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 66ecaf14d..a1d2d0f3d 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -630,432 +630,6 @@ void ConVar::Register(const char* name, int32_t flags, const char* description, #ifdef CONVAR_WORK_FINISHED -//----------------------------------------------------------------------------- -// Various constructors -//----------------------------------------------------------------------------- -ConVar::ConVar( const char *pName, const char *pDefaultValue, int64 flags /* = 0 */ ) -{ - Create( pName, pDefaultValue, flags ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int64 flags, const char *pHelpString ) -{ - Create( pName, pDefaultValue, flags, pHelpString ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int64 flags, const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) -{ - Create( pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax, fMax ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int64 flags, const char *pHelpString, FnChangeCallback_t callback ) -{ - Create( pName, pDefaultValue, flags, pHelpString, false, 0.0, false, 0.0, callback ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int64 flags, const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t callback ) -{ - Create( pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax, fMax, callback ); -} - - -//----------------------------------------------------------------------------- -// Destructor -//----------------------------------------------------------------------------- -ConVar::~ConVar( void ) -{ - if ( m_Value.m_pszString ) - { - delete[] m_Value.m_pszString; - m_Value.m_pszString = NULL; - } -} - - -//----------------------------------------------------------------------------- -// Install a change callback (there shouldn't already be one....) -//----------------------------------------------------------------------------- -void ConVar::InstallChangeCallback( FnChangeCallback_t callback, bool bInvoke ) -{ - if (callback) - { - if (m_fnChangeCallbacks.Find(callback) != -1) - { - m_fnChangeCallbacks.AddToTail(callback); - if (bInvoke) - callback(this, m_Value.m_pszString, m_Value.m_fValue); - } - else - { - Warning("InstallChangeCallback ignoring duplicate change callback!!!\n"); - } - } - else - { - Warning("InstallChangeCallback called with NULL callback, ignoring!!!\n"); - } -} - -bool ConVar::IsFlagSet( int64 flag ) const -{ - return ( flag & m_pParent->m_nFlags ) ? true : false; -} - -const char *ConVar::GetHelpText( void ) const -{ - return m_pParent->m_pszHelpString; -} - -void ConVar::AddFlags( int64 flags ) -{ - m_pParent->m_nFlags |= flags; - -#ifdef ALLOW_DEVELOPMENT_CVARS - m_pParent->m_nFlags &= ~FCVAR_DEVELOPMENTONLY; -#endif -} - -int64 ConVar::GetFlags( void ) const -{ - return m_pParent->m_nFlags; -} - -const char *ConVar::GetName( void ) const -{ - return m_pParent->m_pszName; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -//----------------------------------------------------------------------------- -void ConVar::Init() -{ - BaseClass::Init(); -} - -const char *ConVar::GetBaseName( void ) const -{ - return m_pParent->m_pszName; -} - -int ConVar::GetSplitScreenPlayerSlot( void ) const -{ - return 0; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::InternalSetValue( const char *value ) -{ - float fNewValue; - char tempVal[ 32 ]; - char *val; - - Assert(m_pParent == this); // Only valid for root convars. - - float flOldValue = m_Value.m_fValue; - - val = (char *)value; - fNewValue = ( float )atof( value ); - - if ( ClampValue( fNewValue ) ) - { - Q_snprintf( tempVal,sizeof(tempVal), "%f", fNewValue ); - val = tempVal; - } - - // Redetermine value - m_Value.m_fValue = fNewValue; - m_Value.m_nValue = ( int )( fNewValue ); - - if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ) - { - ChangeStringValue( val, flOldValue ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *tempVal - -//----------------------------------------------------------------------------- -void ConVar::ChangeStringValue( const char *tempVal, float flOldValue ) -{ - Assert( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ); - - char* pszOldValue = (char*)stackalloc( m_Value.m_StringLength ); - memcpy( pszOldValue, m_Value.m_pszString, m_Value.m_StringLength ); - - int len = Q_strlen(tempVal) + 1; - - if ( len > m_Value.m_StringLength) - { - if (m_Value.m_pszString) - { - delete[] m_Value.m_pszString; - } - - m_Value.m_pszString = new char[len]; - m_Value.m_StringLength = len; - } - - memcpy( m_Value.m_pszString, tempVal, len ); - - // Invoke any necessary callback function - for (int i = 0; i < m_fnChangeCallbacks.Count(); i++) - { - m_fnChangeCallbacks[i]( this, pszOldValue, flOldValue ); - } - - if (g_pCVar) - g_pCVar->CallGlobalChangeCallbacks( this, pszOldValue, flOldValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Check whether to clamp and then perform clamp -// Input : value - -// Output : Returns true if value changed -//----------------------------------------------------------------------------- -bool ConVar::ClampValue( float& value ) -{ - if ( m_bHasMin && ( value < m_fMinVal ) ) - { - value = m_fMinVal; - return true; - } - - if ( m_bHasMax && ( value > m_fMaxVal ) ) - { - value = m_fMaxVal; - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::InternalSetFloatValue( float fNewValue ) -{ - if ( fNewValue == m_Value.m_fValue ) - return; - - Assert( m_pParent == this ); // Only valid for root convars. - - // Check bounds - ClampValue( fNewValue ); - - // Redetermine value - float flOldValue = m_Value.m_fValue; - m_Value.m_fValue = fNewValue; - m_Value.m_nValue = ( int )fNewValue; - - if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ) - { - char tempVal[ 32 ]; - Q_snprintf( tempVal, sizeof( tempVal), "%f", m_Value.m_fValue ); - ChangeStringValue( tempVal, flOldValue ); - } - else - { - Assert( m_fnChangeCallbacks.Count() == 0 ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::InternalSetIntValue( int nValue ) -{ - if ( nValue == m_Value.m_nValue ) - return; - - Assert( m_pParent == this ); // Only valid for root convars. - - float fValue = (float)nValue; - if ( ClampValue( fValue ) ) - { - nValue = ( int )( fValue ); - } - - // Redetermine value - float flOldValue = m_Value.m_fValue; - m_Value.m_fValue = fValue; - m_Value.m_nValue = nValue; - - if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ) - { - char tempVal[ 32 ]; - Q_snprintf( tempVal, sizeof( tempVal ), "%d", m_Value.m_nValue ); - ChangeStringValue( tempVal, flOldValue ); - } - else - { - Assert( m_fnChangeCallbacks.Count() == 0 ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::InternalSetColorValue( Color cValue ) -{ - int color = cValue.GetRawColor(); - InternalSetIntValue( color ); -} - -//----------------------------------------------------------------------------- -// Purpose: Private creation -//----------------------------------------------------------------------------- -void ConVar::Create( const char *pName, const char *pDefaultValue, int64 flags /*= 0*/, - const char *pHelpString /*= NULL*/, bool bMin /*= false*/, float fMin /*= 0.0*/, - bool bMax /*= false*/, float fMax /*= false*/, FnChangeCallback_t callback /*= NULL*/ ) -{ - static const char *empty_string = ""; - - m_pParent = this; - - // Name should be static data - m_pszDefaultValue = pDefaultValue ? pDefaultValue : empty_string; - Assert( m_pszDefaultValue ); - - m_Value.m_StringLength = strlen( m_pszDefaultValue ) + 1; - m_Value.m_pszString = new char[m_Value.m_StringLength]; - memcpy( m_Value.m_pszString, m_pszDefaultValue, m_Value.m_StringLength ); - - m_bHasMin = bMin; - m_fMinVal = fMin; - m_bHasMax = bMax; - m_fMaxVal = fMax; - - if (callback) - m_fnChangeCallbacks.AddToTail(callback); - - m_Value.m_fValue = ( float )atof( m_Value.m_pszString ); - - // Bounds Check, should never happen, if it does, no big deal - if ( m_bHasMin && ( m_Value.m_fValue < m_fMinVal ) ) - { - Assert( 0 ); - } - - if ( m_bHasMax && ( m_Value.m_fValue > m_fMaxVal ) ) - { - Assert( 0 ); - } - - m_Value.m_nValue = ( int )m_Value.m_fValue; - - BaseClass::Create( pName, pHelpString, flags ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::SetValue(const char *value) -{ - ConVar *var = ( ConVar * )m_pParent; - var->InternalSetValue( value ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : value - -//----------------------------------------------------------------------------- -void ConVar::SetValue( float value ) -{ - ConVar *var = ( ConVar * )m_pParent; - var->InternalSetFloatValue( value ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : value - -//----------------------------------------------------------------------------- -void ConVar::SetValue( int value ) -{ - ConVar *var = ( ConVar * )m_pParent; - var->InternalSetIntValue( value ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : value - -//----------------------------------------------------------------------------- -void ConVar::SetValue( Color value ) -{ - ConVar *var = ( ConVar * )m_pParent; - var->InternalSetColorValue( value ); -} - -//----------------------------------------------------------------------------- -// Purpose: Reset to default value -//----------------------------------------------------------------------------- -void ConVar::Revert( void ) -{ - // Force default value again - ConVar *var = ( ConVar * )m_pParent; - var->SetValue( var->m_pszDefaultValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : minVal - -// Output : true if there is a min set -//----------------------------------------------------------------------------- -bool ConVar::GetMin( float& minVal ) const -{ - minVal = m_pParent->m_fMinVal; - return m_pParent->m_bHasMin; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : maxVal - -//----------------------------------------------------------------------------- -bool ConVar::GetMax( float& maxVal ) const -{ - maxVal = m_pParent->m_fMaxVal; - return m_pParent->m_bHasMax; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : const char -//----------------------------------------------------------------------------- -const char *ConVar::GetDefault( void ) const -{ - return m_pParent->m_pszDefaultValue; -} - - -//----------------------------------------------------------------------------- -// This version is simply used to make reading convars simpler. -// Writing convars isn't allowed in this mode -//----------------------------------------------------------------------------- -class CEmptyConVar : public ConVar -{ -public: - CEmptyConVar() : ConVar( "", "0" ) {} - // Used for optimal read access - virtual void SetValue( const char *pValue ) {} - virtual void SetValue( float flValue ) {} - virtual void SetValue( int nValue ) {} - virtual void SetValue( Color cValue ) {} - virtual const char *GetName( void ) const { return ""; } - virtual bool IsFlagSet( int nFlags ) const { return false; } -}; - -static CEmptyConVar s_EmptyConVar; - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- From f70961adac8c9c813c29941b0bccb0ecd9446a53 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 00:40:12 +0200 Subject: [PATCH 12/36] fix copyright symbol --- tier1/convar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tier1/convar.cpp b/tier1/convar.cpp index a1d2d0f3d..1709cfd67 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -1,5 +1,5 @@ -//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // From 6b126ff30f24eee53953ae479a82a5035f229b3b Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 00:43:53 +0200 Subject: [PATCH 13/36] dont break metamod compilation --- public/tier1/convar.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index cae56db03..fc5c8b6ac 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -351,8 +351,14 @@ struct ConCommandCreation_t : CVarCreationBase_t }; static_assert(sizeof(ConCommandCreation_t) == 0x40, "ConCommandCreation_t is of the wrong size!"); -class ConCommandBase {}; // For metamod compatibility only!!!! -class ConCommand : public ConCommandBase +// TO-DO: Remove this... +class ConCommandBase +{ +public: + inline const char* GetName() { return "Please remove the ConCommandBase class..."; } +}; // For metamod compatibility only!!!! + +class ConCommand { public: ConCommand( const char *pName, FnCommandCallback_t callback, From 103543c3f45ef5477d7a8364a9395a47cf575ea8 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 02:13:41 +0200 Subject: [PATCH 14/36] template the entire ConVar class --- public/icvar.h | 107 ++++++++++++++++++++++++++---------- public/tier1/convar.h | 122 ++++++++++++++++++++++++++---------------- tier1/convar.cpp | 109 ++++++------------------------------- 3 files changed, 171 insertions(+), 167 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index bf2b43d24..daa4ca1cd 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -16,17 +16,20 @@ #include "mathlib/vector4d.h" #include +class BaseConVar {}; class ConCommand; class CCommand; class CCommandContext; class ICVarListenerCallbacks; class IConVarListener; -class ConVar; struct ConVarCreation_t; struct ConCommandCreation_t; struct ConVarSnapshot_t; class KeyValues; +template +class ConVar; + union CVValue_t { CVValue_t() { memset(this, 0, sizeof(*this)); } @@ -105,8 +108,8 @@ struct CSplitScreenSlot //----------------------------------------------------------------------------- // Called when a ConVar changes value //----------------------------------------------------------------------------- -typedef void(*FnChangeCallbackGlobal_t)(ConVar* cvar, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); -using FnChangeCallback_t = void(*)(ConVar* cvar, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); +typedef void(*FnChangeCallbackGlobal_t)(BaseConVar* ref, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); +using FnChangeCallback_t = void(*)(BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); static_assert(sizeof(FnChangeCallback_t) == 0x8, "Wrong size for FnChangeCallback_t"); //----------------------------------------------------------------------------- @@ -172,40 +175,70 @@ enum EConVarType : short EConVarType_MAX }; -abstract_class IConVar +template +constexpr EConVarType TranslateConVarType(); + +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Bool; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Int16; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_UInt16; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Int32; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_UInt32; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Int64; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_UInt64; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Float32; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Float64; } +template<> constexpr EConVarType TranslateConVarType( void ){ return EConVarType_String; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Color; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Vector2; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Vector3; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Vector4; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Qangle; } +template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Invalid; } + +template +class IConVar { -friend class ConVar; +public: +friend class ConVar; + IConVar() : + m_pszName(""), + m_Default(nullptr), + m_Min(nullptr), + m_Max(nullptr), + m_pszHelpString("This convar is being accessed prior to ConVar_Register being called"), + m_eVarType(TranslateConVarType()) + { + } + inline const char* GetName( ) const { return m_pszName; } inline const char* GetDescription( ) const { return m_pszHelpString; } inline EConVarType GetType( ) const { return m_eVarType; } - inline CVValue_t* GetDefaultValue( ) const { return m_cvvDefaultValue; } - inline CVValue_t* GetMinValue( ) const { return m_cvvMinValue; } - inline CVValue_t* GetMaxValue( ) const { return m_cvvMaxValue; } + inline const T& GetDefaultValue( ) const { return m_Default->value; } + inline const T& GetMinValue( ) const { return m_Min->value; } + inline const T& GetMaxValue( ) const { return m_Max->value; } - template - inline void SetDefaultValue(const T& value) { m_cvvDefaultValue = value; } - template - inline void SetMinValue(const T& value) { m_cvvMinValue = value; } - template - inline void SetMaxValue(const T& value) { m_cvvMaxValue = value; } + inline void SetDefaultValue(const T& value) { m_Default->value = value; } + inline void SetMinValue(const T& value) { m_Min->value = value; } + inline void SetMaxValue(const T& value) { m_Max->value = value; } - template - inline const T GetValue( int index = 0 ) const { return m_value[index]; } - inline const CVValue_t& GetValue( int index = 0 ) const { return m_value[index]; } - template - inline void SetValue(const T& value, int index = 0) { m_value[index] = value; } + inline const T& GetValue( int index = 0 ) const { return m_value[index].value; } + inline void SetValue(const T& value, int index = 0) { m_value[index].value = value; } inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_flags ) ? true : false; } inline void AddFlags( int64_t flags ) { m_flags |= flags; } inline void RemoveFlags( int64_t flags ) { m_flags &= ~flags; } inline int64_t GetFlags( void ) const { return m_flags; } -protected: const char* m_pszName; - CVValue_t* m_cvvDefaultValue; - CVValue_t* m_cvvMinValue; - CVValue_t* m_cvvMaxValue; + + union TemplatedValue { + int8_t pad[sizeof(CVValue_t)]; + T value = T(); + }; + TemplatedValue* m_Default; + TemplatedValue* m_Min; + TemplatedValue* m_Max; const char* m_pszHelpString; EConVarType m_eVarType; @@ -224,8 +257,10 @@ friend class ConVar; // (1 << 2) Skip setting min/max values int allocation_flag_of_some_sort; - CVValue_t m_value[4]; + TemplatedValue m_value[4]; }; +static_assert(sizeof(IConVar) == 0x80, "IConVar has wrong size!"); +static_assert(sizeof(IConVar) == sizeof(IConVar), "IConVar templated size changes!"); //----------------------------------------------------------------------------- // Purpose: DLL interface to ConVars/ConCommands @@ -247,7 +282,9 @@ abstract_class ICvar : public IAppSystem // Install a global change callback (to be called when any convar changes) virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; virtual void RemoveGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; - virtual void CallGlobalChangeCallbacks( ConVar* var, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) = 0; + virtual void CallGlobalChangeCallbacks( BaseConVar* ref, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) = 0; + template + inline void CallGlobalChangeCallbacks( ConVar* var, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) { this->CallGlobalChangeCallbacks(var, nSlot, pOldString, flOldValue); } // Reverts cvars which contain a specific flag virtual void RevertFlaggedConVars( int nFlag ) = 0; @@ -272,16 +309,30 @@ abstract_class ICvar : public IAppSystem virtual void unk2() = 0; // Register, unregister vars - virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, IConVar** pCvar ) = 0; + virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, void** pCvar ) = 0; + template + inline void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, IConVar** pCvar ) { this->RegisterConVar(setup, nAdditionalFlags, pCvarRef, (void**)pCvar); } + virtual void UnregisterConVar( ConVarHandle handle ) = 0; - virtual IConVar* GetConVar( ConVarHandle handle ) = 0; + + virtual void* GetConVarNoType( ConVarHandle handle ) = 0; + template + inline IConVar* GetConVar( ConVarHandle handle ) + { + auto convar = (IConVar*)this->GetConVarNoType( handle ); + if (convar && convar->GetType() != TranslateConVarType()) + { + return nullptr; + } + return convar; + } // Register, unregister commands virtual ConVarHandle RegisterConCommand( const ConCommandCreation_t& setup, int64 nAdditionalFlags = 0 ) = 0; virtual void UnregisterConCommand( ConVarHandle handle ) = 0; virtual ConCommand* GetCommand( ConVarHandle handle ) = 0; - virtual void QueueThreadSetValue( ConVar* ref, CSplitScreenSlot nSlot, CVValue_t* value ) = 0; + virtual void QueueThreadSetValue( BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t* value ) = 0; }; //----------------------------------------------------------------------------- diff --git a/public/tier1/convar.h b/public/tier1/convar.h index fc5c8b6ac..4c80c491e 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -46,10 +46,8 @@ //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- -class IConVar; class CCommand; class ConCommand; -class ConVar; struct CVarCreationBase_t { @@ -174,14 +172,13 @@ class CCommandContext // Note: IVEngineClient::ClientCmd_Unrestricted can run any client command. #define FCVAR_EXECUTE_PER_TICK (1<<29) - //----------------------------------------------------------------------------- // ConVar & ConCommand creation listener callbacks //----------------------------------------------------------------------------- class ICVarListenerCallbacks { public: - virtual void OnConVarCreated( ConVar* pNewCvar ) = 0; + virtual void OnConVarCreated( BaseConVar* pNewCvar ) = 0; virtual void OnConCommandCreated( ConCommand* pNewCommand ) = 0; }; @@ -430,38 +427,50 @@ struct ConVarCreation_t : CVarCreationBase_t { ConVarSetup_t setup; // 0x18 ConVarHandle* refHandle; // 0x60 - IConVar** refConVar; // 0x68 + void** refConVar; // 0x68 }; static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); static_assert(sizeof(ConVarCreation_t) % 8 == 0x0, "ConVarCreation_t isn't 8 bytes aligned!"); static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); +// sub_10B7760 +extern void* invalid_convar[EConVarType_MAX + 1]; + +template +IConVar* ConVar_Invalid() +{ + return (IConVar*)&invalid_convar[TranslateConVarType()]; +} + +void SetupConVar( ConVarCreation_t& cvar ); +void UnRegisterConVar( ConVarHandle& cvar ); +void RegisterConVar( ConVarCreation_t& cvar ); + //----------------------------------------------------------------- // Used to read/write/create? convars (replaces the FindVar method) //----------------------------------------------------------------- -class ConVar +template +class ConVar : public BaseConVar { public: // sub_6A66B0 - template ConVar(const char* name, int32_t flags, const char* description, T value, FnChangeCallback_t cb = nullptr) { - this->Init(INVALID_CONVAR_HANDLE, TranslateType()); + this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); ConVarSetup_t setup; setup.has_default = true; setup.default_value = value; - setup.type = TranslateType(); + setup.type = TranslateConVarType(); setup.callback = cb; this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } - template ConVar(const char* name, int32_t flags, const char* description, T value, bool min, T minValue, bool max, T maxValue, FnChangeCallback_t cb = nullptr) { - this->Init(INVALID_CONVAR_HANDLE, TranslateType()); + this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); ConVarSetup_t setup; setup.has_default = true; @@ -474,12 +483,15 @@ class ConVar setup.max_value = maxValue; setup.callback = cb; - setup.type = TranslateType(); + setup.type = TranslateConVarType(); this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } - ~ConVar(); + ~ConVar() + { + UnRegisterConVar(this->m_Handle); + } inline const char* GetName( ) const { return m_ConVar->GetName( ); } inline const char* GetDescription( ) const { return m_ConVar->GetDescription( ); } @@ -489,18 +501,12 @@ class ConVar inline CVValue_t* GetMinValue( ) const { return m_ConVar->GetMinValue( ); } inline CVValue_t* GetMaxValue( ) const { return m_ConVar->GetMaxValue( ); } - template inline void SetDefaultValue(const T& value) { m_ConVar->SetDefaultValue( value ); } - template inline void SetMinValue(const T& value) { m_ConVar->SetMinValue( value ); } - template inline void SetMaxValue(const T& value) { m_ConVar->SetMaxValue( value ); } - template - inline const T GetValue( int index = 0 ) const { return m_ConVar->GetValue( index ); } - inline const CVValue_t& GetValue( int index = 0 ) const { return m_ConVar->GetValue( index ); } - template - inline void SetValue(const T& value, int index = 0) { m_ConVar->SetValue( value, index ); } + inline const T& GetValue( int index = 0 ) const { return m_ConVar->GetValue( index ); } + inline void SetValue(const T& value, int index = 0) { m_ConVar->SetValue( value, index ); } inline bool IsFlagSet( int64_t flag ) const { return m_ConVar->IsFlagSet( flag ); } inline void AddFlags( int64_t flags ) { m_ConVar->AddFlags( flags ); } @@ -508,41 +514,64 @@ class ConVar inline int64_t GetFlags( void ) const { return m_ConVar->GetFlags( ); } private: - template - static constexpr EConVarType TranslateType(); - // sub_10B7BC0 - void Init(ConVarHandle defaultHandle, EConVarType type); + void Init(ConVarHandle defaultHandle, EConVarType type) + { + this->m_Handle.Invalidate(); + this->m_ConVar = nullptr; + + // qword_191A3D8 + if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle)) == nullptr) + { + this->m_ConVar = ConVar_Invalid(); + // technically this + //result = *(char ***)(sub_10B7760((unsigned int)a3) + 80); + } + this->m_Handle = defaultHandle; + } // sub_10B7C70 - void Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& obj); + void Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& setup) + { + this->m_ConVar = ConVar_Invalid(); + this->m_Handle.Invalidate(); + + if (!CommandLine()->HasParm("-tools") + && (flags & (FCVAR_DEVELOPMENTONLY + |FCVAR_ARCHIVE + |FCVAR_USERINFO + |FCVAR_CHEAT + |FCVAR_RELEASE + |FCVAR_SERVER_CAN_EXECUTE + |FCVAR_CLIENT_CAN_EXECUTE + |FCVAR_CLIENTCMD_CAN_EXECUTE)) == 0) + { + flags |= FCVAR_DEVELOPMENTONLY; + } + + ConVarCreation_t cvar; + + cvar.name = name; + cvar.description = description; + cvar.flags = flags; + + cvar.setup = setup; + + cvar.refHandle = &this->m_Handle; + cvar.refConVar = (void**)&this->m_ConVar; + + SetupConVar(cvar); + } // High-speed method to read convar data ConVarHandle m_Handle; - IConVar* m_ConVar; + IConVar* m_ConVar; }; - -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Bool; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Int16; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_UInt16; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Int32; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_UInt32; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Int64; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_UInt64; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Float32; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Float64; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_String; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Color; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Vector2; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Vector3; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Vector4; } -template<> constexpr EConVarType ConVar::TranslateType( void ) { return EConVarType_Qangle; } +static_assert(sizeof(ConVar) == 0x10, "ConVar is of the wrong size!"); +static_assert(sizeof(ConVar) == sizeof(ConVar), "Templated ConVar size varies!"); //----------------------------------------------------------------------------- -// sub_10B7760 -IConVar* ConVar_Invalid(EConVarType type); - #ifdef CONVAR_WORK_FINISHED class CSplitScreenAddedConVar : public ConVar { @@ -887,5 +916,4 @@ class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, pu \ CCommandMemberInitializer_##_funcname m_##_funcname##_register; \ - #endif // CONVAR_H diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 1709cfd67..188a323e7 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -534,100 +534,25 @@ void ConCommand::Destroy() // //----------------------------------------------------------------------------- -class CInvalidConvar : public IConVar -{ -public: - CInvalidConvar(EConVarType type) - { - m_pszName = ""; - m_cvvDefaultValue = nullptr; - m_cvvMinValue = nullptr; - m_cvvMaxValue = nullptr; - m_pszHelpString = "This convar is being accessed prior to ConVar_Register being called"; - m_eVarType = type; - } +void* invalid_convar[EConVarType_MAX + 1] = { + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar(), + new IConVar() // EConVarType_MAX }; -CInvalidConvar invalid_convar[EConVarType_MAX + 1] = { - EConVarType_Bool, - EConVarType_Int16, - EConVarType_UInt16, - EConVarType_Int32, - EConVarType_UInt32, - EConVarType_Int64, - EConVarType_UInt64, - EConVarType_Float32, - EConVarType_Float64, - EConVarType_String, - EConVarType_Color, - EConVarType_Vector2, - EConVarType_Vector3, - EConVarType_Vector4, - EConVarType_Qangle, - EConVarType_Invalid // EConVarType_MAX -}; - -IConVar* ConVar_Invalid(EConVarType type) -{ - if (type == EConVarType_Invalid) - { - return &invalid_convar[EConVarType_MAX]; - } - return &invalid_convar[type]; -} - -ConVar::~ConVar() -{ - UnRegisterConVar(this->m_Handle); -} - -void ConVar::Init(ConVarHandle defaultHandle, EConVarType type) -{ - this->m_Handle.Invalidate(); - this->m_ConVar = nullptr; - - // qword_191A3D8 - if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle)) == nullptr) - { - this->m_ConVar = ConVar_Invalid(type); - // technically this - //result = *(char ***)(sub_10B7760((unsigned int)a3) + 80); - } - this->m_Handle = defaultHandle; -} - -void ConVar::Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& setup) -{ - this->m_ConVar = ConVar_Invalid(setup.type); - this->m_Handle.Invalidate(); - - if (!CommandLine()->HasParm("-tools") - && (flags & (FCVAR_DEVELOPMENTONLY - |FCVAR_ARCHIVE - |FCVAR_USERINFO - |FCVAR_CHEAT - |FCVAR_RELEASE - |FCVAR_SERVER_CAN_EXECUTE - |FCVAR_CLIENT_CAN_EXECUTE - |FCVAR_CLIENTCMD_CAN_EXECUTE)) == 0) - { - flags |= FCVAR_DEVELOPMENTONLY; - } - - ConVarCreation_t cvar; - - cvar.name = name; - cvar.description = description; - cvar.flags = flags; - - cvar.setup = setup; - - cvar.refHandle = &this->m_Handle; - cvar.refConVar = &this->m_ConVar; - - SetupConVar(cvar); -} - #ifdef CONVAR_WORK_FINISHED //----------------------------------------------------------------------------- From cf5226f9b5486cb6938de0f81a46cca6241a3d05 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 02:30:34 +0200 Subject: [PATCH 15/36] template change callback --- public/icvar.h | 2 -- public/tier1/convar.h | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index daa4ca1cd..a40d4d0e5 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -109,8 +109,6 @@ struct CSplitScreenSlot // Called when a ConVar changes value //----------------------------------------------------------------------------- typedef void(*FnChangeCallbackGlobal_t)(BaseConVar* ref, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); -using FnChangeCallback_t = void(*)(BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue); -static_assert(sizeof(FnChangeCallback_t) == 0x8, "Wrong size for FnChangeCallback_t"); //----------------------------------------------------------------------------- // Purpose: Replaces the ConVar* diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 4c80c491e..e9d6fcb83 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -408,7 +408,8 @@ struct ConVarSetup_t char pad; // 0x37 - FnChangeCallback_t callback; // 0x38 + using FnGenericChangeCallback_t = void(*)(BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t* pNewValue, CVValue_t* pOldValue); + FnGenericChangeCallback_t callback; // 0x38 EConVarType type; // 0x40 int32_t unk1; // 0x42 @@ -454,6 +455,7 @@ template class ConVar : public BaseConVar { public: + using FnChangeCallback_t = void(*)(ConVar* ref, CSplitScreenSlot nSlot, T* pNewValue, T* pOldValue); // sub_6A66B0 ConVar(const char* name, int32_t flags, const char* description, T value, FnChangeCallback_t cb = nullptr) { @@ -463,7 +465,7 @@ class ConVar : public BaseConVar setup.has_default = true; setup.default_value = value; setup.type = TranslateConVarType(); - setup.callback = cb; + setup.callback = reinterpret_cast(cb); this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } @@ -482,7 +484,7 @@ class ConVar : public BaseConVar setup.has_max = max; setup.max_value = maxValue; - setup.callback = cb; + setup.callback = reinterpret_cast(cb); setup.type = TranslateConVarType(); this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); From c8fdcf56dce83817c474d13065d6e1bb8ad95bbe Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 11:04:51 +0200 Subject: [PATCH 16/36] Use MAX_SPLITSCREEN_CLIENTS for IConVar definition --- public/icvar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index a40d4d0e5..43a8efcc5 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -255,9 +255,9 @@ friend class ConVar; // (1 << 2) Skip setting min/max values int allocation_flag_of_some_sort; - TemplatedValue m_value[4]; + TemplatedValue m_value[MAX_SPLITSCREEN_CLIENTS]; }; -static_assert(sizeof(IConVar) == 0x80, "IConVar has wrong size!"); +static_assert(sizeof(IConVar) == 0x50, "IConVar has wrong size!"); static_assert(sizeof(IConVar) == sizeof(IConVar), "IConVar templated size changes!"); //----------------------------------------------------------------------------- From e8d40e9d97cd6989bbdb91440972d1e7cf25cee1 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 13:34:47 +0200 Subject: [PATCH 17/36] split convarhandle once more + template iconvar --- public/icvar.h | 114 ++++++++++++++++++++++-------------------- public/tier1/convar.h | 4 +- tier1/convar.cpp | 2 +- 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 43a8efcc5..9277ce3af 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -111,43 +111,57 @@ struct CSplitScreenSlot typedef void(*FnChangeCallbackGlobal_t)(BaseConVar* ref, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); //----------------------------------------------------------------------------- -// Purpose: Replaces the ConVar* +// Purpose: Replaces the ConVar* and ConCommand* //----------------------------------------------------------------------------- class ConVarHandle { public: - ConVarHandle( uint16_t convarIndex = -1, uint16_t unk = -1, uint32_t handle = -1) : - m_convarIndex(convarIndex), - m_unknown1(unk), + ConVarHandle( uint16_t index = -1, uint32_t handle = -1) : + m_convarIndex(index), m_handleIndex(handle) {} - bool IsValid( ) const; - void Invalidate( ); + bool IsValid( ) const { return m_convarIndex != 0xFFFF; } + void Invalidate( ) + { + m_convarIndex = 0xFFFF; + m_handleIndex = 0x0; + } uint16_t GetConVarIndex() const { return m_convarIndex; } uint32_t GetIndex() const { return m_handleIndex; } private: uint16_t m_convarIndex; - uint16_t m_unknown1; uint32_t m_handleIndex; }; -static_assert(sizeof(ConVarHandle) == 0x8, "ConVarHandle is of the wrong size!"); static const ConVarHandle INVALID_CONVAR_HANDLE = ConVarHandle(); -inline bool ConVarHandle::IsValid() const +class ConCommandHandle { - return m_convarIndex != 0xFFFF; -} +public: + ConCommandHandle( uint16_t index = -1, uint32_t handle = -1) : + m_concommandIndex(index), + m_handleIndex(handle) + {} -inline void ConVarHandle::Invalidate() -{ - m_convarIndex = 0xFFFF; - m_unknown1 = 0xFFFF; - m_handleIndex = 0x0; -} + bool IsValid( ) const { return m_concommandIndex != 0xFFFF; } + void Invalidate( ) + { + m_concommandIndex = 0xFFFF; + m_handleIndex = 0x0; + } + + uint16_t GetConVarIndex() const { return m_concommandIndex; } + uint32_t GetIndex() const { return m_handleIndex; } + +private: + uint32_t m_concommandIndex; + uint32_t m_handleIndex; +}; + +static const ConCommandHandle INVALID_CONCOMMAND_HANDLE = ConCommandHandle(); //----------------------------------------------------------------------------- // Purpose: Internal structure of ConVar objects @@ -200,9 +214,9 @@ class IConVar friend class ConVar; IConVar() : m_pszName(""), - m_Default(nullptr), - m_Min(nullptr), - m_Max(nullptr), + m_defaultValue(new T()), + m_minValue(new T()), + m_maxValue(new T()), m_pszHelpString("This convar is being accessed prior to ConVar_Register being called"), m_eVarType(TranslateConVarType()) { @@ -212,40 +226,36 @@ friend class ConVar; inline const char* GetDescription( ) const { return m_pszHelpString; } inline EConVarType GetType( ) const { return m_eVarType; } - inline const T& GetDefaultValue( ) const { return m_Default->value; } - inline const T& GetMinValue( ) const { return m_Min->value; } - inline const T& GetMaxValue( ) const { return m_Max->value; } + inline const T& GetDefaultValue( ) const { return *m_defaultValue; } + inline const T& GetMinValue( ) const { return *m_minValue; } + inline const T& GetMaxValue( ) const { return *m_maxValue; } - inline void SetDefaultValue(const T& value) { m_Default->value = value; } - inline void SetMinValue(const T& value) { m_Min->value = value; } - inline void SetMaxValue(const T& value) { m_Max->value = value; } + inline void SetDefaultValue(const T& value) { *m_defaultValue = value; } + inline void SetMinValue(const T& value) { *m_minValue = value; } + inline void SetMaxValue(const T& value) { *m_maxValue = value; } - inline const T& GetValue( int index = 0 ) const { return m_value[index].value; } - inline void SetValue(const T& value, int index = 0) { m_value[index].value = value; } + inline const T& GetValue( int index = 0 ) const { return m_value[index]; } + inline void SetValue(const T& value, int index = 0) { m_value[index] = value; } - inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_flags ) ? true : false; } - inline void AddFlags( int64_t flags ) { m_flags |= flags; } - inline void RemoveFlags( int64_t flags ) { m_flags &= ~flags; } - inline int64_t GetFlags( void ) const { return m_flags; } + inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_nFlags ) ? true : false; } + inline void AddFlags( int64_t flags ) { m_nFlags |= flags; } + inline void RemoveFlags( int64_t flags ) { m_nFlags &= ~flags; } + inline int64_t GetFlags( void ) const { return m_nFlags; } const char* m_pszName; - union TemplatedValue { - int8_t pad[sizeof(CVValue_t)]; - T value = T(); - }; - TemplatedValue* m_Default; - TemplatedValue* m_Min; - TemplatedValue* m_Max; + T* m_defaultValue; + T* m_minValue; + T* m_maxValue; const char* m_pszHelpString; EConVarType m_eVarType; // This gets copied from the ConVarDesc_t on creation short unk1; - unsigned int timesChanged; - int64 m_flags; - unsigned int callback_index; + unsigned int m_iTimesChanged; + int64 m_nFlags; + unsigned int m_iCallbackIndex; // Used when setting default, max, min values from the ConVarDesc_t // although that's not the only place of usage @@ -253,12 +263,10 @@ friend class ConVar; // (1 << 0) Skip setting value to split screen slots and also something keyvalues related // (1 << 1) Skip setting default value // (1 << 2) Skip setting min/max values - int allocation_flag_of_some_sort; + int m_nUnknownAllocFlags; - TemplatedValue m_value[MAX_SPLITSCREEN_CLIENTS]; + T m_value[MAX_SPLITSCREEN_CLIENTS]; }; -static_assert(sizeof(IConVar) == 0x50, "IConVar has wrong size!"); -static_assert(sizeof(IConVar) == sizeof(IConVar), "IConVar templated size changes!"); //----------------------------------------------------------------------------- // Purpose: DLL interface to ConVars/ConCommands @@ -272,10 +280,10 @@ abstract_class ICvar : public IAppSystem virtual ConVarHandle FindNextConVar( ConVarHandle prev ) = 0; virtual void SetConVarValue( ConVarHandle cvarid, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue ) = 0; - virtual ConVarHandle FindCommand( const char *name ) = 0; - virtual ConVarHandle FindFirstCommand() = 0; - virtual ConVarHandle FindNextCommand( ConVarHandle prev ) = 0; - virtual void DispatchConCommand( ConVarHandle cmd, const CCommandContext &ctx, const CCommand &args ) = 0; + virtual ConCommandHandle FindCommand( const char *name ) = 0; + virtual ConCommandHandle FindFirstCommand() = 0; + virtual ConCommandHandle FindNextCommand( ConCommandHandle prev ) = 0; + virtual void DispatchConCommand( ConCommandHandle cmd, const CCommandContext &ctx, const CCommand &args ) = 0; // Install a global change callback (to be called when any convar changes) virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; @@ -326,9 +334,9 @@ abstract_class ICvar : public IAppSystem } // Register, unregister commands - virtual ConVarHandle RegisterConCommand( const ConCommandCreation_t& setup, int64 nAdditionalFlags = 0 ) = 0; - virtual void UnregisterConCommand( ConVarHandle handle ) = 0; - virtual ConCommand* GetCommand( ConVarHandle handle ) = 0; + virtual ConCommandHandle RegisterConCommand( const ConCommandCreation_t& setup, int64 nAdditionalFlags = 0 ) = 0; + virtual void UnregisterConCommand( ConCommandHandle handle ) = 0; + virtual ConCommand* GetCommand( ConCommandHandle handle ) = 0; virtual void QueueThreadSetValue( BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t* value ) = 0; }; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index e9d6fcb83..33ea5d3b1 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -344,7 +344,7 @@ struct ConCommandCreation_t : CVarCreationBase_t bool has_complitioncallback; bool is_interface; - ConVarHandle* refHandle; + ConCommandHandle* refHandle; }; static_assert(sizeof(ConCommandCreation_t) == 0x40, "ConCommandCreation_t is of the wrong size!"); @@ -376,7 +376,7 @@ class ConCommand void Create( const char *pName, const char *pHelpString, int64_t flags, ConCommandCreation_t& setup ); void Destroy( ); - ConVarHandle m_Handle; + ConCommandHandle m_Handle; }; #pragma pack(push,1) diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 188a323e7..cb8f47bc8 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -43,7 +43,7 @@ void RegisterCommand( ConCommandCreation_t& cmd ) } } -void UnRegisterCommand( ConVarHandle& cmd ) +void UnRegisterCommand( ConCommandHandle& cmd ) { if ( cmd.IsValid() ) { From fda174f1b5814c24eaa786f78a2d0d18d1dd3ffd Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 13:55:43 +0200 Subject: [PATCH 18/36] Renaming IConVar and depollute ICVar --- public/icvar.h | 124 +++++++++++++++++++++++++----------------- public/tier1/convar.h | 18 +++--- tier1/convar.cpp | 32 +++++------ 3 files changed, 101 insertions(+), 73 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 9277ce3af..c7f6908b9 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -208,45 +208,45 @@ template<> constexpr EConVarType TranslateConVarType( void ) { return EC template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Invalid; } template -class IConVar +struct ConVarData_t; + +struct ConVarBaseData_t { -public: -friend class ConVar; - IConVar() : - m_pszName(""), - m_defaultValue(new T()), - m_minValue(new T()), - m_maxValue(new T()), - m_pszHelpString("This convar is being accessed prior to ConVar_Register being called"), - m_eVarType(TranslateConVarType()) + template + inline const ConVarData_t* Cast() const { + if (this->m_eVarType == TranslateConVarType()) + { + return reinterpret_cast*>(this); + } + return nullptr; } - inline const char* GetName( ) const { return m_pszName; } - inline const char* GetDescription( ) const { return m_pszHelpString; } - inline EConVarType GetType( ) const { return m_eVarType; } - - inline const T& GetDefaultValue( ) const { return *m_defaultValue; } - inline const T& GetMinValue( ) const { return *m_minValue; } - inline const T& GetMaxValue( ) const { return *m_maxValue; } - - inline void SetDefaultValue(const T& value) { *m_defaultValue = value; } - inline void SetMinValue(const T& value) { *m_minValue = value; } - inline void SetMaxValue(const T& value) { *m_maxValue = value; } - - inline const T& GetValue( int index = 0 ) const { return m_value[index]; } - inline void SetValue(const T& value, int index = 0) { m_value[index] = value; } + template + inline ConVarData_t* Cast() + { + if (this->m_eVarType == TranslateConVarType()) + { + return reinterpret_cast*>(this); + } + return nullptr; + } - inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_nFlags ) ? true : false; } - inline void AddFlags( int64_t flags ) { m_nFlags |= flags; } - inline void RemoveFlags( int64_t flags ) { m_nFlags &= ~flags; } - inline int64_t GetFlags( void ) const { return m_nFlags; } + ConVarBaseData_t() : + m_pszName(""), + m_defaultValue(nullptr), + m_minValue(nullptr), + m_maxValue(nullptr), + m_pszHelpString("This convar is being accessed prior to ConVar_Register being called"), + m_eVarType(EConVarType_Invalid) + { + } const char* m_pszName; - T* m_defaultValue; - T* m_minValue; - T* m_maxValue; + void* m_defaultValue; + void* m_minValue; + void* m_maxValue; const char* m_pszHelpString; EConVarType m_eVarType; @@ -264,6 +264,47 @@ friend class ConVar; // (1 << 1) Skip setting default value // (1 << 2) Skip setting min/max values int m_nUnknownAllocFlags; +}; + +template +struct ConVarData_t : ConVarBaseData_t +{ +public: +friend class ConVar; + ConVarData_t() + { + m_defaultValue = new T(); + m_minValue = new T(); + m_maxValue = new T(); + m_eVarType = TranslateConVarType(); + } + + ~ConVarData_t() + { + delete m_defaultValue; + delete m_minValue; + delete m_eVarType; + } + + inline const char* GetName( ) const { return m_pszName; } + inline const char* GetDescription( ) const { return m_pszHelpString; } + inline EConVarType GetType( ) const { return m_eVarType; } + + inline const T& GetDefaultValue( ) const { return *reinterpret_cast(m_defaultValue); } + inline const T& GetMinValue( ) const { return *reinterpret_cast(m_minValue); } + inline const T& GetMaxValue( ) const { return *reinterpret_cast(m_maxValue); } + + inline void SetDefaultValue(const T& value) { *reinterpret_cast(m_defaultValue) = value; } + inline void SetMinValue(const T& value) { *reinterpret_cast(m_minValue) = value; } + inline void SetMaxValue(const T& value) { *reinterpret_cast(m_maxValue) = value; } + + inline const T& GetValue( int index = 0 ) const { return m_value[index]; } + inline void SetValue(const T& value, int index = 0) { m_value[index] = value; } + + inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_nFlags ) ? true : false; } + inline void AddFlags( int64_t flags ) { m_nFlags |= flags; } + inline void RemoveFlags( int64_t flags ) { m_nFlags &= ~flags; } + inline int64_t GetFlags( void ) const { return m_nFlags; } T m_value[MAX_SPLITSCREEN_CLIENTS]; }; @@ -289,9 +330,6 @@ abstract_class ICvar : public IAppSystem virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; virtual void RemoveGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; virtual void CallGlobalChangeCallbacks( BaseConVar* ref, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) = 0; - template - inline void CallGlobalChangeCallbacks( ConVar* var, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) { this->CallGlobalChangeCallbacks(var, nSlot, pOldString, flOldValue); } - // Reverts cvars which contain a specific flag virtual void RevertFlaggedConVars( int nFlag ) = 0; @@ -315,23 +353,9 @@ abstract_class ICvar : public IAppSystem virtual void unk2() = 0; // Register, unregister vars - virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, void** pCvar ) = 0; - template - inline void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, IConVar** pCvar ) { this->RegisterConVar(setup, nAdditionalFlags, pCvarRef, (void**)pCvar); } - + virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, ConVarBaseData_t** pCvar ) = 0; virtual void UnregisterConVar( ConVarHandle handle ) = 0; - - virtual void* GetConVarNoType( ConVarHandle handle ) = 0; - template - inline IConVar* GetConVar( ConVarHandle handle ) - { - auto convar = (IConVar*)this->GetConVarNoType( handle ); - if (convar && convar->GetType() != TranslateConVarType()) - { - return nullptr; - } - return convar; - } + virtual ConVarBaseData_t* GetConVar( ConVarHandle handle ) = 0; // Register, unregister commands virtual ConCommandHandle RegisterConCommand( const ConCommandCreation_t& setup, int64 nAdditionalFlags = 0 ) = 0; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 33ea5d3b1..f5282461c 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -428,7 +428,7 @@ struct ConVarCreation_t : CVarCreationBase_t { ConVarSetup_t setup; // 0x18 ConVarHandle* refHandle; // 0x60 - void** refConVar; // 0x68 + ConVarBaseData_t** refConVar; // 0x68 }; static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); @@ -439,9 +439,9 @@ static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); extern void* invalid_convar[EConVarType_MAX + 1]; template -IConVar* ConVar_Invalid() +ConVarData_t* ConVar_Invalid() { - return (IConVar*)&invalid_convar[TranslateConVarType()]; + return (ConVarData_t*)&invalid_convar[TranslateConVarType()]; } void SetupConVar( ConVarCreation_t& cvar ); @@ -523,9 +523,13 @@ class ConVar : public BaseConVar this->m_ConVar = nullptr; // qword_191A3D8 - if (g_pCVar && (this->m_ConVar = g_pCVar->GetConVar(defaultHandle)) == nullptr) + if (g_pCVar) { - this->m_ConVar = ConVar_Invalid(); + this->m_ConVar = g_pCVar->GetConVar(defaultHandle)->Cast(); + if (!this->m_ConVar) + { + this->m_ConVar = ConVar_Invalid(); + } // technically this //result = *(char ***)(sub_10B7760((unsigned int)a3) + 80); } @@ -560,14 +564,14 @@ class ConVar : public BaseConVar cvar.setup = setup; cvar.refHandle = &this->m_Handle; - cvar.refConVar = (void**)&this->m_ConVar; + cvar.refConVar = (ConVarBaseData_t**)&this->m_ConVar; SetupConVar(cvar); } // High-speed method to read convar data ConVarHandle m_Handle; - IConVar* m_ConVar; + ConVarData_t* m_ConVar; }; static_assert(sizeof(ConVar) == 0x10, "ConVar is of the wrong size!"); static_assert(sizeof(ConVar) == sizeof(ConVar), "Templated ConVar size varies!"); diff --git a/tier1/convar.cpp b/tier1/convar.cpp index cb8f47bc8..23836ce47 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -535,22 +535,22 @@ void ConCommand::Destroy() //----------------------------------------------------------------------------- void* invalid_convar[EConVarType_MAX + 1] = { - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar(), - new IConVar() // EConVarType_MAX + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t(), + new ConVarData_t() // EConVarType_MAX }; #ifdef CONVAR_WORK_FINISHED From f73e6d6787a2ece9c5306424f7c80775b67ecf62 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 14:01:16 +0200 Subject: [PATCH 19/36] remove static_assert + IDA comments --- public/tier1/convar.h | 6 +----- tier1/convar.cpp | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index f5282461c..3cfd103e2 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -435,7 +435,6 @@ static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); static_assert(sizeof(ConVarCreation_t) % 8 == 0x0, "ConVarCreation_t isn't 8 bytes aligned!"); static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); -// sub_10B7760 extern void* invalid_convar[EConVarType_MAX + 1]; template @@ -456,7 +455,7 @@ class ConVar : public BaseConVar { public: using FnChangeCallback_t = void(*)(ConVar* ref, CSplitScreenSlot nSlot, T* pNewValue, T* pOldValue); - // sub_6A66B0 + ConVar(const char* name, int32_t flags, const char* description, T value, FnChangeCallback_t cb = nullptr) { this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); @@ -516,13 +515,11 @@ class ConVar : public BaseConVar inline int64_t GetFlags( void ) const { return m_ConVar->GetFlags( ); } private: - // sub_10B7BC0 void Init(ConVarHandle defaultHandle, EConVarType type) { this->m_Handle.Invalidate(); this->m_ConVar = nullptr; - // qword_191A3D8 if (g_pCVar) { this->m_ConVar = g_pCVar->GetConVar(defaultHandle)->Cast(); @@ -536,7 +533,6 @@ class ConVar : public BaseConVar this->m_Handle = defaultHandle; } - // sub_10B7C70 void Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& setup) { this->m_ConVar = ConVar_Invalid(); diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 23836ce47..8256505d7 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -195,11 +195,9 @@ class ConVarRegList public: static bool s_bConVarsRegistered; }; -static_assert(sizeof(ConVarRegList) == 0x2BD0, "Size mismatch"); bool ConVarRegList::s_bConVarsRegistered = false; -// sub_10B79F0 void SetupConVar( ConVarCreation_t& cvar ) { if ( ConVarRegList::s_bConVarsRegistered ) From c8d07f89e94adf4029f94f8dbe5790e35b63f841 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 14:26:49 +0200 Subject: [PATCH 20/36] renaming struct properties --- public/tier1/convar.h | 212 ++++++++++++++++++------------------------ tier1/convar.cpp | 78 ++++++++-------- 2 files changed, 132 insertions(+), 158 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 3cfd103e2..abf433889 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -52,9 +52,9 @@ class ConCommand; struct CVarCreationBase_t { CVarCreationBase_t( ) : - name( nullptr ), - description( nullptr ), - flags( 0 ) + m_pszName( nullptr ), + m_pszHelpString( nullptr ), + m_nFlags( 0 ) {} bool IsFlagSet( int64_t flag ) const; @@ -62,35 +62,11 @@ struct CVarCreationBase_t void RemoveFlags( int64_t flags ); int64_t GetFlags() const; - const char* name; - const char* description; - int64_t flags; + const char* m_pszName; + const char* m_pszHelpString; + int64_t m_nFlags; }; -inline bool CVarCreationBase_t::IsFlagSet( int64_t flag ) const -{ - return ( flag & this->flags ) ? true : false; -} - -inline void CVarCreationBase_t::AddFlags( int64_t flags ) -{ - this->flags |= flags; - -#ifdef ALLOW_DEVELOPMENT_CVARS - this->flags &= ~FCVAR_DEVELOPMENTONLY; -#endif -} - -inline void CVarCreationBase_t::RemoveFlags( int64_t flags ) -{ - this->flags &= ~flags; -} - -inline int64_t CVarCreationBase_t::GetFlags( void ) const -{ - return this->flags; -} - enum CommandTarget_t { CT_NO_TARGET = -1, @@ -298,34 +274,34 @@ inline const char *CCommand::operator[]( int nIndex ) const struct ConCommandCreation_t : CVarCreationBase_t { ConCommandCreation_t() : - has_complitioncallback(false), - is_interface(false), - refHandle(nullptr) + m_bHasCompletionCallback(false), + m_bIsInterface(false), + m_pHandle(nullptr) {} // Call this function when executing the command struct CallbackInfo_t { CallbackInfo_t() : - fnCommandCallback(nullptr), - is_interface(false), - is_voidcallback(false), - is_contextless(false) + m_fnCommandCallback(nullptr), + m_bIsInterface(false), + m_bIsVoidCallback(false), + m_bIsContextLess(false) {} union { - FnCommandCallback_t fnCommandCallback; - FnCommandCallbackVoid_t fnVoidCommandCallback; - FnCommandCallbackNoContext_t fnContextlessCommandCallback; - ICommandCallback* pCommandCallback; + FnCommandCallback_t m_fnCommandCallback; + FnCommandCallbackVoid_t m_fnVoidCommandCallback; + FnCommandCallbackNoContext_t m_fnContextlessCommandCallback; + ICommandCallback* m_pCommandCallback; }; - bool is_interface; - bool is_voidcallback; - bool is_contextless; + bool m_bIsInterface; + bool m_bIsVoidCallback; + bool m_bIsContextLess; }; - CallbackInfo_t callback; + CallbackInfo_t m_fnCallback; // NOTE: To maintain backward compat, we have to be very careful: // All public virtual methods must appear in the same order always @@ -337,14 +313,14 @@ struct ConCommandCreation_t : CVarCreationBase_t union { - FnCommandCompletionCallback fnCompletionCallback; - ICommandCompletionCallback* pCommandCompletionCallback; + FnCommandCompletionCallback m_fnCompletionCallback; + ICommandCompletionCallback* m_pCommandCompletionCallback; }; - bool has_complitioncallback; - bool is_interface; + bool m_bHasCompletionCallback; + bool m_bIsInterface; - ConCommandHandle* refHandle; + ConCommandHandle* m_pHandle; }; static_assert(sizeof(ConCommandCreation_t) == 0x40, "ConCommandCreation_t is of the wrong size!"); @@ -379,56 +355,55 @@ class ConCommand ConCommandHandle m_Handle; }; +using FnGenericChangeCallback_t = void(*)(BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t* pNewValue, CVValue_t* pOldValue); #pragma pack(push,1) struct ConVarSetup_t { ConVarSetup_t() : - unknown0(0), - has_default(false), - has_min(false), - has_max(false), - default_value(), - min_value(), - max_value(), - callback(nullptr), - type(EConVarType_Invalid), - unk1(0), - unk2(0) + m_unknown1(0), + m_bHasDefault(false), + m_bHasMin(false), + m_bHasMax(false), + m_defaultValue(), + m_minValue(), + m_maxValue(), + m_fnCallBack(nullptr), + m_eVarType(EConVarType_Invalid), + m_unknown2(0), + m_unknown3(0) {} - int32 unknown0; // 0x0 + int32_t m_unknown1; // 0x0 - bool has_default; // 0x4 - bool has_min; // 0x5 - bool has_max; // 0x6 + bool m_bHasDefault; // 0x4 + bool m_bHasMin; // 0x5 + bool m_bHasMax; // 0x6 - CVValue_t default_value; // 0x7 - CVValue_t min_value; // 0x17 - CVValue_t max_value; // 0x27 + CVValue_t m_defaultValue; // 0x7 + CVValue_t m_minValue; // 0x17 + CVValue_t m_maxValue; // 0x27 char pad; // 0x37 - using FnGenericChangeCallback_t = void(*)(BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t* pNewValue, CVValue_t* pOldValue); - FnGenericChangeCallback_t callback; // 0x38 - EConVarType type; // 0x40 + FnGenericChangeCallback_t m_fnCallBack; // 0x38 + EConVarType m_eVarType; // 0x40 - int32_t unk1; // 0x42 - int16_t unk2; // 0x46 + int32_t m_unknown2; // 0x42 + int16_t m_unknown3; // 0x46 }; #pragma pack(pop) - static_assert(sizeof(ConVarSetup_t) == 0x48, "ConVarSetup_t is of the wrong size!"); static_assert(sizeof(ConVarSetup_t) % 8 == 0x0, "ConVarSetup_t isn't 8 bytes aligned!"); struct ConVarCreation_t : CVarCreationBase_t { ConVarCreation_t() : - refHandle(nullptr), - refConVar(nullptr) + m_pHandle(nullptr), + m_pConVarData(nullptr) {} - ConVarSetup_t setup; // 0x18 + ConVarSetup_t m_cvarSetup; // 0x18 - ConVarHandle* refHandle; // 0x60 - ConVarBaseData_t** refConVar; // 0x68 + ConVarHandle* m_pHandle; // 0x60 + ConVarBaseData_t** m_pConVarData; // 0x68 }; static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); @@ -461,10 +436,10 @@ class ConVar : public BaseConVar this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); ConVarSetup_t setup; - setup.has_default = true; - setup.default_value = value; - setup.type = TranslateConVarType(); - setup.callback = reinterpret_cast(cb); + setup.m_bHasDefault = true; + setup.m_defaultValue = value; + setup.m_eVarType = TranslateConVarType(); + setup.m_fnCallBack = reinterpret_cast(cb); this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } @@ -474,17 +449,16 @@ class ConVar : public BaseConVar this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); ConVarSetup_t setup; - setup.has_default = true; - setup.default_value = value; - - setup.has_min = min; - setup.min_value = minValue; + setup.m_bHasDefault = true; + setup.m_defaultValue = value; - setup.has_max = max; - setup.max_value = maxValue; + setup.m_bHasMin = min; + setup.m_bHasMax = max; + setup.m_minValue = minValue; + setup.m_maxValue = maxValue; - setup.callback = reinterpret_cast(cb); - setup.type = TranslateConVarType(); + setup.m_eVarType = TranslateConVarType(); + setup.m_fnCallBack = reinterpret_cast(cb); this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } @@ -494,38 +468,38 @@ class ConVar : public BaseConVar UnRegisterConVar(this->m_Handle); } - inline const char* GetName( ) const { return m_ConVar->GetName( ); } - inline const char* GetDescription( ) const { return m_ConVar->GetDescription( ); } - inline EConVarType GetType( ) const { return m_ConVar->GetType( ); } + inline const char* GetName( ) const { return m_ConVarData->GetName( ); } + inline const char* GetDescription( ) const { return m_ConVarData->GetDescription( ); } + inline EConVarType GetType( ) const { return m_ConVarData->GetType( ); } - inline CVValue_t* GetDefaultValue( ) const { return m_ConVar->GetDefaultValue( ); } - inline CVValue_t* GetMinValue( ) const { return m_ConVar->GetMinValue( ); } - inline CVValue_t* GetMaxValue( ) const { return m_ConVar->GetMaxValue( ); } + inline CVValue_t* GetDefaultValue( ) const { return m_ConVarData->GetDefaultValue( ); } + inline CVValue_t* GetMinValue( ) const { return m_ConVarData->GetMinValue( ); } + inline CVValue_t* GetMaxValue( ) const { return m_ConVarData->GetMaxValue( ); } - inline void SetDefaultValue(const T& value) { m_ConVar->SetDefaultValue( value ); } - inline void SetMinValue(const T& value) { m_ConVar->SetMinValue( value ); } - inline void SetMaxValue(const T& value) { m_ConVar->SetMaxValue( value ); } + inline void SetDefaultValue(const T& value) { m_ConVarData->SetDefaultValue( value ); } + inline void SetMinValue(const T& value) { m_ConVarData->SetMinValue( value ); } + inline void SetMaxValue(const T& value) { m_ConVarData->SetMaxValue( value ); } - inline const T& GetValue( int index = 0 ) const { return m_ConVar->GetValue( index ); } - inline void SetValue(const T& value, int index = 0) { m_ConVar->SetValue( value, index ); } + inline const T& GetValue( int index = 0 ) const { return m_ConVarData->GetValue( index ); } + inline void SetValue(const T& value, int index = 0) { m_ConVarData->SetValue( value, index ); } - inline bool IsFlagSet( int64_t flag ) const { return m_ConVar->IsFlagSet( flag ); } - inline void AddFlags( int64_t flags ) { m_ConVar->AddFlags( flags ); } - inline void RemoveFlags( int64_t flags ) { return m_ConVar->RemoveFlags( flags ); } - inline int64_t GetFlags( void ) const { return m_ConVar->GetFlags( ); } + inline bool IsFlagSet( int64_t flag ) const { return m_ConVarData->IsFlagSet( flag ); } + inline void AddFlags( int64_t flags ) { m_ConVarData->AddFlags( flags ); } + inline void RemoveFlags( int64_t flags ) { return m_ConVarData->RemoveFlags( flags ); } + inline int64_t GetFlags( void ) const { return m_ConVarData->GetFlags( ); } private: void Init(ConVarHandle defaultHandle, EConVarType type) { this->m_Handle.Invalidate(); - this->m_ConVar = nullptr; + this->m_ConVarData = nullptr; if (g_pCVar) { - this->m_ConVar = g_pCVar->GetConVar(defaultHandle)->Cast(); - if (!this->m_ConVar) + this->m_ConVarData = g_pCVar->GetConVar(defaultHandle)->Cast(); + if (!this->m_ConVarData) { - this->m_ConVar = ConVar_Invalid(); + this->m_ConVarData = ConVar_Invalid(); } // technically this //result = *(char ***)(sub_10B7760((unsigned int)a3) + 80); @@ -535,7 +509,7 @@ class ConVar : public BaseConVar void Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& setup) { - this->m_ConVar = ConVar_Invalid(); + this->m_ConVarData = ConVar_Invalid(); this->m_Handle.Invalidate(); if (!CommandLine()->HasParm("-tools") @@ -553,21 +527,21 @@ class ConVar : public BaseConVar ConVarCreation_t cvar; - cvar.name = name; - cvar.description = description; - cvar.flags = flags; + cvar.m_pszName = name; + cvar.m_pszHelpString = description; + cvar.m_nFlags = flags; - cvar.setup = setup; + cvar.m_cvarSetup = setup; - cvar.refHandle = &this->m_Handle; - cvar.refConVar = (ConVarBaseData_t**)&this->m_ConVar; + cvar.m_pHandle = &this->m_Handle; + cvar.m_pConVarData = (ConVarBaseData_t**)&this->m_ConVarData; SetupConVar(cvar); } // High-speed method to read convar data ConVarHandle m_Handle; - ConVarData_t* m_ConVar; + ConVarData_t* m_ConVarData; }; static_assert(sizeof(ConVar) == 0x10, "ConVar is of the wrong size!"); static_assert(sizeof(ConVar) == sizeof(ConVar), "Templated ConVar size varies!"); diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 8256505d7..741cb7d78 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -35,10 +35,10 @@ static bool s_bRegistered = false; void RegisterCommand( ConCommandCreation_t& cmd ) { - *cmd.refHandle = g_pCVar->RegisterConCommand( cmd, s_nCVarFlag ); - if ( !cmd.refHandle->IsValid() ) + *cmd.m_pHandle = g_pCVar->RegisterConCommand( cmd, s_nCVarFlag ); + if ( !cmd.m_pHandle->IsValid() ) { - Plat_FatalErrorFunc( "RegisterConCommand: Unknown error registering con command \"%s\"!\n", cmd.name ); + Plat_FatalErrorFunc( "RegisterConCommand: Unknown error registering con command \"%s\"!\n", cmd.m_pszName ); DebuggerBreakIfDebugging( ); } } @@ -125,10 +125,10 @@ void AddCommand( ConCommandCreation_t& cmd ) void RegisterConVar( ConVarCreation_t& cvar ) { - g_pCVar->RegisterConVar( cvar, s_nCVarFlag, cvar.refHandle, cvar.refConVar ); - if (!cvar.refHandle->IsValid()) + g_pCVar->RegisterConVar( cvar, s_nCVarFlag, cvar.m_pHandle, cvar.m_pConVarData ); + if (!cvar.m_pHandle->IsValid()) { - Plat_FatalErrorFunc( "RegisterConVar: Unknown error registering convar \"%s\"!\n", cvar.name ); + Plat_FatalErrorFunc( "RegisterConVar: Unknown error registering convar \"%s\"!\n", cvar.m_pszName ); DebuggerBreakIfDebugging(); } } @@ -434,14 +434,14 @@ int DefaultCompletionFunc( const char *partial, CUtlVector< CUtlString > &comman ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { ConCommandCreation_t creation; - creation.callback.fnCommandCallback = callback; - creation.callback.is_interface = false; - creation.callback.is_voidcallback = false; - creation.callback.is_contextless = false; + creation.m_fnCallback.m_fnCommandCallback = callback; + creation.m_fnCallback.m_bIsInterface = false; + creation.m_fnCallback.m_bIsVoidCallback = false; + creation.m_fnCallback.m_bIsContextLess = false; - creation.fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - creation.has_complitioncallback = completionFunc != 0 ? true : false; - creation.is_interface = false; + creation.m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; + creation.m_bHasCompletionCallback = completionFunc != 0 ? true : false; + creation.m_bIsInterface = false; // Setup the rest Create( pName, pHelpString, flags, creation ); @@ -450,14 +450,14 @@ ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const c ConCommand::ConCommand( const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { ConCommandCreation_t creation; - creation.callback.fnVoidCommandCallback = callback; - creation.callback.is_interface = false; - creation.callback.is_voidcallback = true; - creation.callback.is_contextless = false; + creation.m_fnCallback.m_fnVoidCommandCallback = callback; + creation.m_fnCallback.m_bIsInterface = false; + creation.m_fnCallback.m_bIsVoidCallback = true; + creation.m_fnCallback.m_bIsContextLess = false; - creation.fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - creation.has_complitioncallback = completionFunc != nullptr ? true : false; - creation.is_interface = false; + creation.m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; + creation.m_bHasCompletionCallback = completionFunc != nullptr ? true : false; + creation.m_bIsInterface = false; // Setup the rest Create( pName, pHelpString, flags, creation ); @@ -466,14 +466,14 @@ ConCommand::ConCommand( const char *pName, FnCommandCallbackVoid_t callback, con ConCommand::ConCommand( const char *pName, FnCommandCallbackNoContext_t callback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { ConCommandCreation_t creation; - creation.callback.fnContextlessCommandCallback = callback; - creation.callback.is_interface = false; - creation.callback.is_voidcallback = false; - creation.callback.is_contextless = true; + creation.m_fnCallback.m_fnContextlessCommandCallback = callback; + creation.m_fnCallback.m_bIsInterface = false; + creation.m_fnCallback.m_bIsVoidCallback = false; + creation.m_fnCallback.m_bIsContextLess = true; - creation.fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - creation.has_complitioncallback = completionFunc != nullptr ? true : false; - creation.is_interface = false; + creation.m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; + creation.m_bHasCompletionCallback = completionFunc != nullptr ? true : false; + creation.m_bIsInterface = false; // Setup the rest Create( pName, pHelpString, flags, creation ); @@ -482,14 +482,14 @@ ConCommand::ConCommand( const char *pName, FnCommandCallbackNoContext_t callback ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int64 flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ ) { ConCommandCreation_t creation; - creation.callback.pCommandCallback = pCallback; - creation.callback.is_interface = true; - creation.callback.is_voidcallback = false; - creation.callback.is_contextless = false; + creation.m_fnCallback.m_pCommandCallback = pCallback; + creation.m_fnCallback.m_bIsInterface = true; + creation.m_fnCallback.m_bIsVoidCallback = false; + creation.m_fnCallback.m_bIsContextLess = false; - creation.pCommandCompletionCallback = pCompletionCallback; - creation.has_complitioncallback = pCompletionCallback != nullptr ? true : false; - creation.is_interface = true; + creation.m_pCommandCompletionCallback = pCompletionCallback; + creation.m_bHasCompletionCallback = pCompletionCallback != nullptr ? true : false; + creation.m_bIsInterface = true; // Setup the rest Create( pName, pHelpString, flags, creation ); @@ -508,15 +508,15 @@ void ConCommand::Create( const char* pName, const char* pHelpString, int64_t fla // Name should be static data Assert(pName); - setup.name = pName; - setup.description = pHelpString ? pHelpString : empty_string; + setup.m_pszName = pName; + setup.m_pszHelpString = pHelpString ? pHelpString : empty_string; - setup.flags = flags; + setup.m_nFlags = flags; #ifdef ALLOW_DEVELOPMENT_CVARS - setup.flags &= ~FCVAR_DEVELOPMENTONLY; + setup.m_nFlags &= ~FCVAR_DEVELOPMENTONLY; #endif - setup.refHandle = &this->m_Handle; + setup.m_pHandle = &this->m_Handle; AddCommand( setup ); } From a7f6ce176efedbbdc3a10955bc43e5ae7ae97220 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 14:33:41 +0200 Subject: [PATCH 21/36] undo icommandline change --- public/tier0/icommandline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/tier0/icommandline.h b/public/tier0/icommandline.h index 9f30237cb..ee3a1469b 100644 --- a/public/tier0/icommandline.h +++ b/public/tier0/icommandline.h @@ -1,4 +1,4 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // From cd66d1cde48ce00d8c35d23568b07733aa30f6be Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 14:45:52 +0200 Subject: [PATCH 22/36] make reglist simpler --- tier1/convar.cpp | 92 ++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 69 deletions(-) diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 741cb7d78..ff2b7a0bc 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -53,52 +53,38 @@ void UnRegisterCommand( ConCommandHandle& cmd ) } } -class ConCommandRegList; -static ConCommandRegList* s_pCommandRegList = nullptr; - class ConCommandRegList { public: + static ConCommandRegList* GetRegList() + { + static ConCommandRegList* list = new ConCommandRegList(); + return list; + } + static void RegisterAll() { if (!s_bConCommandsRegistered && g_pCVar) { s_bConCommandsRegistered = true; - ConCommandRegList* list = s_pCommandRegList; - while ( list != nullptr ) + ConCommandRegList* list = GetRegList(); + FOR_EACH_VEC( list->m_Vec, i ) { - FOR_EACH_VEC( list->m_Vec, i ) - { - RegisterCommand( list->m_Vec[i] ); - } - - ConCommandRegList *pNext = list->m_pNext; - delete list; - list = pNext; + RegisterCommand( list->m_Vec[i] ); } + delete list; } } private: friend void AddCommand( ConCommandCreation_t& cmd ); - void SetNextList( ConCommandRegList* list ) - { - m_pNext = list; - } - - int Count() const - { - return m_Vec.Count(); - } - void Add( const ConCommandCreation_t& cmd ) { m_Vec.AddToTail( cmd ); } - CUtlVectorFixed m_Vec; - ConCommandRegList* m_pNext = nullptr; + CUtlVector m_Vec; public: static bool s_bConCommandsRegistered; }; @@ -112,15 +98,7 @@ void AddCommand( ConCommandCreation_t& cmd ) return; } - if ( !s_pCommandRegList || s_pCommandRegList->Count() == 100 ) - { - ConCommandRegList* newList = new ConCommandRegList; - newList->SetNextList( s_pCommandRegList ); - - s_pCommandRegList = newList; - } - - s_pCommandRegList->Add( cmd ); + ConCommandRegList::GetRegList()->Add( cmd ); } void RegisterConVar( ConVarCreation_t& cvar ) @@ -143,13 +121,14 @@ void UnRegisterConVar( ConVarHandle& cvar ) } } -class ConVarRegList; -static ConVarRegList* s_pConVarRegList = nullptr; - class ConVarRegList { public: - ConVarRegList() {} + static ConVarRegList* GetRegList() + { + static ConVarRegList* list = new ConVarRegList(); + return list; + } static void RegisterAll() { @@ -157,41 +136,24 @@ class ConVarRegList { s_bConVarsRegistered = true; - ConVarRegList* list = s_pConVarRegList; - while ( list ) + ConVarRegList* list = GetRegList(); + FOR_EACH_VEC( list->m_Vec, i ) { - FOR_EACH_VEC( list->m_Vec, i ) - { - RegisterConVar( list->m_Vec[i] ); - } - - ConVarRegList *pNext = list->m_pNext; - delete list; - list = pNext; + RegisterConVar( list->m_Vec[i] ); } + delete list; } } private: friend void SetupConVar( ConVarCreation_t& cvar ); - void SetNextList( ConVarRegList* list ) - { - m_pNext = list; - } - - int Count() const - { - return m_Vec.Count(); - } - void Add( const ConVarCreation_t& cvar ) { m_Vec.AddToTail( cvar ); } - CUtlVectorFixed m_Vec; - ConVarRegList* m_pNext = nullptr; + CUtlVector m_Vec; public: static bool s_bConVarsRegistered; }; @@ -206,15 +168,7 @@ void SetupConVar( ConVarCreation_t& cvar ) return; } - if ( !s_pConVarRegList || s_pConVarRegList->Count() == 100 ) - { - ConVarRegList* newList = new ConVarRegList; - newList->SetNextList( s_pConVarRegList ); - - s_pConVarRegList = newList; - } - - s_pConVarRegList->Add( cvar ); + ConVarRegList::GetRegList()->Add( cvar ); } //----------------------------------------------------------------------------- From 99f37a8acbb59ce8c0653ce98b9e68a61235b3d3 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 14:48:32 +0200 Subject: [PATCH 23/36] Destroy ConCommandBase --- public/tier1/convar.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index abf433889..c7008921a 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -324,13 +324,6 @@ struct ConCommandCreation_t : CVarCreationBase_t }; static_assert(sizeof(ConCommandCreation_t) == 0x40, "ConCommandCreation_t is of the wrong size!"); -// TO-DO: Remove this... -class ConCommandBase -{ -public: - inline const char* GetName() { return "Please remove the ConCommandBase class..."; } -}; // For metamod compatibility only!!!! - class ConCommand { public: From 97a4d769c5be0767723a4f0aefebb36b0aa0f3a6 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 15:21:42 +0200 Subject: [PATCH 24/36] move some functions to baseconvardata --- public/icvar.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index c7f6908b9..a782eebfb 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -242,6 +242,19 @@ struct ConVarBaseData_t { } + inline const char* GetName( void ) const { return m_pszName; } + inline const char* GetDescription( void ) const { return m_pszHelpString; } + inline EConVarType GetType( void ) const { return m_eVarType; } + + inline int GetTimesChanges( void ) const { return m_iTimesChanged; } + + inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_nFlags ) ? true : false; } + inline void AddFlags( int64_t flags ) { m_nFlags |= flags; } + inline void RemoveFlags( int64_t flags ) { m_nFlags &= ~flags; } + inline int64_t GetFlags( void ) const { return m_nFlags; } + + inline int GetCallbackIndex( void ) const { return m_iCallbackIndex; } +protected: const char* m_pszName; void* m_defaultValue; @@ -286,10 +299,6 @@ friend class ConVar; delete m_eVarType; } - inline const char* GetName( ) const { return m_pszName; } - inline const char* GetDescription( ) const { return m_pszHelpString; } - inline EConVarType GetType( ) const { return m_eVarType; } - inline const T& GetDefaultValue( ) const { return *reinterpret_cast(m_defaultValue); } inline const T& GetMinValue( ) const { return *reinterpret_cast(m_minValue); } inline const T& GetMaxValue( ) const { return *reinterpret_cast(m_maxValue); } @@ -301,11 +310,6 @@ friend class ConVar; inline const T& GetValue( int index = 0 ) const { return m_value[index]; } inline void SetValue(const T& value, int index = 0) { m_value[index] = value; } - inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_nFlags ) ? true : false; } - inline void AddFlags( int64_t flags ) { m_nFlags |= flags; } - inline void RemoveFlags( int64_t flags ) { m_nFlags &= ~flags; } - inline int64_t GetFlags( void ) const { return m_nFlags; } - T m_value[MAX_SPLITSCREEN_CLIENTS]; }; From 0808d7868e46c32f826028953fb3fc88f13381d7 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 15:22:13 +0200 Subject: [PATCH 25/36] put cvar values into its own struct --- public/tier1/convar.h | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index c7008921a..6f6b38bb6 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -354,12 +354,6 @@ struct ConVarSetup_t { ConVarSetup_t() : m_unknown1(0), - m_bHasDefault(false), - m_bHasMin(false), - m_bHasMax(false), - m_defaultValue(), - m_minValue(), - m_maxValue(), m_fnCallBack(nullptr), m_eVarType(EConVarType_Invalid), m_unknown2(0), @@ -368,13 +362,22 @@ struct ConVarSetup_t int32_t m_unknown1; // 0x0 - bool m_bHasDefault; // 0x4 - bool m_bHasMin; // 0x5 - bool m_bHasMax; // 0x6 + struct ConVarValueInfo_t + { + ConVarValueInfo_t() : + m_bHasDefault(false), + m_bHasMin(false), + m_bHasMax(false) + {} + + bool m_bHasDefault; // 0x4 + bool m_bHasMin; // 0x5 + bool m_bHasMax; // 0x6 - CVValue_t m_defaultValue; // 0x7 - CVValue_t m_minValue; // 0x17 - CVValue_t m_maxValue; // 0x27 + CVValue_t m_defaultValue; // 0x7 + CVValue_t m_minValue; // 0x17 + CVValue_t m_maxValue; // 0x27 + } m_valueInfo; char pad; // 0x37 @@ -429,8 +432,8 @@ class ConVar : public BaseConVar this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); ConVarSetup_t setup; - setup.m_bHasDefault = true; - setup.m_defaultValue = value; + setup.m_valueInfo.m_bHasDefault = true; + setup.m_valueInfo.m_defaultValue = value; setup.m_eVarType = TranslateConVarType(); setup.m_fnCallBack = reinterpret_cast(cb); @@ -442,13 +445,13 @@ class ConVar : public BaseConVar this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); ConVarSetup_t setup; - setup.m_bHasDefault = true; - setup.m_defaultValue = value; + setup.m_valueInfo.m_bHasDefault = true; + setup.m_valueInfo.m_defaultValue = value; - setup.m_bHasMin = min; - setup.m_bHasMax = max; - setup.m_minValue = minValue; - setup.m_maxValue = maxValue; + setup.m_valueInfo.m_bHasMin = min; + setup.m_valueInfo.m_bHasMax = max; + setup.m_valueInfo.m_minValue = minValue; + setup.m_valueInfo.m_maxValue = maxValue; setup.m_eVarType = TranslateConVarType(); setup.m_fnCallBack = reinterpret_cast(cb); From b51e4e61b03ca34d3d39d9a817f0b558fc074e87 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 16:17:41 +0200 Subject: [PATCH 26/36] revise struct --- public/tier1/convar.h | 63 ++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 6f6b38bb6..6933bda25 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -349,19 +349,16 @@ class ConCommand }; using FnGenericChangeCallback_t = void(*)(BaseConVar* ref, CSplitScreenSlot nSlot, CVValue_t* pNewValue, CVValue_t* pOldValue); -#pragma pack(push,1) -struct ConVarSetup_t -{ - ConVarSetup_t() : - m_unknown1(0), - m_fnCallBack(nullptr), - m_eVarType(EConVarType_Invalid), - m_unknown2(0), - m_unknown3(0) + +struct ConVarCreation_t : CVarCreationBase_t { + ConVarCreation_t() : + m_pHandle(nullptr), + m_pConVarData(nullptr) {} - int32_t m_unknown1; // 0x0 + int32_t m_unknown1; // 0x18 + #pragma pack(push,1) struct ConVarValueInfo_t { ConVarValueInfo_t() : @@ -370,38 +367,22 @@ struct ConVarSetup_t m_bHasMax(false) {} - bool m_bHasDefault; // 0x4 - bool m_bHasMin; // 0x5 - bool m_bHasMax; // 0x6 - - CVValue_t m_defaultValue; // 0x7 - CVValue_t m_minValue; // 0x17 - CVValue_t m_maxValue; // 0x27 - } m_valueInfo; - - char pad; // 0x37 - - FnGenericChangeCallback_t m_fnCallBack; // 0x38 - EConVarType m_eVarType; // 0x40 + bool m_bHasDefault; // 0x22 + bool m_bHasMin; // 0x23 + bool m_bHasMax; // 0x24 - int32_t m_unknown2; // 0x42 - int16_t m_unknown3; // 0x46 -}; -#pragma pack(pop) -static_assert(sizeof(ConVarSetup_t) == 0x48, "ConVarSetup_t is of the wrong size!"); -static_assert(sizeof(ConVarSetup_t) % 8 == 0x0, "ConVarSetup_t isn't 8 bytes aligned!"); + CVValue_t m_defaultValue; // 0x25 + CVValue_t m_minValue; // 0x35 + CVValue_t m_maxValue; // 0x45 + } m_valueInfo; // 0x22 + #pragma pack(pop) -struct ConVarCreation_t : CVarCreationBase_t { - ConVarCreation_t() : - m_pHandle(nullptr), - m_pConVarData(nullptr) - {} - ConVarSetup_t m_cvarSetup; // 0x18 + FnGenericChangeCallback_t m_fnCallBack; // 0x56 + EConVarType m_eVarType; // 0x58 ConVarHandle* m_pHandle; // 0x60 ConVarBaseData_t** m_pConVarData; // 0x68 }; - static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); static_assert(sizeof(ConVarCreation_t) % 8 == 0x0, "ConVarCreation_t isn't 8 bytes aligned!"); static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); @@ -431,7 +412,7 @@ class ConVar : public BaseConVar { this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); - ConVarSetup_t setup; + ConVarCreation_t setup; setup.m_valueInfo.m_bHasDefault = true; setup.m_valueInfo.m_defaultValue = value; setup.m_eVarType = TranslateConVarType(); @@ -444,7 +425,7 @@ class ConVar : public BaseConVar { this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); - ConVarSetup_t setup; + ConVarCreation_t setup; setup.m_valueInfo.m_bHasDefault = true; setup.m_valueInfo.m_defaultValue = value; @@ -503,7 +484,7 @@ class ConVar : public BaseConVar this->m_Handle = defaultHandle; } - void Register(const char* name, int32_t flags, const char* description, const ConVarSetup_t& setup) + void Register(const char* name, int32_t flags, const char* description, ConVarCreation_t& cvar) { this->m_ConVarData = ConVar_Invalid(); this->m_Handle.Invalidate(); @@ -521,14 +502,10 @@ class ConVar : public BaseConVar flags |= FCVAR_DEVELOPMENTONLY; } - ConVarCreation_t cvar; - cvar.m_pszName = name; cvar.m_pszHelpString = description; cvar.m_nFlags = flags; - cvar.m_cvarSetup = setup; - cvar.m_pHandle = &this->m_Handle; cvar.m_pConVarData = (ConVarBaseData_t**)&this->m_ConVarData; From 66e3e75f049d2da1320e14baa67bc7bb0f21112e Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 16:20:14 +0200 Subject: [PATCH 27/36] remove padding --- public/tier1/convar.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 6933bda25..833495443 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -355,9 +355,7 @@ struct ConVarCreation_t : CVarCreationBase_t { m_pHandle(nullptr), m_pConVarData(nullptr) {} - - int32_t m_unknown1; // 0x18 - + #pragma pack(push,1) struct ConVarValueInfo_t { From 650a4c3fb0224a28eac9676cf06295157c89b951 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 16:31:23 +0200 Subject: [PATCH 28/36] add back unknown --- public/tier1/convar.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 833495443..f7c79b786 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -355,6 +355,8 @@ struct ConVarCreation_t : CVarCreationBase_t { m_pHandle(nullptr), m_pConVarData(nullptr) {} + + int32_t m_unknown1; #pragma pack(push,1) struct ConVarValueInfo_t From 86ff7cd2b45ee5f6c9eeeb867608c50b2ff9bfca Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 23:07:32 +0200 Subject: [PATCH 29/36] finish templating --- public/icvar.h | 201 ++++++++++++++++++++++++++++++++++++------ public/tier1/convar.h | 81 +++++++++++++---- 2 files changed, 239 insertions(+), 43 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index a782eebfb..2e783e930 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -37,7 +37,7 @@ union CVValue_t CVValue_t& operator=(CVValue_t other) { memcpy(this, &other, sizeof(*this)); return *this; } template - inline CVValue_t& operator=(T other); + inline CVValue_t& operator=(const T& other); inline operator bool() const { return m_bValue; } inline operator int16_t() const { return m_i16Value; } @@ -74,24 +74,28 @@ union CVValue_t static_assert(sizeof(float) == sizeof(int32_t), "Wrong float type size for ConVar!"); static_assert(sizeof(double) == sizeof(int64_t), "Wrong double type size for ConVar!"); -template<> inline CVValue_t& CVValue_t::operator=( const bool other ) { m_bValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const int16_t other ) { m_i16Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const uint16_t other ) { m_u16Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const int32_t other ) { m_i32Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const uint32_t other ) { m_u32Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const int64_t other ) { m_i64Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const uint64_t other ) { m_u64Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const float other ) { m_flValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const double other ) { m_dbValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const char* other ) { m_szValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Color& other ) { m_clrValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Vector2D& other ) { m_vec2Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Vector& other ) { m_vec3Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Vector4D& other ) { m_vec4Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const QAngle& other ) { m_angValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const bool& other ) { m_bValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const int16_t& other ) { m_i16Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const uint16_t& other ) { m_u16Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const int32_t& other ) { m_i32Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const uint32_t& other ) { m_u32Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const int64_t& other ) { m_i64Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const uint64_t& other ) { m_u64Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const float& other ) { m_flValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const double& other ) { m_dbValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const char*const& other ) { m_szValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Color& other ) { m_clrValue = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Vector2D& other ) { m_vec2Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Vector& other ) { m_vec3Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const Vector4D& other ) { m_vec4Value = other; return *this; } +template<> inline CVValue_t& CVValue_t::operator=( const QAngle& other ) { m_angValue = other; return *this; } struct CSplitScreenSlot { + CSplitScreenSlot() : + m_Data(0) + {} + CSplitScreenSlot( int index ) { m_Data = index; @@ -101,6 +105,11 @@ struct CSplitScreenSlot { return m_Data; } + + operator int() const + { + return m_Data; + } int m_Data; }; @@ -153,7 +162,7 @@ class ConCommandHandle m_handleIndex = 0x0; } - uint16_t GetConVarIndex() const { return m_concommandIndex; } + uint16_t GetConCommandIndex() const { return m_concommandIndex; } uint32_t GetIndex() const { return m_handleIndex; } private: @@ -166,7 +175,7 @@ static const ConCommandHandle INVALID_CONCOMMAND_HANDLE = ConCommandHandle(); //----------------------------------------------------------------------------- // Purpose: Internal structure of ConVar objects //----------------------------------------------------------------------------- -enum EConVarType : short +enum EConVarType : int16_t { EConVarType_Invalid = -1, EConVarType_Bool, @@ -246,6 +255,10 @@ struct ConVarBaseData_t inline const char* GetDescription( void ) const { return m_pszHelpString; } inline EConVarType GetType( void ) const { return m_eVarType; } + inline bool HasDefaultValue( ) const { return m_defaultValue != nullptr; } + inline bool HasMinValue( ) const { return m_minValue != nullptr; } + inline bool HasMaxValue( ) const { return m_maxValue != nullptr; } + inline int GetTimesChanges( void ) const { return m_iTimesChanged; } inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_nFlags ) ? true : false; } @@ -255,6 +268,12 @@ struct ConVarBaseData_t inline int GetCallbackIndex( void ) const { return m_iCallbackIndex; } protected: + template + static inline void ValueToString( const T& val, char* dst, size_t length ); + + template + static T ValueFromString( const char* val ); + const char* m_pszName; void* m_defaultValue; @@ -279,12 +298,48 @@ struct ConVarBaseData_t int m_nUnknownAllocFlags; }; +template<> inline void ConVarBaseData_t::ValueToString( const bool& val, char* dst, size_t length ) +{ + const char* src = ( val ) ? "true" : "false"; + memcpy( dst, src, length ); +} +template<> inline void ConVarBaseData_t::ValueToString( const uint16_t& val, char* dst, size_t length ) { snprintf( dst, length, "%u", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const int16_t& val, char* dst, size_t length ) { snprintf( dst, length, "%d", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const uint32_t& val, char* dst, size_t length ) { snprintf( dst, length, "%u", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const int32_t& val, char* dst, size_t length ) { snprintf( dst, length, "%d", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const uint64_t& val, char* dst, size_t length ) { snprintf( dst, length, "%lu", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const int64_t& val, char* dst, size_t length ) { snprintf( dst, length, "%ld", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const float& val, char* dst, size_t length ) { snprintf( dst, length, "%f", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const double& val, char* dst, size_t length ) { snprintf( dst, length, "%lf", val ); } +template<> inline void ConVarBaseData_t::ValueToString( const char*const& val, char* dst, size_t length ) { memcpy( dst, val, length ); } +template<> inline void ConVarBaseData_t::ValueToString( const Color& val, char* dst, size_t length ) { snprintf( dst, length, "%d %d %d %d", val.r(), val.g(), val.b(), val.a() ); } +template<> inline void ConVarBaseData_t::ValueToString( const Vector2D& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f", val.x, val.y ); } +template<> inline void ConVarBaseData_t::ValueToString( const Vector& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f", val.x, val.y, val.z ); } +template<> inline void ConVarBaseData_t::ValueToString( const Vector4D& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f %f", val.x, val.y, val.z, val.w ); } +template<> inline void ConVarBaseData_t::ValueToString( const QAngle& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f", val.x, val.y, val.z ); } + +template<> inline bool ConVarBaseData_t::ValueFromString( const char* val ) { if (strcmp(val, "true") == 0 || strcmp(val, "1") == 0) { return true; } return false; } +template<> inline uint16_t ConVarBaseData_t::ValueFromString( const char* val ) { unsigned int ret; sscanf(val, "%u", &ret); return ret; } +template<> inline int16_t ConVarBaseData_t::ValueFromString( const char* val ) { int ret; sscanf(val, "%d", &ret); return ret; } +template<> inline uint32_t ConVarBaseData_t::ValueFromString( const char* val ) { uint32_t ret; sscanf(val, "%u", &ret); return ret; } +template<> inline int32_t ConVarBaseData_t::ValueFromString( const char* val ) { int32_t ret; sscanf(val, "%d", &ret); return ret; } +template<> inline uint64_t ConVarBaseData_t::ValueFromString( const char* val ) { uint64_t ret; sscanf(val, "%lu", &ret); return ret; } +template<> inline int64_t ConVarBaseData_t::ValueFromString( const char* val ) { int64_t ret; sscanf(val, "%ld", &ret); return ret; } +template<> inline float ConVarBaseData_t::ValueFromString( const char* val ) { float ret; sscanf(val, "%f", &ret); return ret; } +template<> inline double ConVarBaseData_t::ValueFromString( const char* val ) { double ret; sscanf(val, "%lf", &ret); return ret; } +template<> inline const char* ConVarBaseData_t::ValueFromString( const char* val ) { return val; } +template<> inline Color ConVarBaseData_t::ValueFromString( const char* val ) { int r, g, b, a; sscanf(val, "%d %d %d %d", &r, &g, &b, &a); return Color(r, g, b, a); } +template<> inline Vector2D ConVarBaseData_t::ValueFromString( const char* val ) { float x, y; sscanf(val, "%f %f", &x, &y); return Vector2D(x, y); } +template<> inline Vector ConVarBaseData_t::ValueFromString( const char* val ) { float x, y, z; sscanf(val, "%f %f %f", &x, &y, &z); return Vector(x, y, z); } +template<> inline Vector4D ConVarBaseData_t::ValueFromString( const char* val ) { float x, y, z, w; sscanf(val, "%f %f %f %f", &x, &y, &z, &w); return Vector4D(x, y, z, w); } +template<> inline QAngle ConVarBaseData_t::ValueFromString( const char* val ) { float x, y, z; sscanf(val, "%f %f %f", &x, &y, &z); return QAngle(x, y, z); } + template struct ConVarData_t : ConVarBaseData_t { public: friend class ConVar; - ConVarData_t() + constexpr ConVarData_t() { m_defaultValue = new T(); m_minValue = new T(); @@ -303,16 +358,110 @@ friend class ConVar; inline const T& GetMinValue( ) const { return *reinterpret_cast(m_minValue); } inline const T& GetMaxValue( ) const { return *reinterpret_cast(m_maxValue); } - inline void SetDefaultValue(const T& value) { *reinterpret_cast(m_defaultValue) = value; } - inline void SetMinValue(const T& value) { *reinterpret_cast(m_minValue) = value; } - inline void SetMaxValue(const T& value) { *reinterpret_cast(m_maxValue) = value; } + inline void SetDefaultValue(const T& value) + { + if (!m_defaultValue) + { + m_defaultValue = new T(); + } + *reinterpret_cast(m_defaultValue) = value; + } + inline void SetMinValue(const T& value) + { + if (!m_minValue) + { + m_minValue = new T(); + } + *reinterpret_cast(m_minValue) = value; + } + inline void SetMaxValue(const T& value) + { + if (!m_maxValue) + { + m_maxValue = new T(); + } + *reinterpret_cast(m_maxValue) = value; + } + + inline void RemoveDefaultValue( ) + { + if (m_defaultValue) + { + delete reinterpret_cast(m_defaultValue); + } + m_defaultValue = nullptr; + } + inline void RemoveMinValue( ) + { + if (m_minValue) + { + delete reinterpret_cast(m_minValue); + } + m_minValue = nullptr; + } + inline void RemoveMaxValue( ) + { + if (m_maxValue) + { + delete reinterpret_cast(m_maxValue); + } + m_maxValue = nullptr; + } + + inline const T& Clamp(const T& value) const + { + if (HasMinValue() && value < GetMinValue()) + { + return GetMinValue(); + } + if (HasMaxValue() && value > GetMaxValue()) + { + return GetMaxValue(); + } + return value; + } + + inline const T& GetValue( const CSplitScreenSlot& index = 0 ) const { return m_value[index]; } + inline void SetValue(const T& value, const CSplitScreenSlot& index = 0) { m_value[index] = value; } + + inline void GetStringValue( char* dst, size_t len, const CSplitScreenSlot& index = 0 ) const { ValueToString( GetValue( index ), dst, len ); } + + inline void GetStringDefaultValue( char* dst, size_t len ) const { ValueToString( GetDefaultValue( ), dst, len ); } + inline void GetStringMinValue( char* dst, size_t len ) const { ValueToString( GetMaxValue( ), dst, len ); } + inline void GetStringMaxValue( char* dst, size_t len ) const { ValueToString( GetValue( index ), dst, len ); } + + inline void SetStringValue( const char* src, const CSplitScreenSlot& index = 0 ) const { SetValue( ValueFromString( src ), index ); } - inline const T& GetValue( int index = 0 ) const { return m_value[index]; } - inline void SetValue(const T& value, int index = 0) { m_value[index] = value; } + inline void SetStringDefaultValue( const char* src ) const { SetDefaultValue( ValueFromString( src ) ); } + inline void SetStringMinValue( const char* src ) const { SetMinValue( ValueFromString( src ) ); } + inline void SetStringMaxValue( const char* src ) const { SetMaxValue( ValueFromString( src ) ); } + +protected: + static inline void ValueToString( const T& value, char* dst, size_t length ) { ConVarBaseData_t::ValueToString( value, dst, length ); }; + + static T ValueFromString( const char* val ) { return ConVarBaseData_t::ValueFromString( val ); }; T m_value[MAX_SPLITSCREEN_CLIENTS]; }; +// Special case for string handling +template<> inline void ConVarData_t::SetValue(const char*const& value, const CSplitScreenSlot& index) +{ + char* data = new char[256]; + memcpy(data, value, 256); + + delete[] m_value[index]; + m_value[index] = data; +} + +// For some types it makes no sense to clamp +template<> inline const char*const& ConVarData_t::Clamp(const char*const& value) const { return value; } +template<> inline const Color& ConVarData_t::Clamp(const Color& value) const { return value; } +template<> inline const Vector2D& ConVarData_t::Clamp(const Vector2D& value) const { return value; } +template<> inline const Vector& ConVarData_t::Clamp(const Vector& value) const { return value; } +template<> inline const Vector4D& ConVarData_t::Clamp(const Vector4D& value) const { return value; } +template<> inline const QAngle& ConVarData_t::Clamp(const QAngle& value) const { return value; } + //----------------------------------------------------------------------------- // Purpose: DLL interface to ConVars/ConCommands //----------------------------------------------------------------------------- @@ -323,7 +472,7 @@ abstract_class ICvar : public IAppSystem virtual ConVarHandle FindConVar( const char *name, bool bAllowDeveloper = false ) = 0; virtual ConVarHandle FindFirstConVar() = 0; virtual ConVarHandle FindNextConVar( ConVarHandle prev ) = 0; - virtual void SetConVarValue( ConVarHandle cvarid, CSplitScreenSlot nSlot, CVValue_t *pNewValue, CVValue_t *pOldValue ) = 0; + virtual void CallChangeCallback( ConVarHandle cvarid, const CSplitScreenSlot nSlot, const CVValue_t* pNewValue, const CVValue_t* pOldValue ) = 0; virtual ConCommandHandle FindCommand( const char *name ) = 0; virtual ConCommandHandle FindFirstCommand() = 0; @@ -333,7 +482,7 @@ abstract_class ICvar : public IAppSystem // Install a global change callback (to be called when any convar changes) virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; virtual void RemoveGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; - virtual void CallGlobalChangeCallbacks( BaseConVar* ref, CSplitScreenSlot nSlot, const char *pOldString, float flOldValue ) = 0; + virtual void CallGlobalChangeCallbacks( BaseConVar* ref, CSplitScreenSlot nSlot, const char* newValue, char* oldValue ) = 0; // Reverts cvars which contain a specific flag virtual void RevertFlaggedConVars( int nFlag ) = 0; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index f7c79b786..c94ebbe38 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -25,6 +25,7 @@ #include "playerslot.h" #include +#include #ifdef _WIN32 #define FORCEINLINE_CVAR FORCEINLINE @@ -355,8 +356,6 @@ struct ConVarCreation_t : CVarCreationBase_t { m_pHandle(nullptr), m_pConVarData(nullptr) {} - - int32_t m_unknown1; #pragma pack(push,1) struct ConVarValueInfo_t @@ -367,6 +366,8 @@ struct ConVarCreation_t : CVarCreationBase_t { m_bHasMax(false) {} + int32_t m_unknown1; // 0x18 + bool m_bHasDefault; // 0x22 bool m_bHasMin; // 0x23 bool m_bHasMax; // 0x24 @@ -390,7 +391,7 @@ static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); extern void* invalid_convar[EConVarType_MAX + 1]; template -ConVarData_t* ConVar_Invalid() +ConVarData_t* GetInvalidConVar() { return (ConVarData_t*)&invalid_convar[TranslateConVarType()]; } @@ -406,9 +407,9 @@ template class ConVar : public BaseConVar { public: - using FnChangeCallback_t = void(*)(ConVar* ref, CSplitScreenSlot nSlot, T* pNewValue, T* pOldValue); + using FnChangeCallback_t = void(*)(ConVar* ref, const CSplitScreenSlot nSlot, const T* pNewValue, const T* pOldValue); - ConVar(const char* name, int32_t flags, const char* description, T value, FnChangeCallback_t cb = nullptr) + ConVar(const char* name, int32_t flags, const char* description, const T& value, FnChangeCallback_t cb = nullptr) { this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); @@ -421,7 +422,7 @@ class ConVar : public BaseConVar this->Register(name, flags &~ FCVAR_DEVELOPMENTONLY, description, setup); } - ConVar(const char* name, int32_t flags, const char* description, T value, bool min, T minValue, bool max, T maxValue, FnChangeCallback_t cb = nullptr) + ConVar(const char* name, int32_t flags, const char* description, const T& value, bool min, const T& minValue, bool max, const T& maxValue, FnChangeCallback_t cb = nullptr) { this->Init(INVALID_CONVAR_HANDLE, TranslateConVarType()); @@ -449,16 +450,46 @@ class ConVar : public BaseConVar inline const char* GetDescription( ) const { return m_ConVarData->GetDescription( ); } inline EConVarType GetType( ) const { return m_ConVarData->GetType( ); } - inline CVValue_t* GetDefaultValue( ) const { return m_ConVarData->GetDefaultValue( ); } - inline CVValue_t* GetMinValue( ) const { return m_ConVarData->GetMinValue( ); } - inline CVValue_t* GetMaxValue( ) const { return m_ConVarData->GetMaxValue( ); } + inline bool HasDefaultValue( ) const { return m_ConVarData->HasDefaultValue( ); } + inline bool HasMinValue( ) const { return m_ConVarData->HasMinValue( ); } + inline bool HasMaxValue( ) const { return m_ConVarData->HasMaxValue( ); } + + inline const T& GetDefaultValue( ) const { return m_ConVarData->GetDefaultValue( ); } + inline const T& GetMinValue( ) const { return m_ConVarData->GetMinValue( ); } + inline const T& GetMaxValue( ) const { return m_ConVarData->GetMaxValue( ); } + + inline void SetDefaultValue( const T& value ) { m_ConVarData->SetDefaultValue( value ); } + inline void SetMinValue( const T& value ) { m_ConVarData->SetMinValue( value ); } + inline void SetMaxValue( const T& value ) { m_ConVarData->SetMaxValue( value ); } + + inline void RemoveDefaultValue( ) { m_ConVarData->RemoveDefaultValue( ); } + inline void RemoveMinValue( ) { m_ConVarData->RemoveMinValue( ); } + inline void RemoveMaxValue( ) { m_ConVarData->RemoveMaxValue( ); } - inline void SetDefaultValue(const T& value) { m_ConVarData->SetDefaultValue( value ); } - inline void SetMinValue(const T& value) { m_ConVarData->SetMinValue( value ); } - inline void SetMaxValue(const T& value) { m_ConVarData->SetMaxValue( value ); } + inline const T& Clamp(const T& value) const { return m_ConVarData->Clamp( value ); } - inline const T& GetValue( int index = 0 ) const { return m_ConVarData->GetValue( index ); } - inline void SetValue(const T& value, int index = 0) { m_ConVarData->SetValue( value, index ); } + inline const T& GetValue( const CSplitScreenSlot& index = CSplitScreenSlot() ) const { return m_ConVarData->GetValue( index ); } + inline void SetValue( const T& val, const CSplitScreenSlot& index = CSplitScreenSlot() ) + { + auto newValue = this->Clamp( val ); + + char szNewValue[256], szOldValue[256]; + ConVarData_t::ValueToString( newValue, szNewValue, sizeof(szNewValue) ); + m_ConVarData->GetStringValue( szOldValue, sizeof(szOldValue), index ); + + // Deep copy + T oldValue = this->GetValue( ); + m_ConVarData->SetValue( newValue, index ); + + g_pCVar->CallChangeCallback( this->m_Handle, index, (const CVValue_t*)&newValue, (const CVValue_t*)&oldValue ); + g_pCVar->CallGlobalChangeCallbacks( this, index, szNewValue, szOldValue ); + } + + inline void GetStringValue( char* dst, size_t len, const CSplitScreenSlot& index = 0 ) const { m_ConVarData->GetStringValue( dst, len, index ); } + + inline void GetStringDefaultValue( char* dst, size_t len ) const { m_ConVarData->GetStringDefaultValue( dst, len ); } + inline void GetStringMinValue( char* dst, size_t len ) const { m_ConVarData->GetStringMinValue( dst, len ); } + inline void GetStringMaxValue( char* dst, size_t len ) const { m_ConVarData->GetStringMaxValue( dst, len ); } inline bool IsFlagSet( int64_t flag ) const { return m_ConVarData->IsFlagSet( flag ); } inline void AddFlags( int64_t flags ) { m_ConVarData->AddFlags( flags ); } @@ -473,10 +504,11 @@ class ConVar : public BaseConVar if (g_pCVar) { - this->m_ConVarData = g_pCVar->GetConVar(defaultHandle)->Cast(); + auto cvar = g_pCVar->GetConVar(defaultHandle); + this->m_ConVarData = (cvar) ? g_pCVar->GetConVar(defaultHandle)->Cast() : nullptr; if (!this->m_ConVarData) { - this->m_ConVarData = ConVar_Invalid(); + this->m_ConVarData = GetInvalidConVar(); } // technically this //result = *(char ***)(sub_10B7760((unsigned int)a3) + 80); @@ -486,7 +518,7 @@ class ConVar : public BaseConVar void Register(const char* name, int32_t flags, const char* description, ConVarCreation_t& cvar) { - this->m_ConVarData = ConVar_Invalid(); + this->m_ConVarData = GetInvalidConVar(); this->m_Handle.Invalidate(); if (!CommandLine()->HasParm("-tools") @@ -519,6 +551,21 @@ class ConVar : public BaseConVar static_assert(sizeof(ConVar) == 0x10, "ConVar is of the wrong size!"); static_assert(sizeof(ConVar) == sizeof(ConVar), "Templated ConVar size varies!"); +// Special case for string +template<> inline void ConVar::SetValue( const char*const& val, const CSplitScreenSlot& index ) +{ + auto newValue = this->Clamp( val ); + + char szNewValue[256], szOldValue[256]; + ConVarData_t::ValueToString( newValue, szNewValue, sizeof(szNewValue) ); + m_ConVarData->GetStringValue( szOldValue, sizeof(szOldValue), index ); + + m_ConVarData->SetValue( newValue, index ); + + g_pCVar->CallChangeCallback( this->m_Handle, index, (const CVValue_t*)&newValue, (const CVValue_t*)&szOldValue ); + g_pCVar->CallGlobalChangeCallbacks( this, index, szNewValue, szOldValue ); +} + //----------------------------------------------------------------------------- #ifdef CONVAR_WORK_FINISHED From 05efa99274f4b45722c44f6dd637b698f6e057e1 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 8 Oct 2023 23:10:11 +0200 Subject: [PATCH 30/36] fix wrong ret value --- public/icvar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/icvar.h b/public/icvar.h index 2e783e930..d78bb8de9 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -162,7 +162,7 @@ class ConCommandHandle m_handleIndex = 0x0; } - uint16_t GetConCommandIndex() const { return m_concommandIndex; } + uint32_t GetConCommandIndex() const { return m_concommandIndex; } uint32_t GetIndex() const { return m_handleIndex; } private: From c9a88ac5ed1dc5a2c5884bbd79071a30797a036f Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Mon, 9 Oct 2023 19:12:08 +0200 Subject: [PATCH 31/36] review changes --- public/icvar.h | 127 +++++++++++++++------------------- public/tier1/convar.h | 156 +++++++++++++++++++++++++----------------- tier1/convar.cpp | 19 ----- 3 files changed, 149 insertions(+), 153 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index d78bb8de9..6ed53b7c3 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -16,7 +16,7 @@ #include "mathlib/vector4d.h" #include -class BaseConVar {}; +class BaseConVar; class ConCommand; class CCommand; class CCommandContext; @@ -32,10 +32,6 @@ class ConVar; union CVValue_t { - CVValue_t() { memset(this, 0, sizeof(*this)); } - CVValue_t(CVValue_t const& cp) { memcpy(this, &cp, sizeof(*this)); }; - CVValue_t& operator=(CVValue_t other) { memcpy(this, &other, sizeof(*this)); return *this; } - template inline CVValue_t& operator=(const T& other); @@ -74,22 +70,6 @@ union CVValue_t static_assert(sizeof(float) == sizeof(int32_t), "Wrong float type size for ConVar!"); static_assert(sizeof(double) == sizeof(int64_t), "Wrong double type size for ConVar!"); -template<> inline CVValue_t& CVValue_t::operator=( const bool& other ) { m_bValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const int16_t& other ) { m_i16Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const uint16_t& other ) { m_u16Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const int32_t& other ) { m_i32Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const uint32_t& other ) { m_u32Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const int64_t& other ) { m_i64Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const uint64_t& other ) { m_u64Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const float& other ) { m_flValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const double& other ) { m_dbValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const char*const& other ) { m_szValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Color& other ) { m_clrValue = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Vector2D& other ) { m_vec2Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Vector& other ) { m_vec3Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const Vector4D& other ) { m_vec4Value = other; return *this; } -template<> inline CVValue_t& CVValue_t::operator=( const QAngle& other ) { m_angValue = other; return *this; } - struct CSplitScreenSlot { CSplitScreenSlot() : @@ -217,31 +197,32 @@ template<> constexpr EConVarType TranslateConVarType( void ) { return EC template<> constexpr EConVarType TranslateConVarType( void ) { return EConVarType_Invalid; } template -struct ConVarData_t; +class CConVarData; -struct ConVarBaseData_t +class CConVarBaseData { +public: template - inline const ConVarData_t* Cast() const + inline const CConVarData* Cast() const { if (this->m_eVarType == TranslateConVarType()) { - return reinterpret_cast*>(this); + return reinterpret_cast*>(this); } return nullptr; } template - inline ConVarData_t* Cast() + inline CConVarData* Cast() { if (this->m_eVarType == TranslateConVarType()) { - return reinterpret_cast*>(this); + return reinterpret_cast*>(this); } return nullptr; } - ConVarBaseData_t() : + CConVarBaseData() : m_pszName(""), m_defaultValue(nullptr), m_minValue(nullptr), @@ -298,48 +279,48 @@ struct ConVarBaseData_t int m_nUnknownAllocFlags; }; -template<> inline void ConVarBaseData_t::ValueToString( const bool& val, char* dst, size_t length ) +template<> inline void CConVarBaseData::ValueToString( const bool& val, char* dst, size_t length ) { const char* src = ( val ) ? "true" : "false"; memcpy( dst, src, length ); } -template<> inline void ConVarBaseData_t::ValueToString( const uint16_t& val, char* dst, size_t length ) { snprintf( dst, length, "%u", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const int16_t& val, char* dst, size_t length ) { snprintf( dst, length, "%d", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const uint32_t& val, char* dst, size_t length ) { snprintf( dst, length, "%u", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const int32_t& val, char* dst, size_t length ) { snprintf( dst, length, "%d", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const uint64_t& val, char* dst, size_t length ) { snprintf( dst, length, "%lu", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const int64_t& val, char* dst, size_t length ) { snprintf( dst, length, "%ld", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const float& val, char* dst, size_t length ) { snprintf( dst, length, "%f", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const double& val, char* dst, size_t length ) { snprintf( dst, length, "%lf", val ); } -template<> inline void ConVarBaseData_t::ValueToString( const char*const& val, char* dst, size_t length ) { memcpy( dst, val, length ); } -template<> inline void ConVarBaseData_t::ValueToString( const Color& val, char* dst, size_t length ) { snprintf( dst, length, "%d %d %d %d", val.r(), val.g(), val.b(), val.a() ); } -template<> inline void ConVarBaseData_t::ValueToString( const Vector2D& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f", val.x, val.y ); } -template<> inline void ConVarBaseData_t::ValueToString( const Vector& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f", val.x, val.y, val.z ); } -template<> inline void ConVarBaseData_t::ValueToString( const Vector4D& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f %f", val.x, val.y, val.z, val.w ); } -template<> inline void ConVarBaseData_t::ValueToString( const QAngle& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f", val.x, val.y, val.z ); } - -template<> inline bool ConVarBaseData_t::ValueFromString( const char* val ) { if (strcmp(val, "true") == 0 || strcmp(val, "1") == 0) { return true; } return false; } -template<> inline uint16_t ConVarBaseData_t::ValueFromString( const char* val ) { unsigned int ret; sscanf(val, "%u", &ret); return ret; } -template<> inline int16_t ConVarBaseData_t::ValueFromString( const char* val ) { int ret; sscanf(val, "%d", &ret); return ret; } -template<> inline uint32_t ConVarBaseData_t::ValueFromString( const char* val ) { uint32_t ret; sscanf(val, "%u", &ret); return ret; } -template<> inline int32_t ConVarBaseData_t::ValueFromString( const char* val ) { int32_t ret; sscanf(val, "%d", &ret); return ret; } -template<> inline uint64_t ConVarBaseData_t::ValueFromString( const char* val ) { uint64_t ret; sscanf(val, "%lu", &ret); return ret; } -template<> inline int64_t ConVarBaseData_t::ValueFromString( const char* val ) { int64_t ret; sscanf(val, "%ld", &ret); return ret; } -template<> inline float ConVarBaseData_t::ValueFromString( const char* val ) { float ret; sscanf(val, "%f", &ret); return ret; } -template<> inline double ConVarBaseData_t::ValueFromString( const char* val ) { double ret; sscanf(val, "%lf", &ret); return ret; } -template<> inline const char* ConVarBaseData_t::ValueFromString( const char* val ) { return val; } -template<> inline Color ConVarBaseData_t::ValueFromString( const char* val ) { int r, g, b, a; sscanf(val, "%d %d %d %d", &r, &g, &b, &a); return Color(r, g, b, a); } -template<> inline Vector2D ConVarBaseData_t::ValueFromString( const char* val ) { float x, y; sscanf(val, "%f %f", &x, &y); return Vector2D(x, y); } -template<> inline Vector ConVarBaseData_t::ValueFromString( const char* val ) { float x, y, z; sscanf(val, "%f %f %f", &x, &y, &z); return Vector(x, y, z); } -template<> inline Vector4D ConVarBaseData_t::ValueFromString( const char* val ) { float x, y, z, w; sscanf(val, "%f %f %f %f", &x, &y, &z, &w); return Vector4D(x, y, z, w); } -template<> inline QAngle ConVarBaseData_t::ValueFromString( const char* val ) { float x, y, z; sscanf(val, "%f %f %f", &x, &y, &z); return QAngle(x, y, z); } +template<> inline void CConVarBaseData::ValueToString( const uint16_t& val, char* dst, size_t length ) { snprintf( dst, length, "%u", val ); } +template<> inline void CConVarBaseData::ValueToString( const int16_t& val, char* dst, size_t length ) { snprintf( dst, length, "%d", val ); } +template<> inline void CConVarBaseData::ValueToString( const uint32_t& val, char* dst, size_t length ) { snprintf( dst, length, "%u", val ); } +template<> inline void CConVarBaseData::ValueToString( const int32_t& val, char* dst, size_t length ) { snprintf( dst, length, "%d", val ); } +template<> inline void CConVarBaseData::ValueToString( const uint64_t& val, char* dst, size_t length ) { snprintf( dst, length, "%lu", val ); } +template<> inline void CConVarBaseData::ValueToString( const int64_t& val, char* dst, size_t length ) { snprintf( dst, length, "%ld", val ); } +template<> inline void CConVarBaseData::ValueToString( const float& val, char* dst, size_t length ) { snprintf( dst, length, "%f", val ); } +template<> inline void CConVarBaseData::ValueToString( const double& val, char* dst, size_t length ) { snprintf( dst, length, "%lf", val ); } +template<> inline void CConVarBaseData::ValueToString( const char*const& val, char* dst, size_t length ) { memcpy( dst, val, length ); } +template<> inline void CConVarBaseData::ValueToString( const Color& val, char* dst, size_t length ) { snprintf( dst, length, "%d %d %d %d", val.r(), val.g(), val.b(), val.a() ); } +template<> inline void CConVarBaseData::ValueToString( const Vector2D& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f", val.x, val.y ); } +template<> inline void CConVarBaseData::ValueToString( const Vector& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f", val.x, val.y, val.z ); } +template<> inline void CConVarBaseData::ValueToString( const Vector4D& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f %f", val.x, val.y, val.z, val.w ); } +template<> inline void CConVarBaseData::ValueToString( const QAngle& val, char* dst, size_t length ) { snprintf( dst, length, "%f %f %f", val.x, val.y, val.z ); } + +template<> inline bool CConVarBaseData::ValueFromString( const char* val ) { if (strcmp(val, "true") == 0 || strcmp(val, "1") == 0) { return true; } return false; } +template<> inline uint16_t CConVarBaseData::ValueFromString( const char* val ) { unsigned int ret; sscanf(val, "%u", &ret); return ret; } +template<> inline int16_t CConVarBaseData::ValueFromString( const char* val ) { int ret; sscanf(val, "%d", &ret); return ret; } +template<> inline uint32_t CConVarBaseData::ValueFromString( const char* val ) { uint32_t ret; sscanf(val, "%u", &ret); return ret; } +template<> inline int32_t CConVarBaseData::ValueFromString( const char* val ) { int32_t ret; sscanf(val, "%d", &ret); return ret; } +template<> inline uint64_t CConVarBaseData::ValueFromString( const char* val ) { uint64_t ret; sscanf(val, "%lu", &ret); return ret; } +template<> inline int64_t CConVarBaseData::ValueFromString( const char* val ) { int64_t ret; sscanf(val, "%ld", &ret); return ret; } +template<> inline float CConVarBaseData::ValueFromString( const char* val ) { float ret; sscanf(val, "%f", &ret); return ret; } +template<> inline double CConVarBaseData::ValueFromString( const char* val ) { double ret; sscanf(val, "%lf", &ret); return ret; } +template<> inline const char* CConVarBaseData::ValueFromString( const char* val ) { return val; } +template<> inline Color CConVarBaseData::ValueFromString( const char* val ) { int r, g, b, a; sscanf(val, "%d %d %d %d", &r, &g, &b, &a); return Color(r, g, b, a); } +template<> inline Vector2D CConVarBaseData::ValueFromString( const char* val ) { float x, y; sscanf(val, "%f %f", &x, &y); return Vector2D(x, y); } +template<> inline Vector CConVarBaseData::ValueFromString( const char* val ) { float x, y, z; sscanf(val, "%f %f %f", &x, &y, &z); return Vector(x, y, z); } +template<> inline Vector4D CConVarBaseData::ValueFromString( const char* val ) { float x, y, z, w; sscanf(val, "%f %f %f %f", &x, &y, &z, &w); return Vector4D(x, y, z, w); } +template<> inline QAngle CConVarBaseData::ValueFromString( const char* val ) { float x, y, z; sscanf(val, "%f %f %f", &x, &y, &z); return QAngle(x, y, z); } template -struct ConVarData_t : ConVarBaseData_t +class CConVarData : public CConVarBaseData { public: friend class ConVar; - constexpr ConVarData_t() + constexpr CConVarData() { m_defaultValue = new T(); m_minValue = new T(); @@ -347,7 +328,7 @@ friend class ConVar; m_eVarType = TranslateConVarType(); } - ~ConVarData_t() + ~CConVarData() { delete m_defaultValue; delete m_minValue; @@ -437,15 +418,15 @@ friend class ConVar; inline void SetStringMaxValue( const char* src ) const { SetMaxValue( ValueFromString( src ) ); } protected: - static inline void ValueToString( const T& value, char* dst, size_t length ) { ConVarBaseData_t::ValueToString( value, dst, length ); }; + static inline void ValueToString( const T& value, char* dst, size_t length ) { CConVarBaseData::ValueToString( value, dst, length ); }; - static T ValueFromString( const char* val ) { return ConVarBaseData_t::ValueFromString( val ); }; + static T ValueFromString( const char* val ) { return CConVarBaseData::ValueFromString( val ); }; T m_value[MAX_SPLITSCREEN_CLIENTS]; }; // Special case for string handling -template<> inline void ConVarData_t::SetValue(const char*const& value, const CSplitScreenSlot& index) +template<> inline void CConVarData::SetValue(const char*const& value, const CSplitScreenSlot& index) { char* data = new char[256]; memcpy(data, value, 256); @@ -455,12 +436,12 @@ template<> inline void ConVarData_t::SetValue(const char*const& val } // For some types it makes no sense to clamp -template<> inline const char*const& ConVarData_t::Clamp(const char*const& value) const { return value; } -template<> inline const Color& ConVarData_t::Clamp(const Color& value) const { return value; } -template<> inline const Vector2D& ConVarData_t::Clamp(const Vector2D& value) const { return value; } -template<> inline const Vector& ConVarData_t::Clamp(const Vector& value) const { return value; } -template<> inline const Vector4D& ConVarData_t::Clamp(const Vector4D& value) const { return value; } -template<> inline const QAngle& ConVarData_t::Clamp(const QAngle& value) const { return value; } +template<> inline const char*const& CConVarData::Clamp(const char*const& value) const { return value; } +template<> inline const Color& CConVarData::Clamp(const Color& value) const { return value; } +template<> inline const Vector2D& CConVarData::Clamp(const Vector2D& value) const { return value; } +template<> inline const Vector& CConVarData::Clamp(const Vector& value) const { return value; } +template<> inline const Vector4D& CConVarData::Clamp(const Vector4D& value) const { return value; } +template<> inline const QAngle& CConVarData::Clamp(const QAngle& value) const { return value; } //----------------------------------------------------------------------------- // Purpose: DLL interface to ConVars/ConCommands @@ -506,9 +487,9 @@ abstract_class ICvar : public IAppSystem virtual void unk2() = 0; // Register, unregister vars - virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, ConVarBaseData_t** pCvar ) = 0; + virtual void RegisterConVar( const ConVarCreation_t& setup, int64 nAdditionalFlags, ConVarHandle* pCvarRef, CConVarBaseData** pCvar ) = 0; virtual void UnregisterConVar( ConVarHandle handle ) = 0; - virtual ConVarBaseData_t* GetConVar( ConVarHandle handle ) = 0; + virtual CConVarBaseData* GetConVar( ConVarHandle handle ) = 0; // Register, unregister commands virtual ConCommandHandle RegisterConCommand( const ConCommandCreation_t& setup, int64 nAdditionalFlags = 0 ) = 0; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index c94ebbe38..7129b7fc1 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -366,15 +366,23 @@ struct ConVarCreation_t : CVarCreationBase_t { m_bHasMax(false) {} + template + T& DefaultValue() { return *reinterpret_cast(m_defaultValue); } + template + T& MinValue() { return *reinterpret_cast(m_minValue); } + template + T& MaxValue() { return *reinterpret_cast(m_maxValue); } + int32_t m_unknown1; // 0x18 bool m_bHasDefault; // 0x22 bool m_bHasMin; // 0x23 bool m_bHasMax; // 0x24 - - CVValue_t m_defaultValue; // 0x25 - CVValue_t m_minValue; // 0x35 - CVValue_t m_maxValue; // 0x45 + private: + // Don't use CVValue_t directly, to avoid initialising memory + uint8_t m_defaultValue[sizeof(CVValue_t)]; // 0x25 + uint8_t m_minValue[sizeof(CVValue_t)]; // 0x35 + uint8_t m_maxValue[sizeof(CVValue_t)]; // 0x45 } m_valueInfo; // 0x22 #pragma pack(pop) @@ -382,18 +390,38 @@ struct ConVarCreation_t : CVarCreationBase_t { EConVarType m_eVarType; // 0x58 ConVarHandle* m_pHandle; // 0x60 - ConVarBaseData_t** m_pConVarData; // 0x68 + CConVarBaseData** m_pConVarData; // 0x68 }; static_assert(sizeof(ConVarCreation_t) == 0x70, "ConVarCreation_t wrong size!"); static_assert(sizeof(ConVarCreation_t) % 8 == 0x0, "ConVarCreation_t isn't 8 bytes aligned!"); static_assert(sizeof(CVValue_t) == 0x10, "CVValue_t wrong size!"); -extern void* invalid_convar[EConVarType_MAX + 1]; +static CConVarBaseData* GetInvalidConVar( EConVarType type ) +{ + static CConVarBaseData* invalid_convar[EConVarType_MAX + 1] = { + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData(), + new CConVarData() // EConVarType_MAX + }; -template -ConVarData_t* GetInvalidConVar() -{ - return (ConVarData_t*)&invalid_convar[TranslateConVarType()]; + if (type == EConVarType_Invalid) + { + return invalid_convar[ EConVarType_MAX ]; + } + return invalid_convar[ type ]; } void SetupConVar( ConVarCreation_t& cvar ); @@ -401,8 +429,29 @@ void UnRegisterConVar( ConVarHandle& cvar ); void RegisterConVar( ConVarCreation_t& cvar ); //----------------------------------------------------------------- -// Used to read/write/create? convars (replaces the FindVar method) +// Used to read/write/create convars (replaces the FindVar method) //----------------------------------------------------------------- +class BaseConVar +{ +public: + inline const char* GetName( ) const { return m_ConVarData->GetName( ); } + inline const char* GetDescription( ) const { return m_ConVarData->GetDescription( ); } + inline EConVarType GetType( ) const { return m_ConVarData->GetType( ); } + + inline bool HasDefaultValue( ) const { return m_ConVarData->HasDefaultValue( ); } + inline bool HasMinValue( ) const { return m_ConVarData->HasMinValue( ); } + inline bool HasMaxValue( ) const { return m_ConVarData->HasMaxValue( ); } + + inline bool IsFlagSet( int64_t flag ) const { return m_ConVarData->IsFlagSet( flag ); } + inline void AddFlags( int64_t flags ) { m_ConVarData->AddFlags( flags ); } + inline void RemoveFlags( int64_t flags ) { return m_ConVarData->RemoveFlags( flags ); } + inline int64_t GetFlags( void ) const { return m_ConVarData->GetFlags( ); } +protected: + // High-speed method to read convar data + ConVarHandle m_Handle; + CConVarBaseData* m_ConVarData; +}; + template class ConVar : public BaseConVar { @@ -415,7 +464,7 @@ class ConVar : public BaseConVar ConVarCreation_t setup; setup.m_valueInfo.m_bHasDefault = true; - setup.m_valueInfo.m_defaultValue = value; + setup.m_valueInfo.DefaultValue() = value; setup.m_eVarType = TranslateConVarType(); setup.m_fnCallBack = reinterpret_cast(cb); @@ -428,12 +477,12 @@ class ConVar : public BaseConVar ConVarCreation_t setup; setup.m_valueInfo.m_bHasDefault = true; - setup.m_valueInfo.m_defaultValue = value; + setup.m_valueInfo.DefaultValue() = value; setup.m_valueInfo.m_bHasMin = min; setup.m_valueInfo.m_bHasMax = max; - setup.m_valueInfo.m_minValue = minValue; - setup.m_valueInfo.m_maxValue = maxValue; + setup.m_valueInfo.MinValue() = minValue; + setup.m_valueInfo.MaxValue() = maxValue; setup.m_eVarType = TranslateConVarType(); setup.m_fnCallBack = reinterpret_cast(cb); @@ -446,69 +495,58 @@ class ConVar : public BaseConVar UnRegisterConVar(this->m_Handle); } - inline const char* GetName( ) const { return m_ConVarData->GetName( ); } - inline const char* GetDescription( ) const { return m_ConVarData->GetDescription( ); } - inline EConVarType GetType( ) const { return m_ConVarData->GetType( ); } - - inline bool HasDefaultValue( ) const { return m_ConVarData->HasDefaultValue( ); } - inline bool HasMinValue( ) const { return m_ConVarData->HasMinValue( ); } - inline bool HasMaxValue( ) const { return m_ConVarData->HasMaxValue( ); } + inline const CConVarData* GetConVarData() const { return reinterpret_cast*>(m_ConVarData); } + inline CConVarData* GetConVarData() { return reinterpret_cast*>(m_ConVarData); } - inline const T& GetDefaultValue( ) const { return m_ConVarData->GetDefaultValue( ); } - inline const T& GetMinValue( ) const { return m_ConVarData->GetMinValue( ); } - inline const T& GetMaxValue( ) const { return m_ConVarData->GetMaxValue( ); } + inline const T& GetDefaultValue( ) const { return GetConVarData()->GetDefaultValue( ); } + inline const T& GetMinValue( ) const { return GetConVarData()->GetMinValue( ); } + inline const T& GetMaxValue( ) const { return GetConVarData()->GetMaxValue( ); } - inline void SetDefaultValue( const T& value ) { m_ConVarData->SetDefaultValue( value ); } - inline void SetMinValue( const T& value ) { m_ConVarData->SetMinValue( value ); } - inline void SetMaxValue( const T& value ) { m_ConVarData->SetMaxValue( value ); } + inline void SetDefaultValue( const T& value ) { GetConVarData()->SetDefaultValue( value ); } + inline void SetMinValue( const T& value ) { GetConVarData()->SetMinValue( value ); } + inline void SetMaxValue( const T& value ) { GetConVarData()->SetMaxValue( value ); } - inline void RemoveDefaultValue( ) { m_ConVarData->RemoveDefaultValue( ); } - inline void RemoveMinValue( ) { m_ConVarData->RemoveMinValue( ); } - inline void RemoveMaxValue( ) { m_ConVarData->RemoveMaxValue( ); } + inline void RemoveDefaultValue( ) { GetConVarData()->RemoveDefaultValue( ); } + inline void RemoveMinValue( ) { GetConVarData()->RemoveMinValue( ); } + inline void RemoveMaxValue( ) { GetConVarData()->RemoveMaxValue( ); } - inline const T& Clamp(const T& value) const { return m_ConVarData->Clamp( value ); } + inline const T& Clamp(const T& value) const { return GetConVarData()->Clamp( value ); } - inline const T& GetValue( const CSplitScreenSlot& index = CSplitScreenSlot() ) const { return m_ConVarData->GetValue( index ); } + inline const T& GetValue( const CSplitScreenSlot& index = CSplitScreenSlot() ) const { return GetConVarData()->GetValue( index ); } inline void SetValue( const T& val, const CSplitScreenSlot& index = CSplitScreenSlot() ) { auto newValue = this->Clamp( val ); char szNewValue[256], szOldValue[256]; - ConVarData_t::ValueToString( newValue, szNewValue, sizeof(szNewValue) ); - m_ConVarData->GetStringValue( szOldValue, sizeof(szOldValue), index ); + CConVarData::ValueToString( newValue, szNewValue, sizeof(szNewValue) ); + GetConVarData()->GetStringValue( szOldValue, sizeof(szOldValue), index ); // Deep copy T oldValue = this->GetValue( ); - m_ConVarData->SetValue( newValue, index ); + GetConVarData()->SetValue( newValue, index ); g_pCVar->CallChangeCallback( this->m_Handle, index, (const CVValue_t*)&newValue, (const CVValue_t*)&oldValue ); g_pCVar->CallGlobalChangeCallbacks( this, index, szNewValue, szOldValue ); } - inline void GetStringValue( char* dst, size_t len, const CSplitScreenSlot& index = 0 ) const { m_ConVarData->GetStringValue( dst, len, index ); } - - inline void GetStringDefaultValue( char* dst, size_t len ) const { m_ConVarData->GetStringDefaultValue( dst, len ); } - inline void GetStringMinValue( char* dst, size_t len ) const { m_ConVarData->GetStringMinValue( dst, len ); } - inline void GetStringMaxValue( char* dst, size_t len ) const { m_ConVarData->GetStringMaxValue( dst, len ); } - - inline bool IsFlagSet( int64_t flag ) const { return m_ConVarData->IsFlagSet( flag ); } - inline void AddFlags( int64_t flags ) { m_ConVarData->AddFlags( flags ); } - inline void RemoveFlags( int64_t flags ) { return m_ConVarData->RemoveFlags( flags ); } - inline int64_t GetFlags( void ) const { return m_ConVarData->GetFlags( ); } + inline void GetStringValue( char* dst, size_t len, const CSplitScreenSlot& index = 0 ) const { GetConVarData()->GetStringValue( dst, len, index ); } + inline void GetStringDefaultValue( char* dst, size_t len ) const { GetConVarData()->GetStringDefaultValue( dst, len ); } + inline void GetStringMinValue( char* dst, size_t len ) const { GetConVarData()->GetStringMinValue( dst, len ); } + inline void GetStringMaxValue( char* dst, size_t len ) const { GetConVarData()->GetStringMaxValue( dst, len ); } private: void Init(ConVarHandle defaultHandle, EConVarType type) { - this->m_Handle.Invalidate(); + this->m_Handle.Invalidate( ); this->m_ConVarData = nullptr; - if (g_pCVar) + if ( g_pCVar ) { - auto cvar = g_pCVar->GetConVar(defaultHandle); - this->m_ConVarData = (cvar) ? g_pCVar->GetConVar(defaultHandle)->Cast() : nullptr; - if (!this->m_ConVarData) + auto cvar = g_pCVar->GetConVar( defaultHandle ); + this->m_ConVarData = ( cvar && cvar->Cast( ) ) ? cvar : nullptr; + if ( !this->m_ConVarData ) { - this->m_ConVarData = GetInvalidConVar(); + this->m_ConVarData = GetInvalidConVar( TranslateConVarType( ) ); } // technically this //result = *(char ***)(sub_10B7760((unsigned int)a3) + 80); @@ -518,7 +556,7 @@ class ConVar : public BaseConVar void Register(const char* name, int32_t flags, const char* description, ConVarCreation_t& cvar) { - this->m_ConVarData = GetInvalidConVar(); + this->m_ConVarData = GetInvalidConVar( cvar.m_eVarType ); this->m_Handle.Invalidate(); if (!CommandLine()->HasParm("-tools") @@ -539,14 +577,10 @@ class ConVar : public BaseConVar cvar.m_nFlags = flags; cvar.m_pHandle = &this->m_Handle; - cvar.m_pConVarData = (ConVarBaseData_t**)&this->m_ConVarData; + cvar.m_pConVarData = &this->m_ConVarData; SetupConVar(cvar); } - - // High-speed method to read convar data - ConVarHandle m_Handle; - ConVarData_t* m_ConVarData; }; static_assert(sizeof(ConVar) == 0x10, "ConVar is of the wrong size!"); static_assert(sizeof(ConVar) == sizeof(ConVar), "Templated ConVar size varies!"); @@ -557,10 +591,10 @@ template<> inline void ConVar::SetValue( const char*const& val, con auto newValue = this->Clamp( val ); char szNewValue[256], szOldValue[256]; - ConVarData_t::ValueToString( newValue, szNewValue, sizeof(szNewValue) ); - m_ConVarData->GetStringValue( szOldValue, sizeof(szOldValue), index ); + CConVarData::ValueToString( newValue, szNewValue, sizeof(szNewValue) ); + GetConVarData()->GetStringValue( szOldValue, sizeof(szOldValue), index ); - m_ConVarData->SetValue( newValue, index ); + GetConVarData()->SetValue( newValue, index ); g_pCVar->CallChangeCallback( this->m_Handle, index, (const CVValue_t*)&newValue, (const CVValue_t*)&szOldValue ); g_pCVar->CallGlobalChangeCallbacks( this, index, szNewValue, szOldValue ); diff --git a/tier1/convar.cpp b/tier1/convar.cpp index ff2b7a0bc..f81b5e551 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -486,25 +486,6 @@ void ConCommand::Destroy() // //----------------------------------------------------------------------------- -void* invalid_convar[EConVarType_MAX + 1] = { - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t(), - new ConVarData_t() // EConVarType_MAX -}; - #ifdef CONVAR_WORK_FINISHED //----------------------------------------------------------------------------- From 2a8d56fc16c73770bc58870376ab331ae709e209 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Mon, 9 Oct 2023 19:27:32 +0200 Subject: [PATCH 32/36] small mistake --- public/icvar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 6ed53b7c3..64daf0d52 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -408,8 +408,8 @@ friend class ConVar; inline void GetStringValue( char* dst, size_t len, const CSplitScreenSlot& index = 0 ) const { ValueToString( GetValue( index ), dst, len ); } inline void GetStringDefaultValue( char* dst, size_t len ) const { ValueToString( GetDefaultValue( ), dst, len ); } - inline void GetStringMinValue( char* dst, size_t len ) const { ValueToString( GetMaxValue( ), dst, len ); } - inline void GetStringMaxValue( char* dst, size_t len ) const { ValueToString( GetValue( index ), dst, len ); } + inline void GetStringMinValue( char* dst, size_t len ) const { ValueToString( GetMinValue( ), dst, len ); } + inline void GetStringMaxValue( char* dst, size_t len ) const { ValueToString( GetMaxValue( ), dst, len ); } inline void SetStringValue( const char* src, const CSplitScreenSlot& index = 0 ) const { SetValue( ValueFromString( src ), index ); } From f6341c0d0792a8dcb5defd5302cf4e7f7cc61f33 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Mon, 9 Oct 2023 19:36:17 +0200 Subject: [PATCH 33/36] setup times changed --- public/icvar.h | 5 +++-- public/tier1/convar.h | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/public/icvar.h b/public/icvar.h index 64daf0d52..41b127cc4 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -240,7 +240,8 @@ class CConVarBaseData inline bool HasMinValue( ) const { return m_minValue != nullptr; } inline bool HasMaxValue( ) const { return m_maxValue != nullptr; } - inline int GetTimesChanges( void ) const { return m_iTimesChanged; } + inline int GetTimesChanged( void ) const { return m_iTimesChanged; } + inline void SetTimesChanged( int val ) { m_iTimesChanged = val; } inline bool IsFlagSet( int64_t flag ) const { return ( flag & m_nFlags ) ? true : false; } inline void AddFlags( int64_t flags ) { m_nFlags |= flags; } @@ -463,7 +464,7 @@ abstract_class ICvar : public IAppSystem // Install a global change callback (to be called when any convar changes) virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; virtual void RemoveGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0; - virtual void CallGlobalChangeCallbacks( BaseConVar* ref, CSplitScreenSlot nSlot, const char* newValue, char* oldValue ) = 0; + virtual void CallGlobalChangeCallbacks( BaseConVar* ref, CSplitScreenSlot nSlot, const char* newValue, const char* oldValue ) = 0; // Reverts cvars which contain a specific flag virtual void RevertFlaggedConVars( int nFlag ) = 0; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 7129b7fc1..998a64db2 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -523,10 +523,7 @@ class ConVar : public BaseConVar // Deep copy T oldValue = this->GetValue( ); - GetConVarData()->SetValue( newValue, index ); - - g_pCVar->CallChangeCallback( this->m_Handle, index, (const CVValue_t*)&newValue, (const CVValue_t*)&oldValue ); - g_pCVar->CallGlobalChangeCallbacks( this, index, szNewValue, szOldValue ); + this->UpdateValue( newValue, index, (const CVValue_t*)&newValue, (const CVValue_t*)&oldValue, szNewValue, szOldValue ); } inline void GetStringValue( char* dst, size_t len, const CSplitScreenSlot& index = 0 ) const { GetConVarData()->GetStringValue( dst, len, index ); } @@ -581,6 +578,15 @@ class ConVar : public BaseConVar SetupConVar(cvar); } + + inline void UpdateValue( const T& value, const CSplitScreenSlot& index, const CVValue_t* newValue, const CVValue_t* oldValue, const char* szNewValue, const char* szOldValue ) + { + GetConVarData()->SetValue( value, index ); + + GetConVarData()->SetTimesChanged( GetConVarData()->GetTimesChanged( ) + 1 ); + g_pCVar->CallChangeCallback( this->m_Handle, index, newValue, oldValue ); + g_pCVar->CallGlobalChangeCallbacks( this, index, szNewValue, szOldValue ); + } }; static_assert(sizeof(ConVar) == 0x10, "ConVar is of the wrong size!"); static_assert(sizeof(ConVar) == sizeof(ConVar), "Templated ConVar size varies!"); @@ -594,10 +600,7 @@ template<> inline void ConVar::SetValue( const char*const& val, con CConVarData::ValueToString( newValue, szNewValue, sizeof(szNewValue) ); GetConVarData()->GetStringValue( szOldValue, sizeof(szOldValue), index ); - GetConVarData()->SetValue( newValue, index ); - - g_pCVar->CallChangeCallback( this->m_Handle, index, (const CVValue_t*)&newValue, (const CVValue_t*)&szOldValue ); - g_pCVar->CallGlobalChangeCallbacks( this, index, szNewValue, szOldValue ); + this->UpdateValue( newValue, index, (const CVValue_t*)&newValue, (const CVValue_t*)&szOldValue, szNewValue, szOldValue ); } //----------------------------------------------------------------------------- From a0a7e34a0f1772e15273bbca09a6faa66c277298 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Mon, 9 Oct 2023 22:31:31 +0200 Subject: [PATCH 34/36] expose handle --- public/tier1/convar.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 998a64db2..79b8fc906 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -342,6 +342,7 @@ class ConCommand this->Destroy(); } + inline ConCommandHandle GetHandle() const { return m_Handle; }; private: void Create( const char *pName, const char *pHelpString, int64_t flags, ConCommandCreation_t& setup ); void Destroy( ); @@ -446,6 +447,9 @@ class BaseConVar inline void AddFlags( int64_t flags ) { m_ConVarData->AddFlags( flags ); } inline void RemoveFlags( int64_t flags ) { return m_ConVarData->RemoveFlags( flags ); } inline int64_t GetFlags( void ) const { return m_ConVarData->GetFlags( ); } + + inline ConVarHandle GetHandle() const { return m_Handle; }; + inline CConVarBaseData* GetConVarData() const { return m_ConVarData; }; protected: // High-speed method to read convar data ConVarHandle m_Handle; From 79059228cb58c9d1406abf1ce5f819b487953a9b Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sun, 29 Oct 2023 22:35:48 +0100 Subject: [PATCH 35/36] add character_t include to icvar --- public/icvar.h | 1 + 1 file changed, 1 insertion(+) diff --git a/public/icvar.h b/public/icvar.h index 41b127cc4..7fd36e46d 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -12,6 +12,7 @@ #include "appframework/IAppSystem.h" #include "tier1/utlvector.h" +#include "tier1/characterset.h" #include "tier0/memalloc.h" #include "mathlib/vector4d.h" #include From db1b48fa04b1fadbdeb79acb6d2d7c0bee680356 Mon Sep 17 00:00:00 2001 From: Benoist <14257866+Kenzzer@users.noreply.github.com> Date: Wed, 7 Feb 2024 14:31:06 +0100 Subject: [PATCH 36/36] Streamline build for others This commit will be reverted eventually --- public/icvar.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/icvar.h b/public/icvar.h index 7fd36e46d..ddaf19764 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -17,6 +17,9 @@ #include "mathlib/vector4d.h" #include +// TO-DO: Remove Metamod ConVar PR is finished +class ConCommandBase; + class BaseConVar; class ConCommand; class CCommand;