diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /common/GameUI/scriptobject.cpp | |
| download | archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip | |
Diffstat (limited to 'common/GameUI/scriptobject.cpp')
| -rw-r--r-- | common/GameUI/scriptobject.cpp | 1153 |
1 files changed, 1153 insertions, 0 deletions
diff --git a/common/GameUI/scriptobject.cpp b/common/GameUI/scriptobject.cpp new file mode 100644 index 0000000..e83f5fd --- /dev/null +++ b/common/GameUI/scriptobject.cpp @@ -0,0 +1,1153 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +// CScriptObject and CDescription class definitions +// +#include "scriptobject.h" +#include <time.h> +#include <stdio.h> +#include <stdlib.h> +#include <vgui_controls/Label.h> +#include "filesystem.h" +#include "tier1/convar.h" +#include "cdll_int.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace vgui; +static char token[ 1024 ]; + +extern IVEngineClient *engine; + +void StripFloatTrailingZeros(char *str) +{ + // scan for a '.' + char *period = strchr(str, '.'); + if (!period) + return; + + // start at the end and scan back to the period + char *end = 0; + for ( end = str + strlen(str) - 1; end > period; --end ) + { + if (*end == '0') + { + *end = '\0'; + } + else + { + // we've hit a real value, stop truncating + break; + } + } + + // if we've made it up to the period, kill that to + if ( *end == '.' ) + { + *end = '\0'; + } +} + +///////////////////// +objtypedesc_t objtypes[] = +{ + { O_BOOL , "BOOL" }, + { O_NUMBER, "NUMBER" }, + { O_LIST , "LIST" }, + { O_STRING, "STRING" }, + { O_OBSOLETE , "OBSOLETE" }, + { O_SLIDER , "SLIDER" }, + { O_CATEGORY, "CATEGORY" }, +}; + +mpcontrol_t::mpcontrol_t( Panel *parent, char const *panelName ) +: Panel( parent, panelName ) +{ + type = O_BADTYPE; + pControl = NULL; + pPrompt = NULL; + pScrObj = NULL; + + next = NULL; + + SetPaintBackgroundEnabled( false ); +} + +void mpcontrol_t::OnSizeChanged( int wide, int tall ) +{ + int inset = 4; + + if ( pPrompt ) + { + int w = wide / 2; + + if ( pControl ) + { + pControl->SetBounds( w + 20, inset, w - 20, tall - 2 * inset ); + } + pPrompt->SetBounds( 0, inset, w + 20, tall - 2 * inset ); + } + else + { + if ( pControl ) + { + pControl->SetBounds( 0, inset, wide, tall - 2 * inset ); + } + } +} + +CScriptListItem::CScriptListItem() +{ + pNext = NULL; + memset( szItemText, 0, 128 ); + memset( szValue, 0, 256 ); +} + +CScriptListItem::CScriptListItem( char const *strItem, char const *strValue ) +{ + pNext = NULL; + Q_strncpy( szItemText, strItem, sizeof( szItemText ) ); + Q_strncpy( szValue , strValue, sizeof( szValue ) ); +} + +CScriptObject::CScriptObject( void ) +{ + type = O_BOOL; + bSetInfo = false; // Prepend "Setinfo" to keyvalue pair in config? + pNext = NULL; + pListItems = NULL; + tooltip[0] = '\0'; +} + +CScriptObject::~CScriptObject() +{ + RemoveAndDeleteAllItems(); +} + +void CScriptObject::RemoveAndDeleteAllItems( void ) +{ + CScriptListItem *p, *n; + + p = pListItems; + while ( p ) + { + n = p->pNext; + delete p; + p = n; + } + pListItems = NULL; +} + +void CScriptObject::SetCurValue( char const *strValue ) +{ + Q_strncpy( curValue, strValue, sizeof( curValue ) ); + + fcurValue = (float)atof( curValue ); + + if ( type == O_NUMBER || type == O_BOOL || type == O_SLIDER ) + { + StripFloatTrailingZeros( curValue ); + } +} + +void CScriptObject::AddItem( CScriptListItem *pItem ) +{ + // Link it into the end of the list; + CScriptListItem *p; + p = pListItems; + if ( !p ) + { + pListItems = pItem; + pItem->pNext = NULL; + return; + } + + while ( p ) + { + if ( !p->pNext ) + { + p->pNext = pItem; + pItem->pNext = NULL; + return; + } + p = p->pNext; + } +} + +/* +=================== +UTIL_StripInvalidCharacters + +Removes any possible formatting codes and double quote characters from the input string +=================== +*/ +void UTIL_StripInvalidCharacters( char *pszInput, int maxlen ) +{ + char szOutput[4096]; + char *pIn, *pOut; + + pIn = pszInput; + pOut = szOutput; + + *pOut = '\0'; + + while ( *pIn ) + { + if ( ( *pIn != '"' ) && + ( *pIn != '%' ) ) + { + *pOut++ = *pIn; + } + pIn++; + } + + *pOut = '\0'; + + // Copy back over, in place + Q_strncpy( pszInput, szOutput, maxlen ); +} + +void FixupString( char *inString, int maxlen ) +{ + char szBuffer[ 4096 ]; + Q_strncpy( szBuffer, inString, sizeof( szBuffer ) ); + UTIL_StripInvalidCharacters( szBuffer, sizeof( szBuffer ) ); + Q_strncpy( inString, szBuffer, maxlen ); +} + +/* +=================== +CleanFloat + +Removes any ".000" from the end of floats +=================== +*/ +char * CleanFloat( float val ) +{ + static int curstring = 0; + static char string[2][32]; + curstring = ( curstring + 1 ) % 2; + + Q_snprintf( string[curstring], sizeof( string[curstring] ), "%f", val ); + + char * str = string[curstring]; + + char * tmp = str; + if ( !str || !*str || !strchr( str, '.' ) ) + return str; + + while ( *tmp ) + ++tmp; + --tmp; + + while ( *tmp == '0' && tmp > str ) + { + *tmp = 0; + --tmp; + } + + if ( *tmp == '.' ) + { + *tmp = 0; + } + + return str; +} + +void CScriptObject::WriteToScriptFile( FileHandle_t fp ) +{ + if ( type == O_OBSOLETE ) + return; + + FixupString( cvarname, sizeof( cvarname ) ); + g_pFullFileSystem->FPrintf( fp, "\t\"%s\"\r\n", cvarname ); + + g_pFullFileSystem->FPrintf( fp, "\t{\r\n" ); + + CScriptListItem *pItem; + + FixupString( prompt, sizeof( prompt ) ); + FixupString( tooltip, sizeof( tooltip ) ); + + switch ( type ) + { + case O_BOOL: + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", prompt ); + if ( tooltip && tooltip[0] ) + { + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", tooltip ); + } + g_pFullFileSystem->FPrintf( fp, "\t\t{ BOOL }\r\n" ); + g_pFullFileSystem->FPrintf( fp, "\t\t{ \"%i\" }\r\n", (int)fcurValue ? 1 : 0 ); + break; + case O_NUMBER: + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", prompt ); + if ( tooltip && tooltip[0] ) + { + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", tooltip ); + } + g_pFullFileSystem->FPrintf( fp, "\t\t{ NUMBER %s %s }\r\n", CleanFloat(fMin), CleanFloat(fMax) ); + g_pFullFileSystem->FPrintf( fp, "\t\t{ \"%s\" }\r\n", CleanFloat(fcurValue) ); + break; + case O_STRING: + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", prompt ); + if ( tooltip && tooltip[0] ) + { + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", tooltip ); + } + g_pFullFileSystem->FPrintf( fp, "\t\t{ STRING }\r\n" ); + FixupString( curValue, sizeof( curValue ) ); + g_pFullFileSystem->FPrintf( fp, "\t\t{ \"%s\" }\r\n", curValue ); + break; + case O_LIST: + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", prompt ); + if ( tooltip && tooltip[0] ) + { + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", tooltip ); + } + g_pFullFileSystem->FPrintf( fp, "\t\t{\r\n\t\t\tLIST\r\n" ); + + pItem = pListItems; + while ( pItem ) + { + UTIL_StripInvalidCharacters( pItem->szItemText, sizeof( pItem->szItemText ) ); + UTIL_StripInvalidCharacters( pItem->szValue, sizeof( pItem->szValue ) ); + g_pFullFileSystem->FPrintf( fp, "\t\t\t\"%s\" \"%s\"\r\n", + pItem->szItemText, pItem->szValue ); + + pItem = pItem->pNext; + } + + g_pFullFileSystem->FPrintf( fp, "\t\t}\r\n"); + g_pFullFileSystem->FPrintf( fp, "\t\t{ \"%s\" }\r\n", CleanFloat(fcurValue) ); + break; + case O_SLIDER: + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", prompt ); + if ( tooltip && tooltip[0] ) + { + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", tooltip ); + } + g_pFullFileSystem->FPrintf( fp, "\t\t{ SLIDER %s %s }\r\n", CleanFloat(fMin), CleanFloat(fMax) ); + g_pFullFileSystem->FPrintf( fp, "\t\t{ \"%s\" }\r\n", CleanFloat(fcurValue) ); + break; + case O_CATEGORY: + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", prompt ); + if ( tooltip && tooltip[0] ) + { + g_pFullFileSystem->FPrintf( fp, "\t\t\"%s\"\r\n", tooltip ); + } + g_pFullFileSystem->FPrintf( fp, "\t\t{ CATEGORY }\r\n" ); + break; + } + + if ( bSetInfo ) + g_pFullFileSystem->FPrintf( fp, "\t\tSetInfo\r\n" ); + + g_pFullFileSystem->FPrintf( fp, "\t}\r\n\r\n" ); +} + +void CScriptObject::WriteToFile( FileHandle_t fp ) +{ + if ( type == O_OBSOLETE || type == O_CATEGORY ) + return; + + FixupString( cvarname, sizeof( cvarname ) ); + g_pFullFileSystem->FPrintf( fp, "\"%s\"\t\t", cvarname ); + + CScriptListItem *pItem; + float fVal; + + switch ( type ) + { + case O_BOOL: + g_pFullFileSystem->FPrintf( fp, "\"%s\"\r\n", fcurValue != 0.0 ? "1" : "0" ); + break; + case O_NUMBER: + case O_SLIDER: + fVal = fcurValue; + if ( fMin != -1.0 ) + fVal = max( fVal, fMin ); + if ( fMax != -1.0 ) + fVal = min( fVal, fMax ); + g_pFullFileSystem->FPrintf( fp, "\"%f\"\r\n", fVal ); + break; + case O_STRING: + FixupString( curValue, sizeof( curValue ) ); + g_pFullFileSystem->FPrintf( fp, "\"%s\"\r\n", curValue ); + break; + case O_LIST: + pItem = pListItems; + while ( pItem ) + { + if ( !Q_stricmp( pItem->szValue, curValue ) ) + break; + + pItem = pItem->pNext; + } + + if ( pItem ) + { + UTIL_StripInvalidCharacters( pItem->szValue, sizeof( pItem->szValue ) ); + g_pFullFileSystem->FPrintf( fp, "\"%s\"\r\n", pItem->szValue ); + } + else //Couln't find index + { + g_pFullFileSystem->FPrintf( fp, "\"0\"\r\n" ); + } + break; + } +} + +void CScriptObject::WriteToConfig( void ) +{ + if ( type == O_OBSOLETE || type == O_CATEGORY ) + return; + + char *pszKey; + char szValue[2048]; + + pszKey = ( char * )cvarname; + + CScriptListItem *pItem; + float fVal; + + switch ( type ) + { + case O_BOOL: + Q_snprintf( szValue, sizeof( szValue ), "%s", fcurValue != 0.0 ? "1" : "0" ); + break; + case O_NUMBER: + case O_SLIDER: + fVal = fcurValue; + if ( fMin != -1.0 ) + fVal = max( fVal, fMin ); + if ( fMax != -1.0 ) + fVal = min( fVal, fMax ); + Q_snprintf( szValue, sizeof( szValue ), "%f", fVal ); + break; + case O_STRING: + Q_snprintf( szValue, sizeof( szValue ), "\"%s\"", (char *)curValue ); + UTIL_StripInvalidCharacters( szValue, sizeof( szValue ) ); + break; + case O_LIST: + pItem = pListItems; + while ( pItem ) + { + if ( !Q_stricmp( pItem->szValue, curValue ) ) + break; + + pItem = pItem->pNext; + } + + if ( pItem ) + { + Q_snprintf( szValue, sizeof( szValue ), "%s", pItem->szValue ); + UTIL_StripInvalidCharacters( szValue, sizeof( szValue ) ); + } + else //Couldn't find index + { + Q_strncpy( szValue, "0", sizeof( szValue ) ); + } + break; + } + + char command[ 256 ]; + if ( bSetInfo ) + { + Q_snprintf( command, sizeof(command), "setinfo %s \"%s\"\n", pszKey, szValue ); + } + else + { + Q_snprintf( command, sizeof(command), "%s \"%s\"\n", pszKey, szValue ); + } + + engine->ClientCmd_Unrestricted( command ); + + // CFG_SetKey( g_szCurrentConfigFile, pszKey, szValue, bSetInfo ); +} + + +objtype_t CScriptObject::GetType( char *pszType ) +{ + int i; + int nTypes; + + nTypes = sizeof( objtypes ) / sizeof( objtypedesc_t); + + for ( i = 0; i < nTypes; i++ ) + { + if ( !stricmp( objtypes[i].szDescription, pszType ) ) + return objtypes[i].type; + } + + return O_BADTYPE; +} + +bool CScriptObject::ReadFromBuffer( const char **pBuffer, bool isNewObject ) +{ + // Get the first token. + // The cvar we are setting + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( isNewObject ) + { + Q_strncpy( cvarname, token, sizeof( cvarname ) ); + } + + // Parse the { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( strcmp( token, "{" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + + // Parse the Prompt + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( isNewObject ) + { + Q_strncpy( prompt, token, sizeof( prompt ) ); + } + + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + // If it's not a {, consider it the optional tooltip + if ( strcmp( token, "{" ) ) + { + Q_strncpy( tooltip, token, sizeof( tooltip ) ); + + // Parse the next { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + } + + if ( strcmp( token, "{" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + + // Now parse the type: + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + objtype_t newType = GetType( token ); + if ( isNewObject ) + { + type = newType; + } + if ( newType == O_BADTYPE ) + { + Msg( "Type '%s' unknown", token ); + return false; + } + + // If it's a category, we're done. + if ( newType == O_CATEGORY ) + { + // Parse the } + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + if ( strcmp( token, "}" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + + // Parse the final } + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + if ( strcmp( token, "}" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + return true; + } + + switch ( newType ) + { + case O_OBSOLETE: + case O_BOOL: + // Parse the next { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( strcmp( token, "}" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + break; + case O_NUMBER: + case O_SLIDER: + // Parse the Min + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( isNewObject ) + { + fMin = (float)atof( token ); + } + + // Parse the Min + *pBuffer = engine->ParseFile( *pBuffer, token , sizeof( token )); + if ( strlen( token ) <= 0 ) + return false; + + if ( isNewObject ) + { + fMax = (float)atof( token ); + } + + // Parse the next { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( strcmp( token, "}" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + break; + case O_STRING: + // Parse the next { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( strcmp( token, "}" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + break; + case O_LIST: + // Parse items until we get the } + while ( 1 ) + { + // Parse the next { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + // Done? + if ( !strcmp( token, "}" ) ) + break; + + // + // Add the item to a list somewhere + // AddItem( token ) + char strItem[ 128 ]; + char strValue[128]; + + Q_strncpy( strItem, token, sizeof( strItem ) ); + + // Parse the value + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + Q_strncpy( strValue, token, sizeof( strValue ) ); + + if ( isNewObject ) + { + CScriptListItem *pItem; + pItem = new CScriptListItem( strItem, strValue ); + + AddItem( pItem ); + } + } + break; + } + + // + // Now read in the default value + + // Parse the { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( strcmp( token, "{" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + + // Parse the default + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + //if ( strlen( token ) <= 0 ) + // return false; + + // Set the values + Q_strncpy( defValue, token, sizeof( defValue ) ); + fdefValue = (float)atof( token ); + + if (type == O_NUMBER || type == O_SLIDER) + { + StripFloatTrailingZeros( defValue ); + } + + SetCurValue( defValue ); + + // Parse the } + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( strcmp( token, "}" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + + // Parse the final } + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( !stricmp( token, "SetInfo" ) ) + { + bSetInfo = true; + // Parse the final } + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + } + + if ( strcmp( token, "}" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + + return true; +} + +///////////////////////// +CDescription::CDescription( void ) +{ + pObjList = NULL; +} + +CDescription::~CDescription() +{ + CScriptObject *p, *n; + + p = pObjList; + while ( p ) + { + n = p->pNext; + p->pNext = NULL; + p->MarkForDeletion(); + //delete p; + p = n; + } + + pObjList = NULL; + + if ( m_pszHintText ) + free( m_pszHintText ); + if ( m_pszDescriptionType ) + free( m_pszDescriptionType ); +} + +CScriptObject * CDescription::FindObject( const char *pszObjectName ) +{ + if ( !pszObjectName ) + return NULL; + + CScriptObject *p; + p = pObjList; + while ( p ) + { + if ( !stricmp( pszObjectName, p->cvarname ) ) + return p; + p = p->pNext; + } + return NULL; +} + +void CDescription::AddObject( CScriptObject *pObj ) +{ + CScriptObject *p; + p = pObjList; + if ( !p ) + { + pObjList = pObj; + pObj->pNext = NULL; + return; + } + + while ( p ) + { + if ( !p->pNext ) + { + p->pNext = pObj; + pObj->pNext = NULL; + return; + } + p = p->pNext; + } +} + +bool CDescription::ReadFromBuffer( const char **pBuffer, bool bAllowNewObject ) +{ + // Get the first token. + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + // Read VERSION # + if ( stricmp ( token, "VERSION" ) ) + { + Msg( "Expecting 'VERSION', got '%s'", token ); + return false; + } + + // Parse in the version # + // Get the first token. + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + { + Msg( "Expecting version #" ); + return false; + } + + float fVer; + fVer = (float)atof( token ); + + if ( fVer != SCRIPT_VERSION ) + { + Msg( "Version mismatch, expecting %f, got %f", SCRIPT_VERSION, fVer ); + return false; + } + + // Get the "DESCRIPTION" + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + // Read DESCRIPTION + if ( stricmp ( token, "DESCRIPTION" ) ) + { + Msg( "Expecting 'DESCRIPTION', got '%s'", token ); + return false; + } + + // Parse in the description type + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + { + Msg( "Expecting '%s'", m_pszDescriptionType ); + return false; + } + + if ( stricmp ( token, m_pszDescriptionType ) ) + { + Msg( "Expecting %s, got %s", m_pszDescriptionType, token ); + return false; + } + + // Parse the { + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + if ( strcmp( token, "{" ) ) + { + Msg( "Expecting '{', got '%s'", token ); + return false; + } + + const char *pStart; + CScriptObject *pObj; + // Now read in the objects and link them in + while ( 1 ) + { + pStart = *pBuffer; + + // Get the first token. + *pBuffer = engine->ParseFile( *pBuffer, token, sizeof( token ) ); + if ( strlen( token ) <= 0 ) + return false; + + // Read "cvar name" or } when done + if ( !stricmp ( token, "}" ) ) + break; + + // Unget the token + *pBuffer = pStart; + + // Create a new object + bool mustAdd = bAllowNewObject; + pObj = FindObject( token ); + if ( pObj ) + { + pObj->ReadFromBuffer( &pStart, false ); + mustAdd = false; // already in list + } + else + { + pObj = new CScriptObject(); + if ( !pObj ) + { + Msg( "Couldn't create script object" ); + return false; + } + + if ( !pObj->ReadFromBuffer( &pStart, true ) ) + { + delete pObj; + return false; + } + + // throw away the object if we're not adding it. + if ( !mustAdd ) + { + delete pObj; + } + } + + *pBuffer = pStart; + + // Add to list + // Fixme, move to end of list first + if ( mustAdd ) + { + AddObject( pObj ); + } + } + + return true; +} + +bool CDescription::InitFromFile( const char *pszFileName, bool bAllowNewObject /*= true*/ ) +{ + + // Load file into memory + FileHandle_t file = g_pFullFileSystem->Open( pszFileName, "rb" ); + if ( !file ) + return false; + + int len =g_pFullFileSystem->Size( file ); + + // read the file + byte *buffer = new unsigned char[ len ]; + Assert( buffer ); + g_pFullFileSystem->Read( buffer, len, file ); + g_pFullFileSystem->Close( file ); + + const char *pBuffer = (const char*)buffer; + + ReadFromBuffer( &pBuffer, bAllowNewObject ); + + delete[] buffer; + + return true; +} + +void CDescription::WriteToFile( FileHandle_t fp ) +{ + CScriptObject *pObj; + + WriteFileHeader( fp ); + + pObj = pObjList; + while ( pObj ) + { + pObj->WriteToFile( fp ); + pObj = pObj->pNext; + } +} + +void CDescription::WriteToConfig( void ) +{ + CScriptObject *pObj; + + pObj = pObjList; + while ( pObj ) + { + pObj->WriteToConfig(); + pObj = pObj->pNext; + } +} + +void CDescription::WriteToScriptFile( FileHandle_t fp ) +{ + CScriptObject *pObj; + + WriteScriptHeader( fp ); + + pObj = pObjList; + while ( pObj ) + { + pObj->WriteToScriptFile( fp ); + pObj = pObj->pNext; + } + + g_pFullFileSystem->FPrintf( fp, "}\r\n" ); +} + +void CDescription::TransferCurrentValues( const char *pszConfigFile ) +{ + char szValue[ 1024 ]; + + CScriptObject *pObj; + + pObj = pObjList; + while ( pObj ) + { + + /* + TODO: if/when prefixed keys are implemented + const char *value; + if ( pObj->bSetInfo ) + { + value = engine->LocalPlayerInfo_ValueForKey( pObj->cvarname ); // use LocalPlayerInfo because PlayerInfo strips keys prefixed with "_" + } + else + { + value = engine->pfnGetCvarString( pObj->cvarname ); + } + */ + + ConVarRef var( pObj->cvarname, true ); + if ( !var.IsValid() ) + { + if ( pObj->type != O_CATEGORY ) + { + DevMsg( "Could not find '%s'\n", pObj->cvarname ); + } + pObj = pObj->pNext; + continue; + } + const char *value = var.GetString(); + + if ( value && value[ 0 ] ) + //if ( CFG_GetValue( pszConfigFile, pObj->cvarname, szValue ) ) + { + Q_strncpy( szValue, value, sizeof( szValue ) ); + + // Fill in better default value + // + Q_strncpy( pObj->curValue, szValue, sizeof( pObj->curValue ) ); + pObj->fcurValue = (float)atof( szValue ); + + Q_strncpy( pObj->defValue, szValue, sizeof( pObj->defValue ) ); + pObj->fdefValue = (float)atof( szValue ); + } + + pObj = pObj->pNext; + } +} + +void CDescription::setDescription( const char *pszDesc ) +{ + m_pszDescriptionType = strdup( pszDesc ); +} + +void CDescription::setHint( const char *pszHint ) +{ + m_pszHintText = strdup( pszHint ); +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor, load/save client settings object +//----------------------------------------------------------------------------- +CInfoDescription::CInfoDescription( void ) + : CDescription( ) +{ + setHint( "// NOTE: THIS FILE IS AUTOMATICALLY REGENERATED, \r\n\ +//DO NOT EDIT THIS HEADER, YOUR COMMENTS WILL BE LOST IF YOU DO\r\n\ +// User options script\r\n\ +//\r\n\ +// Format:\r\n\ +// Version [float]\r\n\ +// Options description followed by \r\n\ +// Options defaults\r\n\ +//\r\n\ +// Option description syntax:\r\n\ +//\r\n\ +// \"cvar\" { \"Prompt\" { type [ type info ] } { default } }\r\n\ +//\r\n\ +// type = \r\n\ +// BOOL (a yes/no toggle)\r\n\ +// STRING\r\n\ +// NUMBER\r\n\ +// LIST\r\n\ +//\r\n\ +// type info:\r\n\ +// BOOL no type info\r\n\ +// NUMBER min max range, use -1 -1 for no limits\r\n\ +// STRING no type info\r\n\ +// LIST "" delimited list of options value pairs\r\n\ +//\r\n\ +//\r\n\ +// default depends on type\r\n\ +// BOOL is \"0\" or \"1\"\r\n\ +// NUMBER is \"value\"\r\n\ +// STRING is \"value\"\r\n\ +// LIST is \"index\", where index \"0\" is the first element of the list\r\n\r\n\r\n" ); + + setDescription( "INFO_OPTIONS" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInfoDescription::WriteScriptHeader( FileHandle_t fp ) +{ + char am_pm[] = "AM"; + tm newtime; + VCRHook_LocalTime( &newtime ); + + g_pFullFileSystem->FPrintf( fp, (char *)getHint() ); + +// Write out the comment and Cvar Info: + g_pFullFileSystem->FPrintf( fp, "// Half-Life User Info Configuration Layout Script (stores last settings chosen, too)\r\n" ); + g_pFullFileSystem->FPrintf( fp, "// File generated: %.19s %s\r\n", asctime( &newtime ), am_pm ); + g_pFullFileSystem->FPrintf( fp, "//\r\n//\r\n// Cvar\t-\tSetting\r\n\r\n" ); + g_pFullFileSystem->FPrintf( fp, "VERSION %.1f\r\n\r\n", SCRIPT_VERSION ); + g_pFullFileSystem->FPrintf( fp, "DESCRIPTION INFO_OPTIONS\r\n{\r\n" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInfoDescription::WriteFileHeader( FileHandle_t fp ) +{ + char am_pm[] = "AM"; + tm newtime; + VCRHook_LocalTime( &newtime ); + + g_pFullFileSystem->FPrintf( fp, "// Half-Life User Info Configuration Settings\r\n" ); + g_pFullFileSystem->FPrintf( fp, "// DO NOT EDIT, GENERATED BY HALF-LIFE\r\n" ); + g_pFullFileSystem->FPrintf( fp, "// File generated: %.19s %s\r\n", asctime( &newtime ), am_pm ); + g_pFullFileSystem->FPrintf( fp, "//\r\n//\r\n// Cvar\t-\tSetting\r\n\r\n" ); +} + +//-----------------------------------------------------------------------------
\ No newline at end of file |