diff --git a/lib/linux64/libtier0.so b/lib/linux64/libtier0.so index 03d4509a..db58ad04 100644 Binary files a/lib/linux64/libtier0.so and b/lib/linux64/libtier0.so differ diff --git a/lib/linux64/libvstdlib.so b/lib/linux64/libvstdlib.so deleted file mode 100644 index 7a04f505..00000000 Binary files a/lib/linux64/libvstdlib.so and /dev/null differ diff --git a/lib/mac/libvstdlib.dylib b/lib/mac/libvstdlib.dylib deleted file mode 100755 index d8e38303..00000000 Binary files a/lib/mac/libvstdlib.dylib and /dev/null differ diff --git a/lib/osx32/release/libprotobuf.a b/lib/osx32/release/libprotobuf.a deleted file mode 100644 index 239c6e9a..00000000 Binary files a/lib/osx32/release/libprotobuf.a and /dev/null differ diff --git a/lib/public/bitmap.lib b/lib/public/bitmap.lib deleted file mode 100644 index c4105541..00000000 Binary files a/lib/public/bitmap.lib and /dev/null differ diff --git a/lib/public/bonesetup.lib b/lib/public/bonesetup.lib deleted file mode 100644 index 86e25843..00000000 Binary files a/lib/public/bonesetup.lib and /dev/null differ diff --git a/lib/public/choreoobjects.lib b/lib/public/choreoobjects.lib deleted file mode 100644 index 5325d72c..00000000 Binary files a/lib/public/choreoobjects.lib and /dev/null differ diff --git a/lib/public/dmxloader.lib b/lib/public/dmxloader.lib deleted file mode 100644 index b56aa061..00000000 Binary files a/lib/public/dmxloader.lib and /dev/null differ diff --git a/lib/public/fgdlib.lib b/lib/public/fgdlib.lib deleted file mode 100644 index 70747559..00000000 Binary files a/lib/public/fgdlib.lib and /dev/null differ diff --git a/lib/public/interfaces.lib b/lib/public/interfaces.lib deleted file mode 100644 index 9688f86c..00000000 Binary files a/lib/public/interfaces.lib and /dev/null differ diff --git a/lib/public/mathlib.lib b/lib/public/mathlib.lib deleted file mode 100644 index dff15d26..00000000 Binary files a/lib/public/mathlib.lib and /dev/null differ diff --git a/lib/public/matsys_controls.lib b/lib/public/matsys_controls.lib deleted file mode 100644 index 9b4740da..00000000 Binary files a/lib/public/matsys_controls.lib and /dev/null differ diff --git a/lib/public/npsclient.lib b/lib/public/npsclient.lib deleted file mode 100644 index dddfadb0..00000000 Binary files a/lib/public/npsclient.lib and /dev/null differ diff --git a/lib/public/nvtristrip.lib b/lib/public/nvtristrip.lib deleted file mode 100644 index 3788c596..00000000 Binary files a/lib/public/nvtristrip.lib and /dev/null differ diff --git a/lib/public/particles.lib b/lib/public/particles.lib deleted file mode 100644 index 2403819e..00000000 Binary files a/lib/public/particles.lib and /dev/null differ diff --git a/lib/public/raytrace.lib b/lib/public/raytrace.lib deleted file mode 100644 index fdbacb7a..00000000 Binary files a/lib/public/raytrace.lib and /dev/null differ diff --git a/lib/public/responserules_runtime.lib b/lib/public/responserules_runtime.lib deleted file mode 100644 index 0a091238..00000000 Binary files a/lib/public/responserules_runtime.lib and /dev/null differ diff --git a/lib/public/steam_api.lib b/lib/public/steam_api.lib deleted file mode 100644 index 4e1b684a..00000000 Binary files a/lib/public/steam_api.lib and /dev/null differ diff --git a/lib/public/tier0.lib b/lib/public/tier0.lib deleted file mode 100644 index 22e9e0c9..00000000 Binary files a/lib/public/tier0.lib and /dev/null differ diff --git a/lib/public/tier1.lib b/lib/public/tier1.lib deleted file mode 100644 index 609570b7..00000000 Binary files a/lib/public/tier1.lib and /dev/null differ diff --git a/lib/public/tier2.lib b/lib/public/tier2.lib deleted file mode 100644 index 6e4c11ce..00000000 Binary files a/lib/public/tier2.lib and /dev/null differ diff --git a/lib/public/tier3.lib b/lib/public/tier3.lib deleted file mode 100644 index c08240c5..00000000 Binary files a/lib/public/tier3.lib and /dev/null differ diff --git a/lib/public/vbsp2lib.lib b/lib/public/vbsp2lib.lib deleted file mode 100644 index 64b967f8..00000000 Binary files a/lib/public/vbsp2lib.lib and /dev/null differ diff --git a/lib/public/vgui_controls.lib b/lib/public/vgui_controls.lib deleted file mode 100644 index b055bee9..00000000 Binary files a/lib/public/vgui_controls.lib and /dev/null differ diff --git a/lib/public/videocfg.lib b/lib/public/videocfg.lib deleted file mode 100644 index 7015fe27..00000000 Binary files a/lib/public/videocfg.lib and /dev/null differ diff --git a/lib/public/vmpi.lib b/lib/public/vmpi.lib deleted file mode 100644 index 98f49679..00000000 Binary files a/lib/public/vmpi.lib and /dev/null differ diff --git a/lib/public/vpklib.lib b/lib/public/vpklib.lib deleted file mode 100644 index 8fa18484..00000000 Binary files a/lib/public/vpklib.lib and /dev/null differ diff --git a/lib/public/vstdlib.lib b/lib/public/vstdlib.lib deleted file mode 100644 index 85b0d94d..00000000 Binary files a/lib/public/vstdlib.lib and /dev/null differ diff --git a/lib/public/vtf.lib b/lib/public/vtf.lib deleted file mode 100644 index 7b799d3a..00000000 Binary files a/lib/public/vtf.lib and /dev/null differ diff --git a/lib/public/win64/tier0.lib b/lib/public/win64/tier0.lib index db3dd96c..ded189bc 100644 Binary files a/lib/public/win64/tier0.lib and b/lib/public/win64/tier0.lib differ diff --git a/lib/public/win64/vstdlib.lib b/lib/public/win64/vstdlib.lib deleted file mode 100644 index 83bfceb6..00000000 Binary files a/lib/public/win64/vstdlib.lib and /dev/null differ diff --git a/lib/win32/debug/vs2013/libprotobuf.lib b/lib/win32/debug/vs2013/libprotobuf.lib deleted file mode 100644 index 826cd77f..00000000 Binary files a/lib/win32/debug/vs2013/libprotobuf.lib and /dev/null differ diff --git a/lib/win32/release/vs2013/libprotobuf.lib b/lib/win32/release/vs2013/libprotobuf.lib deleted file mode 100644 index 933e4076..00000000 Binary files a/lib/win32/release/vs2013/libprotobuf.lib and /dev/null differ diff --git a/linux_sdk/Makefile.tier1 b/linux_sdk/Makefile.tier1 index 7cfccc6a..d9192573 100644 --- a/linux_sdk/Makefile.tier1 +++ b/linux_sdk/Makefile.tier1 @@ -39,7 +39,6 @@ LIB_OBJS= \ $(LIB_OBJ_DIR)/datamanager.o \ $(LIB_OBJ_DIR)/diff.o \ $(LIB_OBJ_DIR)/generichash.o \ - $(LIB_OBJ_DIR)/KeyValues.o \ $(LIB_OBJ_DIR)/mempool.o \ $(LIB_OBJ_DIR)/memstack.o \ $(LIB_OBJ_DIR)/NetAdr.o \ diff --git a/public/eiface.h b/public/eiface.h index 5ff02912..d9f4c10b 100644 --- a/public/eiface.h +++ b/public/eiface.h @@ -1,4 +1,4 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -77,6 +77,7 @@ class ILoopModePrerequisiteRegistry; struct URLArgument_t; struct vis_info_t; class IHLTVServer; +class CBufferString; namespace google { @@ -172,6 +173,7 @@ public: virtual uint32 GetStatsAppID() const = 0; virtual void *UnknownFunc1(const char *pszFilename, void *pUnknown1, void *pUnknown2, void *pUnknown3) = 0; + virtual void UnknownFunc2() = 0; }; //----------------------------------------------------------------------------- @@ -206,6 +208,9 @@ public: virtual int PrecacheDecal( const char *name, bool preload = false ) = 0; virtual bool IsDecalPrecached( const char *s ) const = 0; virtual int GetPrecachedDecalIndex ( const char *s ) const = 0; + + virtual void UnknownFunc3() = 0; + virtual void UnknownFunc4() = 0; virtual int PrecacheGeneric( const char *s, bool preload = false ) = 0; virtual bool IsGenericPrecached( char const *s ) const = 0; @@ -220,17 +225,6 @@ public: virtual bool IsUserIDInUse( int userID ) = 0; // TERROR: used for transitioning virtual int GetLoadingProgressForUserID( int userID ) = 0; // TERROR: used for transitioning - // This returns which entities, to the best of the server's knowledge, the client currently knows about. - // This is really which entities were in the snapshot that this client last acked. - // This returns a bit vector with one bit for each entity. - // - // USE WITH CARE. Whatever tick the client is really currently on is subject to timing and - // ordering differences, so you should account for about a quarter-second discrepancy in here. - // Also, this will return NULL if the client doesn't exist or if this client hasn't acked any frames yet. - // - // iClientIndex is the CLIENT index, so if you use pPlayer->entindex(), subtract 1. - virtual const CBitVec* GetEntityTransmitBitsForClient( CEntityIndex iClientIndex ) = 0; - // Given the current PVS(or PAS) and origin, determine which players should hear/receive the message virtual void Message_DetermineMulticastRecipients( bool usepas, const Vector& origin, CPlayerBitVec& playerbits ) = 0; @@ -242,30 +236,16 @@ public: // Set the lightstyle to the specified value and network the change to any connected clients. Note that val must not // change place in memory (use MAKE_STRING) for anything that's not compiled into your mod. virtual void LightStyle( int style, const char *val ) = 0; - - // Project a static decal onto the specified entity / model (for level placed decals in the .bsp) - virtual void StaticDecal( const Vector &originInEntitySpace, int decalIndex, CEntityIndex entityIndex, int modelIndex, bool lowpriority ) = 0; // Print szMsg to the client console. virtual void ClientPrintf( CEntityIndex playerIndex, const char *szMsg ) = 0; - // SINGLE PLAYER/LISTEN SERVER ONLY (just matching the client .dll api for this) - // Prints the formatted string to the notification area of the screen ( down the right hand edge - // numbered lines starting at position 0 - virtual void Con_NPrintf( int pos, const char *fmt, ... ) = 0; - // SINGLE PLAYER/LISTEN SERVER ONLY(just matching the client .dll api for this) - // Similar to Con_NPrintf, but allows specifying custom text color and duration information - virtual void Con_NXPrintf( const struct con_nprint_s *info, const char *fmt, ... ) = 0; - virtual bool IsLowViolence() = 0; virtual bool SetHLTVChatBan( int tvslot, bool bBanned ) = 0; virtual bool IsAnyClientLowViolence() = 0; - // Change a specified player's "view entity" (i.e., use the view entity position/orientation for rendering the client view) - virtual void SetView( CEntityIndex playerIndex, CEntityIndex viewEntIndex ) = 0; - // Get the current game directory (hl2, tf2, hl1, cstrike, etc.) - virtual void GetGameDir( char *szGetGameDir, int maxlength ) = 0; + virtual void GetGameDir( CBufferString *pOut ) = 0; // Create a bot with the given name. Player index is -1 if fake client can't be created virtual CEntityIndex CreateFakeClient( const char *netname ) = 0; @@ -283,9 +263,7 @@ public: virtual edict_t *GetSplitScreenPlayerForEdict( CEntityIndex ent_num, int nSlot ) = 0; // Ret types might be all wrong for these. Haven't researched yet. - virtual bool IsSpawnGroupLoadedOnClient( CEntityIndex ent_num, SpawnGroupHandle_t spawnGroup ) const = 0; virtual void UnloadSpawnGroup( SpawnGroupHandle_t spawnGroup, /*ESpawnGroupUnloadOption*/ int) = 0; - virtual void LoadSpawnGroup( const SpawnGroupDesc_t & ) = 0; virtual void SetSpawnGroupDescription( SpawnGroupHandle_t spawnGroup, const char *pszDescription ) = 0; virtual bool IsSpawnGroupLoaded( SpawnGroupHandle_t spawnGroup ) const = 0; virtual bool IsSpawnGroupLoading( SpawnGroupHandle_t spawnGroup ) const = 0; @@ -294,26 +272,12 @@ public: virtual void SynchronizeAndBlockUntilLoaded( SpawnGroupHandle_t spawnGroup ) = 0; virtual void SetTimescale( float flTimescale ) = 0; - virtual CEntityIndex GetViewEntity( CEntityIndex ent ) = 0; - - // Is the engine in Commentary mode? - virtual int IsInCommentaryMode( void ) = 0; - + virtual uint32 GetAppID() = 0; // Returns the SteamID of the specified player. It'll be NULL if the player hasn't authenticated yet. virtual const CSteamID *GetClientSteamID( CEntityIndex clientIndex ) = 0; - virtual void ForceModelBounds( const char *s, const Vector &mins, const Vector &maxs ) = 0; - - // Marks the material (vmt file) for consistency checking. If the client and server have different - // contents for the file, the client's vmt can only use the VertexLitGeneric shader, and can only - // contain $baseTexture and $bumpmap vars. - virtual void ForceSimpleMaterial( const char *s ) = 0; - - // Marks the filename for consistency checking. This should be called after precaching the file. - virtual void ForceExactFile( const char *s ) = 0; - // Methods to set/get a gamestats data container so client & server running in same process can send combined data virtual void SetGamestatsData( CGamestatsData *pGamestatsData ) = 0; virtual CGamestatsData *GetGamestatsData() = 0; @@ -394,11 +358,6 @@ public: virtual void PreWorldUpdate( bool simulating ) = 0; virtual CUtlMap *GetEntity2Networkables( void ) const = 0; - virtual bool GetEntity2Networkable( CEntityIndex index, Entity2Networkable_t &out ) = 0; - - virtual void ClearInstancedBaselineFromServerClasses( void ) = 0; - - virtual void ClearSaveDirectory( void ) = 0; virtual void *GetEntityInfo() = 0; @@ -409,8 +368,6 @@ public: // One of these bools is 'simulating'... probably virtual void GameFrame( bool, bool, bool ) = 0; - virtual void PreSaveGameLoaded( char const *pSaveName, bool bCurrentlyInGame ) = 0; - // Returns true if the game DLL wants the server not to be made public. // Used by commentary system to hide multiplayer commentary servers from the master. virtual bool ShouldHideFromMasterServer( bool ) = 0; @@ -553,7 +510,7 @@ public: virtual void GetConVarPrefixesToResetToDefaults( CUtlString &prefixes ) const = 0; }; -#define INTERFACEVERSION_SERVERGAMECLIENTS "Source2GameClients002" +#define INTERFACEVERSION_SERVERGAMECLIENTS "Source2GameClients001" //----------------------------------------------------------------------------- // Purpose: Player / Client related functions diff --git a/public/tier0/dbg.h b/public/tier0/dbg.h index 5b58e1b8..31f0019e 100644 --- a/public/tier0/dbg.h +++ b/public/tier0/dbg.h @@ -1,4 +1,4 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ========// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ========// // // Purpose: // @@ -252,7 +252,7 @@ inline void Error( const tchar* pMsg, ... ) va_start(params, pMsg); V_vsnprintf(szBuffer, sizeof(szBuffer), pMsg, params); va_end(params); - LoggingSystem_LogDirect(LOG_GENERAL, LS_ERROR, szBuffer); + Plat_FatalErrorFunc( "%s", szBuffer ); } // @TODO: these callstack spew functions are currently disabled in the new logging system. Need to add support for these if desired. diff --git a/public/tier0/platform.h b/public/tier0/platform.h index dd303ef5..3fd0782f 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -1129,6 +1129,8 @@ PLATFORM_INTERFACE void Plat_ExitProcess( int nCode ); PLATFORM_INTERFACE bool Plat_ShouldCollectMiniDumpsForFatalErrors(); +PLATFORM_INTERFACE void Plat_FatalErrorFunc( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 ); + // b/w compatibility #define Sys_FloatTime Plat_FloatTime @@ -1227,6 +1229,8 @@ PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey(); //----------------------------------------------------------------------------- PLATFORM_INTERFACE void* Plat_SimpleLog( const tchar* file, int line ); +PLATFORM_INTERFACE const char *Plat_GetGameDirectory( int unknown=0 ); + #if _X360 #define Plat_FastMemset XMemSet diff --git a/public/tier1/KeyValues.h b/public/tier1/KeyValues.h index b220f7cf..a936919d 100644 --- a/public/tier1/KeyValues.h +++ b/public/tier1/KeyValues.h @@ -25,11 +25,12 @@ #include "exprevaluator.h" #include -class IBaseFileSystem; +class IFileSystem; class CUtlBuffer; class Color; class KeyValues; class IKeyValuesDumpContext; +class IKeyValuesErrorSpew; typedef void * FileHandle_t; // single byte identifies a xbox kv file in binary format @@ -84,7 +85,7 @@ public: public: explicit inline AutoDelete( KeyValues *pKeyValues ) : m_pKeyValues( pKeyValues ) {} explicit inline AutoDelete( const char *pchKVName ) : m_pKeyValues( new KeyValues( pchKVName ) ) {} - inline ~AutoDelete( void ) { if( m_pKeyValues ) m_pKeyValues->deleteThis(); } + inline ~AutoDelete( void ) { if( m_pKeyValues ) delete m_pKeyValues; } inline void Assign( KeyValues *pKeyValues ) { m_pKeyValues = pKeyValues; } KeyValues *operator->() { return m_pKeyValues; } operator KeyValues *() { return m_pKeyValues; } @@ -126,14 +127,14 @@ public: // File access. Set UsesEscapeSequences true, if resource file/buffer uses Escape Sequences (eg \n, \t) void UsesEscapeSequences(bool state); // default false - bool LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL); - bool SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL); + bool LoadFromFile( IFileSystem *filesystem, const char *resourceName, const char *pathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL, void *pUnkonwn1 = NULL, const char *pUnknown2 = NULL ); + bool SaveToFile( IFileSystem *filesystem, const char *resourceName, const char *pathID = NULL); // Read from a buffer... Note that the buffer must be null terminated - bool LoadFromBuffer( char const *resourceName, const char *pBuffer, IBaseFileSystem* pFileSystem = NULL, const char *pPathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL ); + bool LoadFromBuffer( char const *resourceName, const char *pBuffer, IFileSystem* pFileSystem = NULL, const char *pPathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL, IKeyValuesErrorSpew *pErrorSpew = NULL, void *pUnkonwn1 = NULL, const char *pUnknown2 = NULL ); // Read from a utlbuffer... - bool LoadFromBuffer( char const *resourceName, CUtlBuffer &buf, IBaseFileSystem* pFileSystem = NULL, const char *pPathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL ); + bool LoadFromBuffer( char const *resourceName, CUtlBuffer &buf, IFileSystem* pFileSystem = NULL, const char *pPathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL, IKeyValuesErrorSpew *pErrorSpew = NULL, void *pUnkonwn1 = NULL, const char *pUnknown2 = NULL ); // Find a keyValue, create it if it is not found. // Set bCreate to true to create the key if it doesn't already exist (which ensures a valid pointer will be returned) @@ -180,7 +181,13 @@ public: int GetInt( const char *keyName = NULL, int defaultValue = 0 ); uint64 GetUint64( const char *keyName = NULL, uint64 defaultValue = 0 ); float GetFloat( const char *keyName = NULL, float defaultValue = 0.0f ); - const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ); + inline const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ) + { + static char buf[ 64 ]; + GetString(keyName, defaultValue, &buf[0], sizeof(buf) ); + return &buf[0]; + } + const char *GetString( const char *keyName, const char *defaultValue, char *pszOut, uint64 maxlen ); const wchar_t *GetWString( const char *keyName = NULL, const wchar_t *defaultValue = L"" ); void *GetPtr( const char *keyName = NULL, void *defaultValue = (void*)0 ); Color GetColor( const char *keyName = NULL , const Color &defaultColor = Color( 0, 0, 0, 0 ) ); @@ -208,13 +215,11 @@ public: void SetColor( const char *keyName, Color value); void SetBool( const char *keyName, bool value ) { SetInt( keyName, value ? 1 : 0 ); } -#if 0 // Memory allocation (optimized) void *operator new( size_t iAllocSize ); void *operator new( size_t iAllocSize, int nBlockUse, const char *pFileName, int nLine ); void operator delete( void *pMem ); void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ); -#endif KeyValues& operator=( KeyValues& src ); @@ -254,9 +259,6 @@ public: }; types_t GetDataType(const char *keyName = NULL); - // Virtual deletion function - ensures that KeyValues object is deleted from correct heap - void deleteThis(); - void SetStringValue( char const *strValue ); // unpack a key values list into a structure @@ -280,31 +282,30 @@ public: // Assign keyvalues from a string static KeyValues * FromString( char const *szName, char const *szStringVal, char const **ppEndOfParse = NULL ); + + ~KeyValues(); private: KeyValues( KeyValues& ); // prevent copy constructor being used - // prevent delete being called except through deleteThis() - ~KeyValues(); - KeyValues* CreateKey( const char *keyName ); void RecursiveCopyKeyValues( KeyValues& src ); void RemoveEverything(); -// void RecursiveSaveToFile( IBaseFileSystem *filesystem, CUtlBuffer &buffer, int indentLevel ); +// void RecursiveSaveToFile( IFileSystem *filesystem, CUtlBuffer &buffer, int indentLevel ); // void WriteConvertedString( CUtlBuffer &buffer, const char *pszString ); // NOTE: If both filesystem and pBuf are non-null, it'll save to both of them. // If filesystem is null, it'll ignore f. - void RecursiveSaveToFile( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ); - void WriteConvertedString( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const char *pszString ); + void RecursiveSaveToFile( IFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ); + void WriteConvertedString( IFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const char *pszString ); void RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &buf, GetSymbolProc_t pfnEvaluateSymbolProc ); // for handling #include "filename" void AppendIncludedKeys( CUtlVector< KeyValues * >& includedKeys ); void ParseIncludedKeys( char const *resourceName, const char *filetoinclude, - IBaseFileSystem* pFileSystem, const char *pPathID, CUtlVector< KeyValues * >& includedKeys, GetSymbolProc_t pfnEvaluateSymbolProc ); + IFileSystem* pFileSystem, const char *pPathID, CUtlVector< KeyValues * >& includedKeys, GetSymbolProc_t pfnEvaluateSymbolProc ); // For handling #base "filename" void MergeBaseKeys( CUtlVector< KeyValues * >& baseKeys ); @@ -312,16 +313,16 @@ private: // NOTE: If both filesystem and pBuf are non-null, it'll save to both of them. // If filesystem is null, it'll ignore f. - void InternalWrite( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const void *pData, int len ); + void InternalWrite( IFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const void *pData, int len ); void Init(); const char * ReadToken( CUtlBuffer &buf, bool &wasQuoted, bool &wasConditional ); - void WriteIndents( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ); + void WriteIndents( IFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ); void FreeAllocatedValue(); void AllocateValueBlock(int size); - bool ReadAsBinaryPooledFormat( CUtlBuffer &buf, IBaseFileSystem *pFileSystem, unsigned int poolKey, GetSymbolProc_t pfnEvaluateSymbolProc ); + bool ReadAsBinaryPooledFormat( CUtlBuffer &buf, IFileSystem *pFileSystem, unsigned int poolKey, GetSymbolProc_t pfnEvaluateSymbolProc ); bool EvaluateConditional( const char *pExpressionString, GetSymbolProc_t pfnEvaluateSymbolProc ); @@ -377,6 +378,7 @@ struct KeyValuesUnpackStructure //----------------------------------------------------------------------------- // inline methods //----------------------------------------------------------------------------- +#if 0 inline int KeyValues::GetInt( HKeySymbol keySymbol, int defaultValue ) { KeyValues *dat = FindKey( keySymbol ); @@ -425,6 +427,7 @@ inline bool KeyValues::IsEmpty(HKeySymbol keySymbol) KeyValues *dat = FindKey( keySymbol ); return dat ? dat->IsEmpty( ) : true; } +#endif // diff --git a/public/tier1/exprevaluator.h b/public/tier1/exprevaluator.h index 7af80310..1dd75f2f 100644 --- a/public/tier1/exprevaluator.h +++ b/public/tier1/exprevaluator.h @@ -1,4 +1,4 @@ -//===== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2006, Valve Corporation, All rights reserved. ======// // // Purpose: ExprSimplifier builds a binary tree from an infix expression (in the // form of a character array). @@ -34,7 +34,7 @@ struct ExprNode typedef ExprNode *ExprTree; // callback to evaluate a $ during evaluation, return true or false -typedef bool (*GetSymbolProc_t)( const char *pKey ); +typedef bool (*GetSymbolProc_t)( const char *pKey, void *pUnknown ); typedef void (*SyntaxErrorProc_t)( const char *pReason ); class CExpressionEvaluator diff --git a/tier1/KeyValues.cpp b/tier1/KeyValues.cpp deleted file mode 100644 index 4ac50926..00000000 --- a/tier1/KeyValues.cpp +++ /dev/null @@ -1,2521 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#if defined( _WIN32 ) && !defined( _X360 ) -#include // for WideCharToMultiByte and MultiByteToWideChar -#elif defined( _LINUX ) || defined( __APPLE__ ) -#include // wcslen() -#define _alloca alloca -#endif - -#include -#include "filesystem.h" -#include - -#include -#include -#include "tier0/dbg.h" -#include "tier0/mem.h" -#include "utlvector.h" -#include "utlbuffer.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include - -static const char * s_LastFileLoadingFrom = "unknown"; // just needed for error messages - -#define KEYVALUES_TOKEN_SIZE 1024 -static char s_pTokenBuf[KEYVALUES_TOKEN_SIZE]; - - -#define INTERNALWRITE( pData, len ) InternalWrite( filesystem, f, pBuf, pData, len ) - - -// a simple class to keep track of a stack of valid parsed symbols -const int MAX_ERROR_STACK = 64; -class CKeyValuesErrorStack -{ -public: - CKeyValuesErrorStack() : m_pFilename("NULL"), m_errorIndex(0), m_maxErrorIndex(0) {} - - void SetFilename( const char *pFilename ) - { - m_pFilename = pFilename; - m_maxErrorIndex = 0; - } - - // entering a new keyvalues block, save state for errors - // Not save symbols instead of pointers because the pointers can move! - int Push(HKeySymbol symName) - { - if ( m_errorIndex < MAX_ERROR_STACK ) - { - m_errorStack[m_errorIndex] = symName; - } - m_errorIndex++; - m_maxErrorIndex = MAX( m_maxErrorIndex, (m_errorIndex-1) ); - return m_errorIndex-1; - } - - // exiting block, error isn't in this block, remove. - void Pop() - { - m_errorIndex--; - Assert(m_errorIndex>=0); - } - - // Allows you to keep the same stack level, but change the name as you parse peers - void Reset(int stackLevel, HKeySymbol symName) - { - Assert( stackLevel >= 0 && stackLevel < m_errorIndex ); - m_errorStack[stackLevel] = symName; - } - - // Hit an error, report it and the parsing stack for context - void ReportError( const char *pError ) - { - Warning( "KeyValues Error: %s in file %s\n", pError, m_pFilename ); - for ( int i = 0; i < m_maxErrorIndex; i++ ) - { - if ( m_errorStack[i] != INVALID_KEY_SYMBOL ) - { - if ( i < m_errorIndex ) - { - Warning( "%s, ", KeyValuesSystem()->GetStringForSymbol(m_errorStack[i]) ); - } - else - { - Warning( "(*%s*), ", KeyValuesSystem()->GetStringForSymbol(m_errorStack[i]) ); - } - } - } - Warning( "\n" ); - } - -private: - HKeySymbol m_errorStack[MAX_ERROR_STACK]; - const char *m_pFilename; - int m_errorIndex; - int m_maxErrorIndex; -} g_KeyValuesErrorStack; - - -// a simple helper that creates stack entries as it goes in & out of scope -class CKeyErrorContext -{ -public: - CKeyErrorContext( KeyValues *pKv ) - { - Init( pKv->GetNameSymbol() ); - } - - ~CKeyErrorContext() - { - g_KeyValuesErrorStack.Pop(); - } - CKeyErrorContext( HKeySymbol symName ) - { - Init( symName ); - } - void Reset( HKeySymbol symName ) - { - g_KeyValuesErrorStack.Reset( m_stackLevel, symName ); - } -private: - void Init( HKeySymbol symName ) - { - m_stackLevel = g_KeyValuesErrorStack.Push( symName ); - } - - int m_stackLevel; -}; - -// Uncomment this line to hit the ~CLeakTrack assert to see what's looking like it's leaking -// #define LEAKTRACK - -#ifdef LEAKTRACK - -class CLeakTrack -{ -public: - CLeakTrack() - { - } - ~CLeakTrack() - { - if ( keys.Count() != 0 ) - { - Assert( 0 ); - } - } - - struct kve - { - KeyValues *kv; - char name[ 256 ]; - }; - - void AddKv( KeyValues *kv, char const *name ) - { - kve k; - Q_strncpy( k.name, name ? name : "NULL", sizeof( k.name ) ); - k.kv = kv; - - keys.AddToTail( k ); - } - - void RemoveKv( KeyValues *kv ) - { - int c = keys.Count(); - for ( int i = 0; i < c; i++ ) - { - if ( keys[i].kv == kv ) - { - keys.Remove( i ); - break; - } - } - } - - CUtlVector< kve > keys; -}; - -static CLeakTrack track; - -#define TRACK_KV_ADD( ptr, name ) track.AddKv( ptr, name ) -#define TRACK_KV_REMOVE( ptr ) track.RemoveKv( ptr ) - -#else - -#define TRACK_KV_ADD( ptr, name ) -#define TRACK_KV_REMOVE( ptr ) - -#endif - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName ( setName ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, const char *firstValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetString( firstKey, firstValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, const wchar_t *firstValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetWString( firstKey, firstValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, int firstValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetInt( firstKey, firstValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, const char *firstValue, const char *secondKey, const char *secondValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetString( firstKey, firstValue ); - SetString( secondKey, secondValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, int firstValue, const char *secondKey, int secondValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetInt( firstKey, firstValue ); - SetInt( secondKey, secondValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Initialize member variables -//----------------------------------------------------------------------------- -void KeyValues::Init() -{ - m_iKeyName = HKeySymbol::MakeHandle(0); - m_iDataType = TYPE_NONE; - - m_pSub = NULL; - m_pPeer = NULL; - m_pChain = NULL; - - m_sValue = NULL; - m_wsValue = NULL; - m_pValue = NULL; - - m_bHasEscapeSequences = false; -} - -//----------------------------------------------------------------------------- -// Purpose: Destructor -//----------------------------------------------------------------------------- -KeyValues::~KeyValues() -{ - TRACK_KV_REMOVE( this ); - - RemoveEverything(); -} - -//----------------------------------------------------------------------------- -// Purpose: remove everything -//----------------------------------------------------------------------------- -void KeyValues::RemoveEverything() -{ - KeyValues *dat; - KeyValues *datNext = NULL; - for ( dat = m_pSub; dat != NULL; dat = datNext ) - { - datNext = dat->m_pPeer; - dat->m_pPeer = NULL; - delete dat; - } - - for ( dat = m_pPeer; dat && dat != this; dat = datNext ) - { - datNext = dat->m_pPeer; - dat->m_pPeer = NULL; - delete dat; - } - - delete [] m_sValue; - m_sValue = NULL; - delete [] m_wsValue; - m_wsValue = NULL; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *f - -//----------------------------------------------------------------------------- - -void KeyValues::RecursiveSaveToFile( CUtlBuffer& buf, int indentLevel ) -{ - RecursiveSaveToFile( NULL, FILESYSTEM_INVALID_HANDLE, &buf, indentLevel ); -} - -//----------------------------------------------------------------------------- -// Adds a chain... if we don't find stuff in this keyvalue, we'll look -// in the one we're chained to. -//----------------------------------------------------------------------------- - -void KeyValues::ChainKeyValue( KeyValues* pChain ) -{ - m_pChain = pChain; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the name of the current key section -//----------------------------------------------------------------------------- -const char *KeyValues::GetName( void ) const -{ - return KeyValuesSystem()->GetStringForSymbol(m_iKeyName); -} - -//----------------------------------------------------------------------------- -// Purpose: Get the symbol name of the current key section -//----------------------------------------------------------------------------- -HKeySymbol KeyValues::GetNameSymbol() const -{ - return m_iKeyName; -} - - -//----------------------------------------------------------------------------- -// Purpose: Read a single token from buffer (0 terminated) -//----------------------------------------------------------------------------- -#ifdef _MSC_VER -#pragma warning (disable:4706) -#endif -const char *KeyValues::ReadToken( CUtlBuffer &buf, bool &wasQuoted, bool &wasConditional ) -{ - wasQuoted = false; - wasConditional = false; - - if ( !buf.IsValid() ) - return NULL; - - // eating white spaces and remarks loop - while ( true ) - { - buf.EatWhiteSpace(); - if ( !buf.IsValid() ) - return NULL; // file ends after reading whitespaces - - // stop if it's not a comment; a new token starts here - if ( !buf.EatCPPComment() ) - break; - } - - const char *c = (const char*)buf.PeekGet( sizeof(char), 0 ); - if ( !c ) - return NULL; - - // read quoted strings specially - if ( *c == '\"' ) - { - wasQuoted = true; - buf.GetDelimitedString( m_bHasEscapeSequences ? GetCStringCharConversion() : GetNoEscCharConversion(), - s_pTokenBuf, KEYVALUES_TOKEN_SIZE ); - return s_pTokenBuf; - } - - if ( *c == '{' || *c == '}' ) - { - // it's a control char, just add this one char and stop reading - s_pTokenBuf[0] = *c; - s_pTokenBuf[1] = 0; - buf.SeekGet( CUtlBuffer::SEEK_CURRENT, 1 ); - return s_pTokenBuf; - } - - // read in the token until we hit a whitespace or a control character - bool bReportedError = false; - bool bConditionalStart = false; - int nCount = 0; - while ( (c = (const char*)buf.PeekGet( sizeof(char), 0 )) ) - { - // end of file - if ( *c == 0 ) - break; - - // break if any control character appears in non quoted tokens - if ( *c == '"' || *c == '{' || *c == '}' ) - break; - - if ( *c == '[' ) - bConditionalStart = true; - - if ( *c == ']' && bConditionalStart ) - { - wasConditional = true; - } - - // break on whitespace - if ( isspace(*c) ) - break; - - if (nCount < (KEYVALUES_TOKEN_SIZE-1) ) - { - s_pTokenBuf[nCount++] = *c; // add char to buffer - } - else if ( !bReportedError ) - { - bReportedError = true; - g_KeyValuesErrorStack.ReportError(" ReadToken overflow" ); - } - - buf.SeekGet( CUtlBuffer::SEEK_CURRENT, 1 ); - } - s_pTokenBuf[ nCount ] = 0; - return s_pTokenBuf; -} -#ifdef _MSC_VER -#pragma warning (default:4706) -#endif - - -//----------------------------------------------------------------------------- -// Purpose: if parser should translate escape sequences ( /n, /t etc), set to true -//----------------------------------------------------------------------------- -void KeyValues::UsesEscapeSequences(bool state) -{ - m_bHasEscapeSequences = state; -} - - -//----------------------------------------------------------------------------- -// Purpose: Load keyValues from disk -//----------------------------------------------------------------------------- -bool KeyValues::LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID, GetSymbolProc_t pfnEvaluateSymbolProc ) -{ - Assert(filesystem); -#ifndef _LINUX - Assert( IsX360() || ( IsPC() && _heapchk() == _HEAPOK ) ); -#endif - - FileHandle_t f = filesystem->Open(resourceName, "rb", pathID); - if ( !f ) - return false; - - s_LastFileLoadingFrom = (char*)resourceName; - - // load file into a null-terminated buffer - int fileSize = filesystem->Size( f ); - unsigned bufSize = ((IFileSystem *)filesystem)->GetOptimalReadSize( f, fileSize + 1 ); - - char *buffer = (char*)((IFileSystem *)filesystem)->AllocOptimalReadBuffer( f, bufSize ); - Assert( buffer ); - - // read into local buffer - bool bRetOK = ( ((IFileSystem *)filesystem)->ReadEx( buffer, bufSize, fileSize, f ) != 0 ); - - filesystem->Close( f ); // close file after reading - - if ( bRetOK ) - { - buffer[fileSize] = 0; // null terminate file as EOF - bRetOK = LoadFromBuffer( resourceName, buffer, filesystem, pathID, pfnEvaluateSymbolProc); - } - - ((IFileSystem *)filesystem)->FreeOptimalReadBuffer( buffer ); - - return bRetOK; -} - -//----------------------------------------------------------------------------- -// Purpose: Save the keyvalues to disk -// Creates the path to the file if it doesn't exist -//----------------------------------------------------------------------------- -bool KeyValues::SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID ) -{ - // create a write file - FileHandle_t f = filesystem->Open(resourceName, "wb", pathID); - - if ( f == FILESYSTEM_INVALID_HANDLE ) - { - DevMsg(1, "KeyValues::SaveToFile: couldn't open file \"%s\" in path \"%s\".\n", - resourceName?resourceName:"NULL", pathID?pathID:"NULL" ); - return false; - } - - RecursiveSaveToFile(filesystem, f, NULL, 0); - filesystem->Close(f); - - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Write out a set of indenting -//----------------------------------------------------------------------------- -void KeyValues::WriteIndents( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ) -{ - for ( int i = 0; i < indentLevel; i++ ) - { - INTERNALWRITE( "\t", 1 ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Write out a string where we convert the double quotes to backslash double quote -//----------------------------------------------------------------------------- -void KeyValues::WriteConvertedString( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const char *pszString ) -{ - // handle double quote chars within the string - // the worst possible case is that the whole string is quotes - int len = Q_strlen(pszString); - char *convertedString = (char *) _alloca ((len + 1) * sizeof(char) * 2); - int j=0; - for (int i=0; i <= len; i++) - { - if (pszString[i] == '\"') - { - convertedString[j] = '\\'; - j++; - } - else if ( m_bHasEscapeSequences && pszString[i] == '\\' ) - { - convertedString[j] = '\\'; - j++; - } - convertedString[j] = pszString[i]; - j++; - } - - INTERNALWRITE(convertedString, strlen(convertedString)); -} - - -void KeyValues::InternalWrite( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const void *pData, int len ) -{ - if ( filesystem ) - { - filesystem->Write( pData, len, f ); - } - - if ( pBuf ) - { - pBuf->Put( pData, len ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Save keyvalues from disk, if subkey values are detected, calls -// itself to save those -//----------------------------------------------------------------------------- -void KeyValues::RecursiveSaveToFile( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ) -{ - // write header - WriteIndents( filesystem, f, pBuf, indentLevel ); - INTERNALWRITE("\"", 1); - WriteConvertedString(filesystem, f, pBuf, GetName()); - INTERNALWRITE("\"\n", 2); - WriteIndents( filesystem, f, pBuf, indentLevel ); - INTERNALWRITE("{\n", 2); - - // loop through all our keys writing them to disk - for ( KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer ) - { - if ( dat->m_pSub ) - { - dat->RecursiveSaveToFile( filesystem, f, pBuf, indentLevel + 1 ); - } - else - { - // only write non-empty keys - - switch (dat->m_iDataType) - { - case TYPE_STRING: - { - if (dat->m_sValue && *(dat->m_sValue)) - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - WriteConvertedString(filesystem, f, pBuf, dat->GetName()); - INTERNALWRITE("\"\t\t\"", 4); - - WriteConvertedString(filesystem, f, pBuf, dat->m_sValue); - - INTERNALWRITE("\"\n", 2); - } - break; - } - case TYPE_WSTRING: - { -#ifdef _WIN32 - if ( dat->m_wsValue ) - { - static char buf[KEYVALUES_TOKEN_SIZE]; - // make sure we have enough space - Assert(::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, NULL, 0, NULL, NULL) < KEYVALUES_TOKEN_SIZE); - int result = ::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, buf, KEYVALUES_TOKEN_SIZE, NULL, NULL); - if (result) - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - WriteConvertedString(filesystem, f, pBuf, buf); - - INTERNALWRITE("\"\n", 2); - } - } -#endif - break; - } - - case TYPE_INT: - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - char buf[32]; - Q_snprintf(buf, sizeof( buf ), "%d", dat->m_iValue); - - INTERNALWRITE(buf, Q_strlen(buf)); - INTERNALWRITE("\"\n", 2); - break; - } - - case TYPE_UINT64: - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - char buf[32]; - // write "0x" + 16 char 0-padded hex encoded 64 bit value - Q_snprintf( buf, sizeof( buf ), "0x%016llX", *( (uint64 *)dat->m_sValue ) ); - - INTERNALWRITE(buf, Q_strlen(buf)); - INTERNALWRITE("\"\n", 2); - break; - } - - case TYPE_FLOAT: - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - char buf[48]; - Q_snprintf(buf, sizeof( buf ), "%f", dat->m_flValue); - - INTERNALWRITE(buf, Q_strlen(buf)); - INTERNALWRITE("\"\n", 2); - break; - } - case TYPE_COLOR: - DevMsg(1, "KeyValues::RecursiveSaveToFile: TODO, missing code for TYPE_COLOR.\n"); - break; - - default: - break; - } - } - } - - // write tail - WriteIndents(filesystem, f, pBuf, indentLevel); - INTERNALWRITE("}\n", 2); -} - -//----------------------------------------------------------------------------- -// Purpose: looks up a key by symbol name -//----------------------------------------------------------------------------- -KeyValues *KeyValues::FindKey(HKeySymbol keySymbol) const -{ - for (KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer) - { - if (dat->m_iKeyName == keySymbol) - return dat; - } - - return NULL; -} - -//----------------------------------------------------------------------------- -// Purpose: Find a keyValue, create it if it is not found. -// Set bCreate to true to create the key if it doesn't already exist -// (which ensures a valid pointer will be returned) -//----------------------------------------------------------------------------- -KeyValues *KeyValues::FindKey(const char *keyName, bool bCreate) -{ - // return the current key if a NULL subkey is asked for - if (!keyName || !keyName[0]) - return this; - - // look for '/' characters deliminating sub fields - char szBuf[256]; - const char *subStr = strchr(keyName, '/'); - const char *searchStr = keyName; - - // pull out the substring if it exists - if (subStr) - { - int size = subStr - keyName; - Q_memcpy( szBuf, keyName, size ); - szBuf[size] = 0; - searchStr = szBuf; - } - - // lookup the symbol for the search string - HKeySymbol iSearchStr = KeyValuesSystem()->GetSymbolForString( searchStr, bCreate ); - if ( iSearchStr == INVALID_KEY_SYMBOL ) - { - // not found, couldn't possibly be in key value list - return NULL; - } - - KeyValues *lastItem = NULL; - KeyValues *dat; - // find the searchStr in the current peer list - for (dat = m_pSub; dat != NULL; dat = dat->m_pPeer) - { - lastItem = dat; // record the last item looked at (for if we need to append to the end of the list) - - // symbol compare - if (dat->m_iKeyName == iSearchStr) - { - break; - } - } - - if ( !dat && m_pChain ) - { - dat = m_pChain->FindKey(keyName, false); - } - - // make sure a key was found - if (!dat) - { - if (bCreate) - { - // we need to create a new key - dat = new KeyValues( searchStr ); -// Assert(dat != NULL); - - // insert new key at end of list - if (lastItem) - { - lastItem->m_pPeer = dat; - } - else - { - m_pSub = dat; - } - dat->m_pPeer = NULL; - - // a key graduates to be a submsg as soon as it's m_pSub is set - // this should be the only place m_pSub is set - m_iDataType = TYPE_NONE; - } - else - { - return NULL; - } - } - - // if we've still got a subStr we need to keep looking deeper in the tree - if ( subStr ) - { - // recursively chain down through the paths in the string - return dat->FindKey(subStr + 1, bCreate); - } - - return dat; -} - -//----------------------------------------------------------------------------- -// Purpose: Create a new key, with an autogenerated name. -// Name is guaranteed to be an integer, of value 1 higher than the highest -// other integer key name -//----------------------------------------------------------------------------- -KeyValues *KeyValues::CreateNewKey() -{ - int newID = 1; - - // search for any key with higher values - for (KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer) - { - // case-insensitive string compare - int val = atoi(dat->GetName()); - if (newID <= val) - { - newID = val + 1; - } - } - - char buf[12]; - Q_snprintf( buf, sizeof(buf), "%d", newID ); - - return CreateKey( buf ); -} - - -//----------------------------------------------------------------------------- -// Create a key -//----------------------------------------------------------------------------- -KeyValues* KeyValues::CreateKey( const char *keyName ) -{ - // key wasn't found so just create a new one - KeyValues* dat = new KeyValues( keyName ); - - dat->UsesEscapeSequences( m_bHasEscapeSequences != 0 ); // use same format as parent does - - // add into subkey list - AddSubKey( dat ); - - return dat; -} - - -//----------------------------------------------------------------------------- -// Adds a subkey. Make sure the subkey isn't a child of some other keyvalues -//----------------------------------------------------------------------------- -void KeyValues::AddSubKey( KeyValues *pSubkey ) -{ - // Make sure the subkey isn't a child of some other keyvalues - Assert( pSubkey->m_pPeer == NULL ); - - // add into subkey list - if ( m_pSub == NULL ) - { - m_pSub = pSubkey; - } - else - { - KeyValues *pTempDat = m_pSub; - while ( pTempDat->GetNextKey() != NULL ) - { - pTempDat = pTempDat->GetNextKey(); - } - - pTempDat->SetNextKey( pSubkey ); - } -} - - - -//----------------------------------------------------------------------------- -// Purpose: Remove a subkey from the list -//----------------------------------------------------------------------------- -void KeyValues::RemoveSubKey(KeyValues *subKey) -{ - if (!subKey) - return; - - // check the list pointer - if (m_pSub == subKey) - { - m_pSub = subKey->m_pPeer; - } - else - { - // look through the list - KeyValues *kv = m_pSub; - while (kv->m_pPeer) - { - if (kv->m_pPeer == subKey) - { - kv->m_pPeer = subKey->m_pPeer; - break; - } - - kv = kv->m_pPeer; - } - } - - subKey->m_pPeer = NULL; -} - - - -//----------------------------------------------------------------------------- -// Purpose: Return the first subkey in the list -//----------------------------------------------------------------------------- -KeyValues *KeyValues::GetFirstSubKey() -{ - return m_pSub; -} - -//----------------------------------------------------------------------------- -// Purpose: Return the next subkey -//----------------------------------------------------------------------------- -KeyValues *KeyValues::GetNextKey() -{ - return m_pPeer; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets this key's peer to the KeyValues passed in -//----------------------------------------------------------------------------- -void KeyValues::SetNextKey( KeyValues *pDat ) -{ - m_pPeer = pDat; -} - - -KeyValues* KeyValues::GetFirstTrueSubKey() -{ - KeyValues *pRet = m_pSub; - while ( pRet && pRet->m_iDataType != TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - -KeyValues* KeyValues::GetNextTrueSubKey() -{ - KeyValues *pRet = m_pPeer; - while ( pRet && pRet->m_iDataType != TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - -KeyValues* KeyValues::GetFirstValue() -{ - KeyValues *pRet = m_pSub; - while ( pRet && pRet->m_iDataType == TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - -KeyValues* KeyValues::GetNextValue() -{ - KeyValues *pRet = m_pPeer; - while ( pRet && pRet->m_iDataType == TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - - -//----------------------------------------------------------------------------- -// Purpose: Get the integer value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -int KeyValues::GetInt( const char *keyName, int defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_STRING: - return atoi(dat->m_sValue); - case TYPE_WSTRING: -#ifdef _WIN32 - return _wtoi(dat->m_wsValue); -#else - DevMsg( "TODO: implement _wtoi\n"); - return 0; -#endif - case TYPE_FLOAT: - return (int)dat->m_flValue; - case TYPE_UINT64: - // can't convert, since it would lose data - Assert(0); - return 0; - case TYPE_INT: - case TYPE_PTR: - default: - return dat->m_iValue; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the integer value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -uint64 KeyValues::GetUint64( const char *keyName, uint64 defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_STRING: - return atoi(dat->m_sValue); - case TYPE_WSTRING: -#ifdef _WIN32 - return _wtoi(dat->m_wsValue); -#else - AssertFatal( 0 ); - return 0; -#endif - case TYPE_FLOAT: - return (int)dat->m_flValue; - case TYPE_UINT64: - return *((uint64 *)dat->m_sValue); - case TYPE_INT: - case TYPE_PTR: - default: - return dat->m_iValue; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the pointer value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -void *KeyValues::GetPtr( const char *keyName, void *defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_PTR: - return dat->m_pValue; - - case TYPE_WSTRING: - case TYPE_STRING: - case TYPE_FLOAT: - case TYPE_INT: - case TYPE_UINT64: - default: - return NULL; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the float value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -float KeyValues::GetFloat( const char *keyName, float defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_STRING: - return (float)atof(dat->m_sValue); - case TYPE_WSTRING: -#ifdef _WIN32 - return (float) _wtof(dat->m_wsValue); // no wtof -#else - Assert(0); - return 0.; -#endif - case TYPE_FLOAT: - return dat->m_flValue; - case TYPE_INT: - return (float)dat->m_iValue; - case TYPE_UINT64: - return (float)(*((uint64 *)dat->m_sValue)); - case TYPE_PTR: - default: - return 0.0f; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the string pointer of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -const char *KeyValues::GetString( const char *keyName, const char *defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - // convert the data to string form then return it - char buf[64]; - switch ( dat->m_iDataType ) - { - case TYPE_FLOAT: - Q_snprintf( buf, sizeof( buf ), "%f", dat->m_flValue ); - SetString( keyName, buf ); - break; - case TYPE_INT: - case TYPE_PTR: - Q_snprintf( buf, sizeof( buf ), "%d", dat->m_iValue ); - SetString( keyName, buf ); - break; - case TYPE_UINT64: - Q_snprintf( buf, sizeof( buf ), "%llu", *((uint64 *)(dat->m_sValue)) ); - SetString( keyName, buf ); - break; - - case TYPE_WSTRING: - { -#ifdef _WIN32 - // convert the string to char *, set it for future use, and return it - char wideBuf[512]; - int result = ::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, wideBuf, 512, NULL, NULL); - if ( result ) - { - // note: this will copy wideBuf - SetString( keyName, wideBuf ); - } - else - { - return defaultValue; - } -#endif - break; - } - case TYPE_STRING: - break; - default: - return defaultValue; - }; - - return dat->m_sValue; - } - return defaultValue; -} - -const wchar_t *KeyValues::GetWString( const char *keyName, const wchar_t *defaultValue) -{ -#ifdef _WIN32 - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - wchar_t wbuf[64]; - switch ( dat->m_iDataType ) - { - case TYPE_FLOAT: - swprintf(wbuf, L"%f", dat->m_flValue); - SetWString( keyName, wbuf); - break; - case TYPE_INT: - case TYPE_PTR: - swprintf( wbuf, L"%d", dat->m_iValue ); - SetWString( keyName, wbuf ); - break; - case TYPE_UINT64: - { - swprintf( wbuf, L"%I64i", *((uint64 *)(dat->m_sValue)) ); - SetWString( keyName, wbuf ); - } - break; - - case TYPE_WSTRING: - break; - case TYPE_STRING: - { - static wchar_t wbuftemp[512]; // convert to wide - int result = ::MultiByteToWideChar(CP_UTF8, 0, dat->m_sValue, -1, wbuftemp, 512); - if ( result ) - { - SetWString( keyName, wbuftemp); - } - else - { - return defaultValue; - } - break; - } - default: - return defaultValue; - }; - - return (const wchar_t* )dat->m_wsValue; - } -#else - DevMsg("TODO: implement wide char functions\n"); -#endif - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Gets a color -//----------------------------------------------------------------------------- -Color KeyValues::GetColor( const char *keyName, const Color &defaultColor ) -{ - Color color = defaultColor; - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - if ( dat->m_iDataType == TYPE_COLOR ) - { - color[0] = dat->m_Color[0]; - color[1] = dat->m_Color[1]; - color[2] = dat->m_Color[2]; - color[3] = dat->m_Color[3]; - } - else if ( dat->m_iDataType == TYPE_FLOAT ) - { - color[0] = (unsigned char)dat->m_flValue; - } - else if ( dat->m_iDataType == TYPE_INT ) - { - color[0] = dat->m_iValue; - } - else if ( dat->m_iDataType == TYPE_STRING ) - { - // parse the colors out of the string - float a, b, c, d; - sscanf(dat->m_sValue, "%f %f %f %f", &a, &b, &c, &d); - color[0] = (unsigned char)a; - color[1] = (unsigned char)b; - color[2] = (unsigned char)c; - color[3] = (unsigned char)d; - } - } - return color; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets a color -//----------------------------------------------------------------------------- -void KeyValues::SetColor( const char *keyName, Color value) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_iDataType = TYPE_COLOR; - dat->m_Color[0] = value[0]; - dat->m_Color[1] = value[1]; - dat->m_Color[2] = value[2]; - dat->m_Color[3] = value[3]; - } -} - -void KeyValues::SetStringValue( char const *strValue ) -{ - // delete the old value - delete [] m_sValue; - // make sure we're not storing the WSTRING - as we're converting over to STRING - delete [] m_wsValue; - m_wsValue = NULL; - - if (!strValue) - { - // ensure a valid value - strValue = ""; - } - - // allocate memory for the new value and copy it in - int len = Q_strlen( strValue ); - m_sValue = new char[len + 1]; - Q_memcpy( m_sValue, strValue, len+1 ); - - m_iDataType = TYPE_STRING; -} - -//----------------------------------------------------------------------------- -// Purpose: Set the string value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetString( const char *keyName, const char *value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - // delete the old value - delete [] dat->m_sValue; - // make sure we're not storing the WSTRING - as we're converting over to STRING - delete [] dat->m_wsValue; - dat->m_wsValue = NULL; - - if (!value) - { - // ensure a valid value - value = ""; - } - - // allocate memory for the new value and copy it in - int len = Q_strlen( value ); - dat->m_sValue = new char[len + 1]; - Q_memcpy( dat->m_sValue, value, len+1 ); - - dat->m_iDataType = TYPE_STRING; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the string value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetWString( const char *keyName, const wchar_t *value ) -{ - KeyValues *dat = FindKey( keyName, true ); - if ( dat ) - { - // delete the old value - delete [] dat->m_wsValue; - // make sure we're not storing the STRING - as we're converting over to WSTRING - delete [] dat->m_sValue; - dat->m_sValue = NULL; - - if (!value) - { - // ensure a valid value - value = L""; - } - - // allocate memory for the new value and copy it in - int len = wcslen( value ); - dat->m_wsValue = new wchar_t[len + 1]; - Q_memcpy( dat->m_wsValue, value, (len+1) * sizeof(wchar_t) ); - - dat->m_iDataType = TYPE_WSTRING; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the integer value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetInt( const char *keyName, int value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_iValue = value; - dat->m_iDataType = TYPE_INT; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the integer value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetUint64( const char *keyName, uint64 value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - // delete the old value - delete [] dat->m_sValue; - // make sure we're not storing the WSTRING - as we're converting over to STRING - delete [] dat->m_wsValue; - dat->m_wsValue = NULL; - - dat->m_sValue = new char[sizeof(uint64)]; - *((uint64 *)dat->m_sValue) = value; - dat->m_iDataType = TYPE_UINT64; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the float value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetFloat( const char *keyName, float value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_flValue = value; - dat->m_iDataType = TYPE_FLOAT; - } -} - -void KeyValues::SetName( const char * setName ) -{ - m_iKeyName = KeyValuesSystem()->GetSymbolForString( setName ); -} - -//----------------------------------------------------------------------------- -// Purpose: Set the pointer value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetPtr( const char *keyName, void *value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_pValue = value; - dat->m_iDataType = TYPE_PTR; - } -} - -void KeyValues::RecursiveCopyKeyValues( KeyValues& src ) -{ - // garymcthack - need to check this code for possible buffer overruns. - - m_iKeyName = src.GetNameSymbol(); - - if( !src.m_pSub ) - { - m_iDataType = src.m_iDataType; - char buf[256]; - switch( src.m_iDataType ) - { - case TYPE_NONE: - break; - case TYPE_STRING: - if( src.m_sValue ) - { - int len = Q_strlen(src.m_sValue) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, src.m_sValue, len ); - } - break; - case TYPE_INT: - { - m_iValue = src.m_iValue; - Q_snprintf( buf,sizeof(buf), "%d", m_iValue ); - int len = Q_strlen(buf) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, buf, len ); - } - break; - case TYPE_FLOAT: - { - m_flValue = src.m_flValue; - Q_snprintf( buf,sizeof(buf), "%f", m_flValue ); - int len = Q_strlen(buf) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, buf, len ); - } - break; - case TYPE_PTR: - { - m_pValue = src.m_pValue; - } - break; - case TYPE_UINT64: - { - m_sValue = new char[sizeof(uint64)]; - Q_memcpy( m_sValue, src.m_sValue, sizeof(uint64) ); - } - break; - case TYPE_COLOR: - { - m_Color[0] = src.m_Color[0]; - m_Color[1] = src.m_Color[1]; - m_Color[2] = src.m_Color[2]; - m_Color[3] = src.m_Color[3]; - } - break; - - default: - { - // do nothing . .what the heck is this? - Assert( 0 ); - } - break; - } - - } -#if 0 - KeyValues *pDst = this; - for ( KeyValues *pSrc = src.m_pSub; pSrc; pSrc = pSrc->m_pPeer ) - { - if ( pSrc->m_pSub ) - { - pDst->m_pSub = new KeyValues( pSrc->m_pSub->getName() ); - pDst->m_pSub->RecursiveCopyKeyValues( *pSrc->m_pSub ); - } - else - { - // copy non-empty keys - if ( pSrc->m_sValue && *(pSrc->m_sValue) ) - { - pDst->m_pPeer = new KeyValues( - } - } - } -#endif - - // Handle the immediate child - if( src.m_pSub ) - { - m_pSub = new KeyValues( NULL ); - m_pSub->RecursiveCopyKeyValues( *src.m_pSub ); - } - - // Handle the immediate peer - if( src.m_pPeer ) - { - m_pPeer = new KeyValues( NULL ); - m_pPeer->RecursiveCopyKeyValues( *src.m_pPeer ); - } -} - -KeyValues& KeyValues::operator=( KeyValues& src ) -{ - RemoveEverything(); - Init(); // reset all values - RecursiveCopyKeyValues( src ); - return *this; -} - - -//----------------------------------------------------------------------------- -// Make a new copy of all subkeys, add them all to the passed-in keyvalues -//----------------------------------------------------------------------------- -void KeyValues::CopySubkeys( KeyValues *pParent ) const -{ - // recursively copy subkeys - // Also maintain ordering.... - KeyValues *pPrev = NULL; - for ( KeyValues *sub = m_pSub; sub != NULL; sub = sub->m_pPeer ) - { - // take a copy of the subkey - KeyValues *dat = sub->MakeCopy(); - - // add into subkey list - if (pPrev) - { - pPrev->m_pPeer = dat; - } - else - { - pParent->m_pSub = dat; - } - dat->m_pPeer = NULL; - pPrev = dat; - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Makes a copy of the whole key-value pair set -//----------------------------------------------------------------------------- -KeyValues *KeyValues::MakeCopy( void ) const -{ - KeyValues *newKeyValue = new KeyValues(GetName()); - - // copy data - newKeyValue->m_iDataType = m_iDataType; - switch ( m_iDataType ) - { - case TYPE_STRING: - { - if ( m_sValue ) - { - int len = Q_strlen( m_sValue ); - Assert( !newKeyValue->m_sValue ); - newKeyValue->m_sValue = new char[len + 1]; - Q_memcpy( newKeyValue->m_sValue, m_sValue, len+1 ); - } - } - break; - case TYPE_WSTRING: - { - if ( m_wsValue ) - { - int len = wcslen( m_wsValue ); - newKeyValue->m_wsValue = new wchar_t[len+1]; - Q_memcpy( newKeyValue->m_wsValue, m_wsValue, (len+1)*sizeof(wchar_t)); - } - } - break; - - case TYPE_INT: - newKeyValue->m_iValue = m_iValue; - break; - - case TYPE_FLOAT: - newKeyValue->m_flValue = m_flValue; - break; - - case TYPE_PTR: - newKeyValue->m_pValue = m_pValue; - break; - - case TYPE_COLOR: - newKeyValue->m_Color[0] = m_Color[0]; - newKeyValue->m_Color[1] = m_Color[1]; - newKeyValue->m_Color[2] = m_Color[2]; - newKeyValue->m_Color[3] = m_Color[3]; - break; - - case TYPE_UINT64: - newKeyValue->m_sValue = new char[sizeof(uint64)]; - Q_memcpy( newKeyValue->m_sValue, m_sValue, sizeof(uint64) ); - break; - }; - - // recursively copy subkeys - CopySubkeys( newKeyValue ); - return newKeyValue; -} - - -//----------------------------------------------------------------------------- -// Purpose: Check if a keyName has no value assigned to it. -//----------------------------------------------------------------------------- -bool KeyValues::IsEmpty(const char *keyName) -{ - KeyValues *dat = FindKey(keyName, false); - if (!dat) - return true; - - if (dat->m_iDataType == TYPE_NONE && dat->m_pSub == NULL) - return true; - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: Clear out all subkeys, and the current value -//----------------------------------------------------------------------------- -void KeyValues::Clear( void ) -{ - delete m_pSub; - m_pSub = NULL; - m_iDataType = TYPE_NONE; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the data type of the value stored in a keyName -//----------------------------------------------------------------------------- -KeyValues::types_t KeyValues::GetDataType(const char *keyName) -{ - KeyValues *dat = FindKey(keyName, false); - if (dat) - return (types_t)dat->m_iDataType; - - return TYPE_NONE; -} - -//----------------------------------------------------------------------------- -// Purpose: Deletion, ensures object gets deleted from correct heap -//----------------------------------------------------------------------------- -void KeyValues::deleteThis() -{ - delete this; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : includedKeys - -//----------------------------------------------------------------------------- -void KeyValues::AppendIncludedKeys( CUtlVector< KeyValues * >& includedKeys ) -{ - // Append any included keys, too... - int includeCount = includedKeys.Count(); - int i; - for ( i = 0; i < includeCount; i++ ) - { - KeyValues *kv = includedKeys[ i ]; - Assert( kv ); - - KeyValues *insertSpot = this; - while ( insertSpot->GetNextKey() ) - { - insertSpot = insertSpot->GetNextKey(); - } - - insertSpot->SetNextKey( kv ); - } -} - -void KeyValues::ParseIncludedKeys( char const *resourceName, const char *filetoinclude, - IBaseFileSystem* pFileSystem, const char *pPathID, CUtlVector< KeyValues * >& includedKeys, - GetSymbolProc_t pfnEvaluateSymbolProc ) -{ - Assert( resourceName ); - Assert( filetoinclude ); - Assert( pFileSystem ); - - // Load it... - if ( !pFileSystem ) - { - return; - } - - // Get relative subdirectory - char fullpath[ 512 ]; - Q_strncpy( fullpath, resourceName, sizeof( fullpath ) ); - - // Strip off characters back to start or first / - bool done = false; - int len = Q_strlen( fullpath ); - while ( !done ) - { - if ( len <= 0 ) - { - break; - } - - if ( fullpath[ len - 1 ] == '\\' || - fullpath[ len - 1 ] == '/' ) - { - break; - } - - // zero it - fullpath[ len - 1 ] = 0; - --len; - } - - // Append included file - Q_strncat( fullpath, filetoinclude, sizeof( fullpath ), COPY_ALL_CHARACTERS ); - - KeyValues *newKV = new KeyValues( fullpath ); - - // CUtlSymbol save = s_CurrentFileSymbol; // did that had any use ??? - - newKV->UsesEscapeSequences( m_bHasEscapeSequences != 0 ); // use same format as parent - - if ( newKV->LoadFromFile( pFileSystem, fullpath, pPathID, pfnEvaluateSymbolProc ) ) - { - includedKeys.AddToTail( newKV ); - } - else - { - DevMsg( "KeyValues::ParseIncludedKeys: Couldn't load included keyvalue file %s\n", fullpath ); - newKV->deleteThis(); - } - - // s_CurrentFileSymbol = save; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : baseKeys - -//----------------------------------------------------------------------------- -void KeyValues::MergeBaseKeys( CUtlVector< KeyValues * >& baseKeys ) -{ - int includeCount = baseKeys.Count(); - int i; - for ( i = 0; i < includeCount; i++ ) - { - KeyValues *kv = baseKeys[ i ]; - Assert( kv ); - - RecursiveMergeKeyValues( kv ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : baseKV - keyvalues we're basing ourselves on -//----------------------------------------------------------------------------- -void KeyValues::RecursiveMergeKeyValues( KeyValues *baseKV ) -{ - // Merge ourselves - // we always want to keep our value, so nothing to do here - - // Now merge our children - for ( KeyValues *baseChild = baseKV->m_pSub; baseChild != NULL; baseChild = baseChild->m_pPeer ) - { - // for each child in base, see if we have a matching kv - - bool bFoundMatch = false; - - // If we have a child by the same name, merge those keys - for ( KeyValues *newChild = m_pSub; newChild != NULL; newChild = newChild->m_pPeer ) - { - if ( !Q_strcmp( baseChild->GetName(), newChild->GetName() ) ) - { - newChild->RecursiveMergeKeyValues( baseChild ); - bFoundMatch = true; - break; - } - } - - // If not merged, append this key - if ( !bFoundMatch ) - { - KeyValues *dat = baseChild->MakeCopy(); - Assert( dat ); - AddSubKey( dat ); - } - } -} - -//----------------------------------------------------------------------------- -// Returns whether a keyvalues conditional evaluates to true or false -// Needs more flexibility with conditionals, checking convars would be nice. -//----------------------------------------------------------------------------- -bool KeyValues::EvaluateConditional( const char *str, GetSymbolProc_t pfnEvaluateSymbolProc ) -{ - bool bResult = false; - bool bXboxUI = IsX360(); - - if ( bXboxUI ) - { - bResult = !Q_stricmp( "[$X360]", str ); - } - else - { - bResult = !Q_stricmp( "[$WIN32]", str ); - } - - return bResult; -} - - -//----------------------------------------------------------------------------- -// Read from a buffer... -//----------------------------------------------------------------------------- -bool KeyValues::LoadFromBuffer( char const *resourceName, CUtlBuffer &buf, IBaseFileSystem* pFileSystem, const char *pPathID, GetSymbolProc_t pfnEvaluateSymbolProc ) -{ - KeyValues *pPreviousKey = NULL; - KeyValues *pCurrentKey = this; - CUtlVector< KeyValues * > includedKeys; - CUtlVector< KeyValues * > baseKeys; - bool wasQuoted; - bool wasConditional; - g_KeyValuesErrorStack.SetFilename( resourceName ); - do - { - bool bAccepted = true; - - // the first thing must be a key - const char *s = ReadToken( buf, wasQuoted, wasConditional ); - if ( !buf.IsValid() || !s || *s == 0 ) - break; - - if ( !Q_stricmp( s, "#include" ) ) // special include macro (not a key name) - { - s = ReadToken( buf, wasQuoted, wasConditional ); - // Name of subfile to load is now in s - - if ( !s || *s == 0 ) - { - g_KeyValuesErrorStack.ReportError("#include is NULL " ); - } - else - { - ParseIncludedKeys( resourceName, s, pFileSystem, pPathID, includedKeys, pfnEvaluateSymbolProc ); - } - - continue; - } - else if ( !Q_stricmp( s, "#base" ) ) - { - s = ReadToken( buf, wasQuoted, wasConditional ); - // Name of subfile to load is now in s - - if ( !s || *s == 0 ) - { - g_KeyValuesErrorStack.ReportError("#base is NULL " ); - } - else - { - ParseIncludedKeys( resourceName, s, pFileSystem, pPathID, baseKeys, pfnEvaluateSymbolProc ); - } - - continue; - } - - if ( !pCurrentKey ) - { - pCurrentKey = new KeyValues( s ); - Assert( pCurrentKey ); - - pCurrentKey->UsesEscapeSequences( m_bHasEscapeSequences != 0 ); // same format has parent use - - if ( pPreviousKey ) - { - pPreviousKey->SetNextKey( pCurrentKey ); - } - } - else - { - pCurrentKey->SetName( s ); - } - - // get the '{' - s = ReadToken( buf, wasQuoted, wasConditional ); - - if ( wasConditional ) - { - bAccepted = EvaluateConditional( s, pfnEvaluateSymbolProc ); - - // Now get the '{' - s = ReadToken( buf, wasQuoted, wasConditional ); - } - - if ( s && *s == '{' && !wasQuoted ) - { - // header is valid so load the file - pCurrentKey->RecursiveLoadFromBuffer( resourceName, buf, pfnEvaluateSymbolProc ); - } - else - { - g_KeyValuesErrorStack.ReportError("LoadFromBuffer: missing {" ); - } - - if ( !bAccepted ) - { - if ( pPreviousKey ) - { - pPreviousKey->SetNextKey( NULL ); - } - pCurrentKey->Clear(); - } - else - { - pPreviousKey = pCurrentKey; - pCurrentKey = NULL; - } - } while ( buf.IsValid() ); - - AppendIncludedKeys( includedKeys ); - { - // delete included keys! - int i; - for ( i = includedKeys.Count() - 1; i > 0; i-- ) - { - KeyValues *kv = includedKeys[ i ]; - kv->deleteThis(); - } - } - - MergeBaseKeys( baseKeys ); - { - // delete base keys! - int i; - for ( i = baseKeys.Count() - 1; i >= 0; i-- ) - { - KeyValues *kv = baseKeys[ i ]; - kv->deleteThis(); - } - } - - g_KeyValuesErrorStack.SetFilename( "" ); - - return true; -} - - -//----------------------------------------------------------------------------- -// Read from a buffer... -//----------------------------------------------------------------------------- -bool KeyValues::LoadFromBuffer( char const *resourceName, const char *pBuffer, IBaseFileSystem* pFileSystem, const char *pPathID, GetSymbolProc_t pfnEvaluateSymbolProc ) -{ - if ( !pBuffer ) - return true; - - int nLen = Q_strlen( pBuffer ); - CUtlBuffer buf( pBuffer, nLen, CUtlBuffer::READ_ONLY | CUtlBuffer::TEXT_BUFFER ); - return LoadFromBuffer( resourceName, buf, pFileSystem, pPathID, pfnEvaluateSymbolProc ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void KeyValues::RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &buf, GetSymbolProc_t pfnEvaluateSymbolProc ) -{ - CKeyErrorContext errorReport(this); - bool wasQuoted; - bool wasConditional; - // keep this out of the stack until a key is parsed - CKeyErrorContext errorKey( INVALID_KEY_SYMBOL ); - while ( 1 ) - { - bool bAccepted = true; - - // get the key name - const char * name = ReadToken( buf, wasQuoted, wasConditional ); - - if ( !name ) // EOF stop reading - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got EOF instead of keyname" ); - break; - } - - if ( !*name ) // empty token, maybe "" or EOF - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got empty keyname" ); - break; - } - - if ( *name == '}' && !wasQuoted ) // top level closed, stop reading - break; - - // Always create the key; note that this could potentially - // cause some duplication, but that's what we want sometimes - KeyValues *dat = CreateKey( name ); - - errorKey.Reset( dat->GetNameSymbol() ); - - // get the value - const char * value = ReadToken( buf, wasQuoted, wasConditional ); - - if ( wasConditional && value ) - { - bAccepted = EvaluateConditional( value, pfnEvaluateSymbolProc ); - - // get the real value - value = ReadToken( buf, wasQuoted, wasConditional ); - } - - if ( !value ) - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got NULL key" ); - break; - } - - if ( *value == '}' && !wasQuoted ) - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got } in key" ); - break; - } - - if ( *value == '{' && !wasQuoted ) - { - // this isn't a key, it's a section - errorKey.Reset( INVALID_KEY_SYMBOL ); - // sub value list - dat->RecursiveLoadFromBuffer( resourceName, buf, pfnEvaluateSymbolProc ); - } - else - { - if ( wasConditional ) - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got conditional between key and value" ); - break; - } - - if (dat->m_sValue) - { - delete[] dat->m_sValue; - dat->m_sValue = NULL; - } - - int len = Q_strlen( value ); - - // Here, let's determine if we got a float or an int.... - char* pIEnd; // pos where int scan ended - char* pFEnd; // pos where float scan ended - const char* pSEnd = value + len ; // pos where token ends - - int ival = strtol( value, &pIEnd, 10 ); - float fval = (float)strtod( value, &pFEnd ); - - if ( *value == 0 ) - { - dat->m_iDataType = TYPE_STRING; - } - else if ( ( 18 == len ) && ( value[0] == '0' ) && ( value[1] == 'x' ) ) - { - // an 18-byte value prefixed with "0x" (followed by 16 hex digits) is an int64 value - int64 retVal = 0; - for( int i=2; i < 2 + 16; i++ ) - { - char digit = value[i]; - if ( digit >= 'a' ) - digit -= 'a' - ( '9' + 1 ); - else - if ( digit >= 'A' ) - digit -= 'A' - ( '9' + 1 ); - retVal = ( retVal * 16 ) + ( digit - '0' ); - } - dat->m_sValue = new char[sizeof(uint64)]; - *((uint64 *)dat->m_sValue) = retVal; - dat->m_iDataType = TYPE_UINT64; - } - else if ( (pFEnd > pIEnd) && (pFEnd == pSEnd) ) - { - dat->m_flValue = fval; - dat->m_iDataType = TYPE_FLOAT; - } - else if (pIEnd == pSEnd) - { - dat->m_iValue = ival; - dat->m_iDataType = TYPE_INT; - } - else - { - dat->m_iDataType = TYPE_STRING; - } - - if (dat->m_iDataType == TYPE_STRING) - { - // copy in the string information - dat->m_sValue = new char[len+1]; - Q_memcpy( dat->m_sValue, value, len+1 ); - } - - // Look ahead one token for a conditional tag - int prevPos = buf.TellGet(); - const char *peek = ReadToken( buf, wasQuoted, wasConditional ); - if ( wasConditional ) - { - bAccepted = EvaluateConditional( peek, pfnEvaluateSymbolProc ); - } - else - { - buf.SeekGet( CUtlBuffer::SEEK_HEAD, prevPos ); - } - } - - if ( !bAccepted ) - { - this->RemoveSubKey( dat ); - dat->deleteThis(); - dat = NULL; - } - } -} - - - -// writes KeyValue as binary data to buffer -bool KeyValues::WriteAsBinary( CUtlBuffer &buffer ) -{ - if ( buffer.IsText() ) // must be a binary buffer - return false; - - if ( !buffer.IsValid() ) // must be valid, no overflows etc - return false; - - // Write subkeys: - - // loop through all our peers - for ( KeyValues *dat = this; dat != NULL; dat = dat->m_pPeer ) - { - // write type - buffer.PutUnsignedChar( dat->m_iDataType ); - - // write name - buffer.PutString( dat->GetName() ); - - // write type - switch (dat->m_iDataType) - { - case TYPE_NONE: - { - dat->m_pSub->WriteAsBinary( buffer ); - break; - } - case TYPE_STRING: - { - if (dat->m_sValue && *(dat->m_sValue)) - { - buffer.PutString( dat->m_sValue ); - } - else - { - buffer.PutString( "" ); - } - break; - } - case TYPE_WSTRING: - { - Assert( !"TYPE_WSTRING" ); - break; - } - - case TYPE_INT: - { - buffer.PutInt( dat->m_iValue ); - break; - } - - case TYPE_UINT64: - { - buffer.PutDouble( *((double *)dat->m_sValue) ); - break; - } - - case TYPE_FLOAT: - { - buffer.PutFloat( dat->m_flValue ); - break; - } - case TYPE_COLOR: - { - buffer.PutUnsignedChar( dat->m_Color[0] ); - buffer.PutUnsignedChar( dat->m_Color[1] ); - buffer.PutUnsignedChar( dat->m_Color[2] ); - buffer.PutUnsignedChar( dat->m_Color[3] ); - break; - } - case TYPE_PTR: - { - buffer.PutPtr( dat->m_pValue ); - } - - default: - break; - } - } - - // write tail, marks end of peers - buffer.PutUnsignedChar( TYPE_NUMTYPES ); - - return buffer.IsValid(); -} - -// read KeyValues from binary buffer, returns true if parsing was successful -bool KeyValues::ReadAsBinary( CUtlBuffer &buffer ) -{ - if ( buffer.IsText() ) // must be a binary buffer - return false; - - if ( !buffer.IsValid() ) // must be valid, no overflows etc - return false; - - RemoveEverything(); // remove current content - Init(); // reset - - char token[KEYVALUES_TOKEN_SIZE]; - KeyValues *dat = this; - types_t type = (types_t)buffer.GetUnsignedChar(); - - // loop through all our peers - while ( true ) - { - if ( type == TYPE_NUMTYPES ) - break; // no more peers - - dat->m_iDataType = type; - - buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); - token[KEYVALUES_TOKEN_SIZE-1] = 0; - - dat->SetName( token ); - - switch ( type ) - { - case TYPE_NONE: - { - dat->m_pSub = new KeyValues(""); - dat->m_pSub->ReadAsBinary( buffer ); - break; - } - case TYPE_STRING: - { - buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); - token[KEYVALUES_TOKEN_SIZE-1] = 0; - - int len = Q_strlen( token ); - dat->m_sValue = new char[len + 1]; - Q_memcpy( dat->m_sValue, token, len+1 ); - - break; - } - case TYPE_WSTRING: - { - Assert( !"TYPE_WSTRING" ); - break; - } - - case TYPE_INT: - { - dat->m_iValue = buffer.GetInt(); - break; - } - - case TYPE_UINT64: - { - dat->m_sValue = new char[sizeof(uint64)]; - *((double *)dat->m_sValue) = buffer.GetDouble(); - } - - case TYPE_FLOAT: - { - dat->m_flValue = buffer.GetFloat(); - break; - } - case TYPE_COLOR: - { - dat->m_Color[0] = buffer.GetUnsignedChar(); - dat->m_Color[1] = buffer.GetUnsignedChar(); - dat->m_Color[2] = buffer.GetUnsignedChar(); - dat->m_Color[3] = buffer.GetUnsignedChar(); - break; - } - case TYPE_PTR: - { - dat->m_pValue = buffer.GetPtr(); - } - - default: - break; - } - - if ( !buffer.IsValid() ) // error occured - return false; - - type = (types_t)buffer.GetUnsignedChar(); - - if ( type == TYPE_NUMTYPES ) - break; - - // new peer follows - dat->m_pPeer = new KeyValues(""); - dat = dat->m_pPeer; - } - - return buffer.IsValid(); -} - -#include "tier0/memdbgoff.h" - -#if 0 -//----------------------------------------------------------------------------- -// Purpose: memory allocator -//----------------------------------------------------------------------------- -void *KeyValues::operator new( size_t iAllocSize ) -{ - MEM_ALLOC_CREDIT(); - return KeyValuesSystem()->AllocKeyValuesMemory(); -} - -void *KeyValues::operator new( size_t iAllocSize, int nBlockUse, const char *pFileName, int nLine ) -{ - MemAlloc_PushAllocDbgInfo( pFileName, nLine ); - void *p = KeyValuesSystem()->AllocKeyValuesMemory(); - MemAlloc_PopAllocDbgInfo(); - return p; -} - -//----------------------------------------------------------------------------- -// Purpose: deallocator -//----------------------------------------------------------------------------- -void KeyValues::operator delete( void *pMem ) -{ - KeyValuesSystem()->FreeKeyValuesMemory((KeyValues *)pMem); -} - -void KeyValues::operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ) -{ - KeyValuesSystem()->FreeKeyValuesMemory((KeyValues *)pMem); -} -#endif - -void KeyValues::UnpackIntoStructure( KeyValuesUnpackStructure const *pUnpackTable, void *pDest ) -{ - uint8 *dest=(uint8 *) pDest; - while( pUnpackTable->m_pKeyName ) - { - uint8 *dest_field=dest+pUnpackTable->m_nFieldOffset; - KeyValues *find_it=FindKey( pUnpackTable->m_pKeyName ); - switch( pUnpackTable->m_eDataType ) - { - case UNPACK_TYPE_FLOAT: - { - float default_value=(pUnpackTable->m_pKeyDefault)?atof(pUnpackTable->m_pKeyDefault):0.0; - *( ( float *) dest_field)=GetFloat( pUnpackTable->m_pKeyName, default_value ); - break; - } - break; - - case UNPACK_TYPE_VECTOR: - { - Vector *dest_v=(Vector *) dest_field; - char const *src_string= - GetString( pUnpackTable->m_pKeyName, pUnpackTable->m_pKeyDefault ); - if ( (!src_string) || - ( sscanf(src_string,"%f %f %f", - &(dest_v->x), &(dest_v->y), &(dest_v->z)) != 3)) - dest_v->Init( 0, 0, 0 ); - } - break; - - case UNPACK_TYPE_FOUR_FLOATS: - { - float *dest_f=(float *) dest_field; - char const *src_string= - GetString( pUnpackTable->m_pKeyName, pUnpackTable->m_pKeyDefault ); - if ( (!src_string) || - ( sscanf(src_string,"%f %f %f %f", - dest_f,dest_f+1,dest_f+2,dest_f+3)) != 4) - memset( dest_f, 0, 4*sizeof(float) ); - } - break; - - case UNPACK_TYPE_TWO_FLOATS: - { - float *dest_f=(float *) dest_field; - char const *src_string= - GetString( pUnpackTable->m_pKeyName, pUnpackTable->m_pKeyDefault ); - if ( (!src_string) || - ( sscanf(src_string,"%f %f", - dest_f,dest_f+1)) != 2) - memset( dest_f, 0, 2*sizeof(float) ); - } - break; - - case UNPACK_TYPE_STRING: - { - char *dest_s=(char *) dest_field; - strncpy( dest_s, GetString( pUnpackTable->m_pKeyName, - pUnpackTable->m_pKeyDefault ), - pUnpackTable->m_nFieldSize ); - - } - break; - - case UNPACK_TYPE_INT: - { - int *dest_i=(int *) dest_field; - int default_int=0; - if ( pUnpackTable->m_pKeyDefault) - default_int = atoi( pUnpackTable->m_pKeyDefault ); - *(dest_i)=GetInt( pUnpackTable->m_pKeyName, default_int ); - } - break; - - case UNPACK_TYPE_VECTOR_COLOR: - { - Vector *dest_v=(Vector *) dest_field; - if (find_it) - { - Color c=GetColor( pUnpackTable->m_pKeyName ); - dest_v->x = c.r(); - dest_v->y = c.g(); - dest_v->z = c.b(); - } - else - { - if ( pUnpackTable->m_pKeyDefault ) - sscanf(pUnpackTable->m_pKeyDefault,"%f %f %f", - &(dest_v->x), &(dest_v->y), &(dest_v->z)); - else - dest_v->Init( 0, 0, 0 ); - } - *(dest_v) *= (1.0/255); - } - } - pUnpackTable++; - } -} - -//----------------------------------------------------------------------------- -// Helper function for processing a keyvalue tree for console resolution support. -// Alters key/values for easier console video resolution support. -// If running SD (640x480), the presence of "???_lodef" creates or slams "???". -// If running HD (1280x720), the presence of "???_hidef" creates or slams "???". -//----------------------------------------------------------------------------- -bool KeyValues::ProcessResolutionKeys( const char *pResString ) -{ - if ( !pResString ) - { - // not for pc, console only - return false; - } - - KeyValues *pSubKey = GetFirstSubKey(); - if ( !pSubKey ) - { - // not a block - return false; - } - - for ( ; pSubKey != NULL; pSubKey = pSubKey->GetNextKey() ) - { - // recursively descend each sub block - pSubKey->ProcessResolutionKeys( pResString ); - - // check to see if our substring is present - if ( Q_stristr( pSubKey->GetName(), pResString ) != NULL ) - { - char normalKeyName[128]; - V_strncpy( normalKeyName, pSubKey->GetName(), sizeof( normalKeyName ) ); - - // substring must match exactly, otherwise keys like "_lodef" and "_lodef_wide" would clash. - char *pString = Q_stristr( normalKeyName, pResString ); - if ( pString && !Q_stricmp( pString, pResString ) ) - { - *pString = '\0'; - - // find and delete the original key (if any) - KeyValues *pKey = FindKey( normalKeyName ); - if ( pKey ) - { - // remove the key - RemoveSubKey( pKey ); - } - - // rename the marked key - pSubKey->SetName( normalKeyName ); - } - } - } - - return true; -} diff --git a/tier1/tier1.vcxproj b/tier1/tier1.vcxproj index 497be0cd..7ac9bfc3 100644 --- a/tier1/tier1.vcxproj +++ b/tier1/tier1.vcxproj @@ -30,7 +30,7 @@ StaticLibrary - v120 + v140 StaticLibrary @@ -327,7 +327,6 @@ - diff --git a/tier1/tier1.vcxproj.filters b/tier1/tier1.vcxproj.filters index 5f57bdbe..3811c24f 100644 --- a/tier1/tier1.vcxproj.filters +++ b/tier1/tier1.vcxproj.filters @@ -41,9 +41,6 @@ Source Files - - Source Files - Source Files