summaryrefslogtreecommitdiff
path: root/common/GameUI
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /common/GameUI
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'common/GameUI')
-rw-r--r--common/GameUI/IGameConsole.h41
-rw-r--r--common/GameUI/IGameUI.h121
-rw-r--r--common/GameUI/ObjectList.cpp243
-rw-r--r--common/GameUI/ObjectList.h58
-rw-r--r--common/GameUI/Random.cpp131
-rw-r--r--common/GameUI/Random.h30
-rw-r--r--common/GameUI/cvarslider.cpp334
-rw-r--r--common/GameUI/cvarslider.h63
-rw-r--r--common/GameUI/scriptobject.cpp1153
-rw-r--r--common/GameUI/scriptobject.h155
10 files changed, 2329 insertions, 0 deletions
diff --git a/common/GameUI/IGameConsole.h b/common/GameUI/IGameConsole.h
new file mode 100644
index 0000000..a18f331
--- /dev/null
+++ b/common/GameUI/IGameConsole.h
@@ -0,0 +1,41 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//===========================================================================//
+
+#ifndef IGAMECONSOLE_H
+#define IGAMECONSOLE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier1/interface.h"
+
+
+//-----------------------------------------------------------------------------
+// Purpose: interface to game/dev console
+//-----------------------------------------------------------------------------
+abstract_class IGameConsole : public IBaseInterface
+{
+public:
+ // activates the console, makes it visible and brings it to the foreground
+ virtual void Activate() = 0;
+
+ virtual void Initialize() = 0;
+
+ // hides the console
+ virtual void Hide() = 0;
+
+ // clears the console
+ virtual void Clear() = 0;
+
+ // return true if the console has focus
+ virtual bool IsConsoleVisible() = 0;
+
+ virtual void SetParent( int parent ) = 0;
+};
+
+#define GAMECONSOLE_INTERFACE_VERSION "GameConsole004"
+
+#endif // IGAMECONSOLE_H
diff --git a/common/GameUI/IGameUI.h b/common/GameUI/IGameUI.h
new file mode 100644
index 0000000..99967f4
--- /dev/null
+++ b/common/GameUI/IGameUI.h
@@ -0,0 +1,121 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef IGAMEUI_H
+#define IGAMEUI_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "interface.h"
+#include "vgui/IPanel.h"
+
+#if !defined( _X360 )
+#include "xbox/xboxstubs.h"
+#endif
+
+// reasons why the user can't connect to a game server
+enum ESteamLoginFailure
+{
+ STEAMLOGINFAILURE_NONE,
+ STEAMLOGINFAILURE_BADTICKET,
+ STEAMLOGINFAILURE_NOSTEAMLOGIN,
+ STEAMLOGINFAILURE_VACBANNED,
+ STEAMLOGINFAILURE_LOGGED_IN_ELSEWHERE
+};
+
+enum ESystemNotify
+{
+ SYSTEMNOTIFY_STORAGEDEVICES_CHANGED,
+ SYSTEMNOTIFY_USER_SIGNEDIN,
+ SYSTEMNOTIFY_USER_SIGNEDOUT,
+ SYSTEMNOTIFY_XUIOPENING,
+ SYSTEMNOTIFY_XUICLOSED,
+ SYSTEMNOTIFY_INVITE_SHUTDOWN, // Cross-game invite is causing us to shutdown
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: contains all the functions that the GameUI dll exports
+//-----------------------------------------------------------------------------
+abstract_class IGameUI
+{
+public:
+ // initialization/shutdown
+ virtual void Initialize( CreateInterfaceFn appFactory ) = 0;
+ virtual void PostInit() = 0;
+
+ // connect to other interfaces at the same level (gameui.dll/server.dll/client.dll)
+ virtual void Connect( CreateInterfaceFn gameFactory ) = 0;
+
+ virtual void Start() = 0;
+ virtual void Shutdown() = 0;
+ virtual void RunFrame() = 0;
+
+ // notifications
+ virtual void OnGameUIActivated() = 0;
+ virtual void OnGameUIHidden() = 0;
+
+ // OLD: Use OnConnectToServer2
+ virtual void OLD_OnConnectToServer(const char *game, int IP, int port) = 0;
+
+ virtual void OnDisconnectFromServer_OLD( uint8 eSteamLoginFailure, const char *username ) = 0;
+ virtual void OnLevelLoadingStarted(bool bShowProgressDialog) = 0;
+ virtual void OnLevelLoadingFinished(bool bError, const char *failureReason, const char *extendedReason) = 0;
+
+ // level loading progress, returns true if the screen needs updating
+ virtual bool UpdateProgressBar(float progress, const char *statusText) = 0;
+ // Shows progress desc, returns previous setting... (used with custom progress bars )
+ virtual bool SetShowProgressText( bool show ) = 0;
+
+ // !!!!!!!!!members added after "GameUI011" initial release!!!!!!!!!!!!!!!!!!!
+ virtual void ShowNewGameDialog( int chapter ) = 0;
+
+ // Xbox 360
+ virtual void SessionNotification( const int notification, const int param = 0 ) = 0;
+ virtual void SystemNotification( const int notification ) = 0;
+ virtual void ShowMessageDialog( const uint nType, vgui::Panel *pOwner ) = 0;
+ virtual void UpdatePlayerInfo( uint64 nPlayerId, const char *pName, int nTeam, byte cVoiceState, int nPlayersNeeded, bool bHost ) = 0;
+ virtual void SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping ) = 0;
+ virtual void OnCreditsFinished( void ) = 0;
+
+ // inserts specified panel as background for level load dialog
+ virtual void SetLoadingBackgroundDialog( vgui::VPANEL panel ) = 0;
+
+ // Bonus maps interfaces
+ virtual void BonusMapUnlock( const char *pchFileName = NULL, const char *pchMapName = NULL ) = 0;
+ virtual void BonusMapComplete( const char *pchFileName = NULL, const char *pchMapName = NULL ) = 0;
+ virtual void BonusMapChallengeUpdate( const char *pchFileName, const char *pchMapName, const char *pchChallengeName, int iBest ) = 0;
+ virtual void BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName ) = 0;
+ virtual void BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold ) = 0;
+ virtual void BonusMapDatabaseSave( void ) = 0;
+ virtual int BonusMapNumAdvancedCompleted( void ) = 0;
+ virtual void BonusMapNumMedals( int piNumMedals[ 3 ] ) = 0;
+
+ virtual void OnConnectToServer2(const char *game, int IP, int connectionPort, int queryPort) = 0;
+
+ // X360 Storage device validation:
+ // returns true right away if storage device has been previously selected.
+ // otherwise returns false and will set the variable pointed by pStorageDeviceValidated to 1
+ // once the storage device is selected by user.
+ virtual bool ValidateStorageDevice( int *pStorageDeviceValidated ) = 0;
+
+ virtual void SetProgressOnStart() = 0;
+ virtual void OnDisconnectFromServer( uint8 eSteamLoginFailure ) = 0;
+
+ virtual void OnConfirmQuit( void ) = 0;
+
+ virtual bool IsMainMenuVisible( void ) = 0;
+
+ // Client DLL is providing us with a panel that it wants to replace the main menu with
+ virtual void SetMainMenuOverride( vgui::VPANEL panel ) = 0;
+ // Client DLL is telling us that a main menu command was issued, probably from its custom main menu panel
+ virtual void SendMainMenuCommand( const char *pszCommand ) = 0;
+};
+
+#define GAMEUI_INTERFACE_VERSION "GameUI011"
+
+#endif // IGAMEUI_H
diff --git a/common/GameUI/ObjectList.cpp b/common/GameUI/ObjectList.cpp
new file mode 100644
index 0000000..7da1100
--- /dev/null
+++ b/common/GameUI/ObjectList.cpp
@@ -0,0 +1,243 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include <stdio.h>
+#include <malloc.h>
+#include "ObjectList.h"
+#include "tier1/strtools.h"
+
+//#include "port.h"
+//#include "mem.h"
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+ObjectList::ObjectList()
+{
+ head = tail = current = NULL;
+ number = 0;
+}
+
+ObjectList::~ObjectList()
+{
+ Clear( false );
+}
+
+bool ObjectList::AddHead(void * newObject)
+{
+ // create new element
+ element_t * newElement = (element_t *) calloc(1, sizeof(element_t));
+
+ if (newElement == NULL )
+ return false; // out of memory
+
+ // insert element
+ newElement->object = newObject;
+
+ if (head)
+ {
+ newElement->next = head;
+ head->prev = newElement;
+ };
+
+ head = newElement;
+
+ // if list was empty set new tail
+ if (tail==NULL) tail = head;
+
+ number++;
+
+ return true;
+
+}
+
+void * ObjectList::RemoveHead()
+{
+ void * retObj;
+
+ // check head is present
+ if (head)
+ {
+ retObj = head->object;
+ element_t * newHead = head->next;
+ if (newHead) newHead->prev = NULL;
+
+ // if only one element is in list also update tail
+ // if we remove this prev element
+ if (tail==head) tail = NULL;
+
+ free(head);
+ head = newHead;
+
+ number--;
+
+ } else
+ retObj = NULL;
+
+ return retObj;
+}
+
+bool ObjectList::AddTail(void * newObject)
+{
+ element_t * newElement = (element_t *) calloc(1, sizeof(element_t));
+
+ if (newElement == NULL)
+ return false; // out of memory;
+
+ newElement->object = newObject;
+
+ if (tail)
+ {
+ newElement->prev = tail;
+ tail->next = newElement;
+ }
+
+ tail = newElement;
+
+ // if list was empty set new head
+ if (head==NULL) head = tail;
+
+ number++;
+
+ return true;
+
+}
+
+void * ObjectList::RemoveTail()
+{
+ void * retObj;
+
+ // check tail is present
+ if (tail)
+ {
+ retObj = tail->object;
+ element_t * newTail = tail->prev;
+ if (newTail) newTail->next = NULL;
+
+ // if only one element is in list also update tail
+ // if we remove this prev element
+ if (head==tail) head = NULL;
+
+ free(tail);
+ tail = newTail;
+
+ number--;
+
+ } else
+ retObj = NULL;
+
+ return retObj;
+}
+
+bool ObjectList::IsEmpty()
+{
+ return ( head == NULL );
+}
+
+int ObjectList::CountElements()
+{
+ return number;
+}
+
+bool ObjectList::Contains(void * object)
+{
+ element_t * e = head;
+
+ while(e && e->object!=object) { e = e->next;}
+
+ if ( e )
+ {
+ current = e;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void ObjectList::Clear( bool freeElementsMemory )
+{
+ element_t * ne;
+
+ element_t * e = head;
+ while(e)
+ {
+ ne = e->next;
+
+ if ( freeElementsMemory && e->object )
+ free( e->object );
+
+ free(e);
+ e = ne;
+ }
+
+ head = tail = current = NULL;
+ number = 0;
+
+}
+
+bool ObjectList::Remove( void * object )
+{
+ element_t * e = head;
+
+ while(e && e->object!=object) { e = e->next;}
+
+ if (e!=NULL)
+ {
+ if (e->prev) e->prev->next = e->next;
+ if (e->next) e->next->prev = e->prev;
+ if (head==e) head = e->next;
+ if (tail==e) tail = e->prev;
+ if (current == e) current= e->next;
+ free(e);
+ number--;
+ }
+
+ return (e!=NULL);
+}
+
+void ObjectList::Init()
+{
+ head = tail = current = NULL;
+ number = 0;
+}
+
+void * ObjectList::GetFirst()
+{
+ if (head)
+ {
+ current = head->next;
+ return head->object;
+ }
+ else
+ {
+ current = NULL;
+ return NULL;
+ };
+
+}
+
+void * ObjectList::GetNext()
+{
+ void * retObj = NULL;
+ if (current)
+ {
+ retObj = current->object;
+ current = current->next;
+ }
+ return retObj;
+}
+
+bool ObjectList::Add(void *newObject)
+{
+ return AddTail( newObject );
+}
+
diff --git a/common/GameUI/ObjectList.h b/common/GameUI/ObjectList.h
new file mode 100644
index 0000000..b52a0ce
--- /dev/null
+++ b/common/GameUI/ObjectList.h
@@ -0,0 +1,58 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+// ObjectList.h: interface for the ObjectList class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef OBJECTLIST_H
+#define OBJECTLIST_H
+
+#pragma once
+
+#include "IObjectContainer.h" // Added by ClassView
+
+class ObjectList : public IObjectContainer
+{
+public:
+ void Init();
+ bool Add( void * newObject );
+ void * GetFirst();
+ void * GetNext();
+
+
+
+ ObjectList();
+ virtual ~ObjectList();
+
+ void Clear( bool freeElementsMemory );
+ int CountElements();
+ void * RemoveTail();
+ void * RemoveHead();
+
+ bool AddTail(void * newObject);
+ bool AddHead(void * newObject);
+ bool Remove(void * object);
+ bool Contains(void * object);
+ bool IsEmpty();
+
+ typedef struct element_s {
+ element_s * prev; // pointer to the last element or NULL
+ element_s * next; // pointer to the next elemnet or NULL
+ void * object; // the element's object
+ } element_t;
+
+protected:
+
+ element_t * head; // first element in list
+ element_t * tail; // last element in list
+ element_t * current; // current element in list
+ int number;
+
+};
+
+#endif // !defined
diff --git a/common/GameUI/Random.cpp b/common/GameUI/Random.cpp
new file mode 100644
index 0000000..ec17986
--- /dev/null
+++ b/common/GameUI/Random.cpp
@@ -0,0 +1,131 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Basic random number generator
+//
+// $NoKeywords: $
+//===========================================================================//
+
+
+#include <time.h>
+#include "Random.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define IA 16807
+#define IM 2147483647
+#define IQ 127773
+#define IR 2836
+#define NTAB 32
+#define NDIV (1+(IM-1)/NTAB)
+
+static long idum = 0;
+
+void SeedRandomNumberGenerator(long lSeed)
+{
+ if (lSeed)
+ {
+ idum = lSeed;
+ }
+ else
+ {
+ idum = -time(NULL);
+ }
+ if (1000 < idum)
+ {
+ idum = -idum;
+ }
+ else if (-1000 < idum)
+ {
+ idum -= 22261048;
+ }
+}
+
+long ran1(void)
+{
+ int j;
+ long k;
+ static long iy=0;
+ static long iv[NTAB];
+
+ if (idum <= 0 || !iy)
+ {
+ if (-(idum) < 1) idum=1;
+ else idum = -(idum);
+ for (j=NTAB+7;j>=0;j--)
+ {
+ k=(idum)/IQ;
+ idum=IA*(idum-k*IQ)-IR*k;
+ if (idum < 0) idum += IM;
+ if (j < NTAB) iv[j] = idum;
+ }
+ iy=iv[0];
+ }
+ k=(idum)/IQ;
+ idum=IA*(idum-k*IQ)-IR*k;
+ if (idum < 0) idum += IM;
+ j=iy/NDIV;
+ iy=iv[j];
+ iv[j] = idum;
+
+ return iy;
+}
+
+// fran1 -- return a random floating-point number on the interval [0,1)
+//
+#define AM (1.0/IM)
+#define EPS 1.2e-7
+#define RNMX (1.0-EPS)
+float fran1(void)
+{
+ float temp = (float)AM*ran1();
+ if (temp > RNMX) return (float)RNMX;
+ else return temp;
+}
+
+#ifndef _XBOX
+float RandomFloat( float flLow, float flHigh )
+{
+ if (idum == 0)
+ {
+ SeedRandomNumberGenerator(0);
+ }
+
+ float fl = fran1(); // float in [0,1)
+ return (fl * (flHigh-flLow)) + flLow; // float in [low,high)
+}
+#endif
+
+long RandomLong( long lLow, long lHigh )
+{
+ if (idum == 0)
+ {
+ SeedRandomNumberGenerator(0);
+ }
+
+ unsigned long maxAcceptable;
+ unsigned long x = lHigh-lLow+1;
+ unsigned long n;
+ if (x <= 0 || MAX_RANDOM_RANGE < x-1)
+ {
+ return lLow;
+ }
+
+ // The following maps a uniform distribution on the interval [0,MAX_RANDOM_RANGE]
+ // to a smaller, client-specified range of [0,x-1] in a way that doesn't bias
+ // the uniform distribution unfavorably. Even for a worst case x, the loop is
+ // guaranteed to be taken no more than half the time, so for that worst case x,
+ // the average number of times through the loop is 2. For cases where x is
+ // much smaller than MAX_RANDOM_RANGE, the average number of times through the
+ // loop is very close to 1.
+ //
+ maxAcceptable = MAX_RANDOM_RANGE - ((MAX_RANDOM_RANGE+1) % x );
+ do
+ {
+ n = ran1();
+ } while (n > maxAcceptable);
+
+ return lLow + (n % x);
+}
+
+
diff --git a/common/GameUI/Random.h b/common/GameUI/Random.h
new file mode 100644
index 0000000..90beb78
--- /dev/null
+++ b/common/GameUI/Random.h
@@ -0,0 +1,30 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Generalized 32-bit random number generator
+// Range is 0x00000000 - 0x7FFFFFFF
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef RANDOM_H
+#define RANDOM_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+// the random number seeding is automatic
+
+#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
+
+// restarts random generator
+// setting lSeed to 0 causes the current time to be used as the seed
+// random number generator will automatically seed itself on first use with current time if this is not called
+extern void SeedRandomNumberGenerator(long lSeed = 0);
+
+// returns a random integer of range [low, high]
+extern long RandomLong( long lLow, long lHigh );
+
+// returns a random float of range [low, high)
+extern float RandomFloat( float flLow, float flHigh );
+
+#endif // RANDOM_H
diff --git a/common/GameUI/cvarslider.cpp b/common/GameUI/cvarslider.cpp
new file mode 100644
index 0000000..7220538
--- /dev/null
+++ b/common/GameUI/cvarslider.cpp
@@ -0,0 +1,334 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cvarslider.h"
+#include <stdio.h>
+#include "tier1/KeyValues.h"
+#include "tier1/convar.h"
+#include <vgui/IVGui.h>
+#include <vgui_controls/PropertyPage.h>
+
+#define CVARSLIDER_SCALE_FACTOR 100.0f
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+using namespace vgui;
+
+DECLARE_BUILD_FACTORY( CCvarSlider );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CCvarSlider::CCvarSlider( Panel *parent, const char *name ) : Slider( parent, name )
+{
+ SetupSlider( 0, 1, "", false );
+ m_bCreatedInCode = false;
+
+ AddActionSignalTarget( this );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CCvarSlider::CCvarSlider( Panel *parent, const char *panelName, char const *caption,
+ float minValue, float maxValue, char const *cvarname, bool bAllowOutOfRange )
+ : Slider( parent, panelName )
+{
+ AddActionSignalTarget( this );
+
+ SetupSlider( minValue, maxValue, cvarname, bAllowOutOfRange );
+
+ // For backwards compatability. Ignore .res file settings for forced setup sliders.
+ m_bCreatedInCode = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCvarSlider::SetupSlider( float minValue, float maxValue, const char *cvarname, bool bAllowOutOfRange )
+{
+ // make sure min/max don't go outside cvar range if there's one
+ ConVarRef var( cvarname, true );
+ if ( var.IsValid() )
+ {
+ float flCVarMin;
+ if ( var.GetMin( flCVarMin ) )
+ {
+ minValue = m_bUseConVarMinMax ? flCVarMin : MAX( minValue, flCVarMin );
+ }
+ float flCVarMax;
+ if ( var.GetMax( flCVarMax ) )
+ {
+ maxValue = m_bUseConVarMinMax ? flCVarMax : MIN( maxValue, flCVarMax );
+ }
+ }
+
+ m_flMinValue = minValue;
+ m_flMaxValue = maxValue;
+
+ // scale by CVARSLIDER_SCALE_FACTOR
+ SetRange( (int)( CVARSLIDER_SCALE_FACTOR * minValue ), (int)( CVARSLIDER_SCALE_FACTOR * maxValue ) );
+
+ char szMin[ 32 ];
+ char szMax[ 32 ];
+
+ Q_snprintf( szMin, sizeof( szMin ), "%.2f", minValue );
+ Q_snprintf( szMax, sizeof( szMax ), "%.2f", maxValue );
+
+ SetTickCaptions( szMin, szMax );
+
+ Q_strncpy( m_szCvarName, cvarname, sizeof( m_szCvarName ) );
+
+ m_bModifiedOnce = false;
+ m_bAllowOutOfRange = bAllowOutOfRange;
+
+ // Set slider to current value
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CCvarSlider::~CCvarSlider()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCvarSlider::ApplySettings( KeyValues *inResourceData )
+{
+ BaseClass::ApplySettings( inResourceData );
+
+ if ( !m_bCreatedInCode )
+ {
+ float minValue = inResourceData->GetFloat( "minvalue", 0 );
+ float maxValue = inResourceData->GetFloat( "maxvalue", 1 );
+ const char *cvarname = inResourceData->GetString( "cvar_name", "" );
+ bool bAllowOutOfRange = inResourceData->GetInt( "allowoutofrange", 0 ) != 0;
+ SetupSlider( minValue, maxValue, cvarname, bAllowOutOfRange );
+
+ if ( GetParent() )
+ {
+ // HACK: If our parent is a property page, we want the dialog containing it
+ if ( dynamic_cast<vgui::PropertyPage*>(GetParent()) && GetParent()->GetParent() )
+ {
+ GetParent()->GetParent()->AddActionSignalTarget( this );
+ }
+ else
+ {
+ GetParent()->AddActionSignalTarget( this );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Get control settings for editing
+//-----------------------------------------------------------------------------
+void CCvarSlider::GetSettings( KeyValues *outResourceData )
+{
+ BaseClass::GetSettings(outResourceData);
+
+ if ( !m_bCreatedInCode )
+ {
+ outResourceData->SetFloat( "minvalue", m_flMinValue );
+ outResourceData->SetFloat( "maxvalue", m_flMaxValue );
+ outResourceData->SetString( "cvar_name", m_szCvarName );
+ outResourceData->SetInt( "allowoutofrange", m_bAllowOutOfRange );
+ }
+}
+
+void CCvarSlider::SetCVarName( char const *cvarname )
+{
+ Q_strncpy( m_szCvarName, cvarname, sizeof( m_szCvarName ) );
+
+ m_bModifiedOnce = false;
+
+ // Set slider to current value
+ Reset();
+}
+
+void CCvarSlider::SetMinMaxValues( float minValue, float maxValue, bool bSetTickDisplay )
+{
+ SetRange( (int)( CVARSLIDER_SCALE_FACTOR * minValue ), (int)( CVARSLIDER_SCALE_FACTOR * maxValue ) );
+
+ if ( bSetTickDisplay )
+ {
+ char szMin[ 32 ];
+ char szMax[ 32 ];
+
+ Q_snprintf( szMin, sizeof( szMin ), "%.2f", minValue );
+ Q_snprintf( szMax, sizeof( szMax ), "%.2f", maxValue );
+
+
+ SetTickCaptions( szMin, szMax );
+ }
+
+ // Set slider to current value
+ Reset();
+}
+
+void CCvarSlider::SetTickColor( Color color )
+{
+ m_TickColor = color;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCvarSlider::Paint()
+{
+ // Get engine's current value
+// float curvalue = engine->pfnGetCvarFloat( m_szCvarName );
+ ConVarRef var( m_szCvarName, true );
+ if ( !var.IsValid() )
+ return;
+ float curvalue = var.GetFloat();
+
+ // did it get changed from under us?
+ if (curvalue != m_fStartValue)
+ {
+ int val = (int)( CVARSLIDER_SCALE_FACTOR * curvalue );
+ m_fStartValue = curvalue;
+ m_fCurrentValue = curvalue;
+
+ SetValue( val );
+ m_iStartValue = GetValue();
+ }
+
+ BaseClass::Paint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCvarSlider::ApplyChanges()
+{
+ if (m_bModifiedOnce)
+ {
+ m_iStartValue = GetValue();
+ if (m_bAllowOutOfRange)
+ {
+ m_fStartValue = m_fCurrentValue;
+ }
+ else
+ {
+ m_fStartValue = (float) m_iStartValue / CVARSLIDER_SCALE_FACTOR;
+ }
+
+ //engine->Cvar_SetValue( m_szCvarName, m_fStartValue );
+ ConVarRef var( m_szCvarName, true );
+ if ( !var.IsValid() )
+ return;
+ var.SetValue( (float)m_fStartValue );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CCvarSlider::GetSliderValue()
+{
+ if (m_bAllowOutOfRange)
+ {
+ return m_fCurrentValue;
+ }
+ else
+ {
+ return ((float)GetValue())/ CVARSLIDER_SCALE_FACTOR;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCvarSlider::SetSliderValue(float fValue)
+{
+ int nVal = (int)( CVARSLIDER_SCALE_FACTOR * fValue );
+ SetValue( nVal, false);
+
+ // remember this slider value
+ m_iLastSliderValue = GetValue();
+
+ if (m_fCurrentValue != fValue)
+ {
+ m_fCurrentValue = fValue;
+ m_bModifiedOnce = true;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCvarSlider::Reset()
+{
+ // Set slider to current value
+// m_fStartValue = engine->pfnGetCvarFloat( m_szCvarName );
+ ConVarRef var( m_szCvarName, true );
+ if ( !var.IsValid() )
+ {
+ m_fCurrentValue = m_fStartValue = 0.0f;
+ SetValue( 0, false );
+ m_iStartValue = GetValue();
+ m_iLastSliderValue = m_iStartValue;
+ return;
+ }
+ m_fStartValue = var.GetFloat();
+ m_fCurrentValue = m_fStartValue;
+
+ int value = (int)( CVARSLIDER_SCALE_FACTOR * m_fStartValue );
+ SetValue( value, false );
+
+ m_iStartValue = GetValue();
+ m_iLastSliderValue = m_iStartValue;
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CCvarSlider::HasBeenModified()
+{
+ if (GetValue() != m_iStartValue)
+ {
+ m_bModifiedOnce = true;
+ }
+
+ return m_bModifiedOnce;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : position -
+//-----------------------------------------------------------------------------
+void CCvarSlider::OnSliderMoved()
+{
+ if (HasBeenModified())
+ {
+ if (m_iLastSliderValue != GetValue())
+ {
+ m_iLastSliderValue = GetValue();
+ m_fCurrentValue = ((float) m_iLastSliderValue)/CVARSLIDER_SCALE_FACTOR;
+ }
+
+ // tell parent that we've been modified
+ PostActionSignal(new KeyValues("ControlModified"));
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCvarSlider::OnSliderDragEnd( void )
+{
+ if ( !m_bCreatedInCode )
+ {
+ ApplyChanges();
+ }
+} \ No newline at end of file
diff --git a/common/GameUI/cvarslider.h b/common/GameUI/cvarslider.h
new file mode 100644
index 0000000..b03417a
--- /dev/null
+++ b/common/GameUI/cvarslider.h
@@ -0,0 +1,63 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef CVARSLIDER_H
+#define CVARSLIDER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Slider.h>
+
+class CCvarSlider : public vgui::Slider
+{
+ DECLARE_CLASS_SIMPLE( CCvarSlider, vgui::Slider );
+
+public:
+
+ CCvarSlider( vgui::Panel *parent, const char *panelName );
+ CCvarSlider( vgui::Panel *parent, const char *panelName, char const *caption,
+ float minValue, float maxValue, char const *cvarname, bool bAllowOutOfRange=false );
+ ~CCvarSlider();
+
+ void SetupSlider( float minValue, float maxValue, const char *cvarname, bool bAllowOutOfRange );
+
+ void SetCVarName( char const *cvarname );
+ void SetMinMaxValues( float minValue, float maxValue, bool bSetTickdisplay = true );
+ void SetTickColor( Color color );
+
+ virtual void Paint();
+
+ virtual void ApplySettings( KeyValues *inResourceData );
+ virtual void GetSettings( KeyValues *outResourceData );
+
+ void ApplyChanges();
+ float GetSliderValue();
+ void SetSliderValue(float fValue);
+ void Reset();
+ bool HasBeenModified();
+
+private:
+ MESSAGE_FUNC( OnSliderMoved, "SliderMoved" );
+ MESSAGE_FUNC( OnSliderDragEnd, "SliderDragEnd" );
+
+ CPanelAnimationVar( bool, m_bUseConVarMinMax, "use_convar_minmax", "0" );
+
+ bool m_bAllowOutOfRange;
+ bool m_bModifiedOnce;
+ float m_fStartValue;
+ int m_iStartValue;
+ int m_iLastSliderValue;
+ float m_fCurrentValue;
+ char m_szCvarName[ 64 ];
+
+ bool m_bCreatedInCode;
+ float m_flMinValue;
+ float m_flMaxValue;
+};
+
+#endif // CVARSLIDER_H
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
diff --git a/common/GameUI/scriptobject.h b/common/GameUI/scriptobject.h
new file mode 100644
index 0000000..78bf3e3
--- /dev/null
+++ b/common/GameUI/scriptobject.h
@@ -0,0 +1,155 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef SCRIPTOBJECT_H
+#define SCRIPTOBJECT_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Panel.h>
+
+class CPanelListPanel;
+
+#define SCRIPT_VERSION 1.0f
+
+typedef void * FileHandle_t;
+
+enum objtype_t
+{
+ O_BADTYPE,
+ O_BOOL,
+ O_NUMBER,
+ O_LIST,
+ O_STRING,
+ O_OBSOLETE,
+ O_SLIDER,
+ O_CATEGORY,
+};
+
+typedef struct
+{
+ objtype_t type;
+ char szDescription[32];
+} objtypedesc_t;
+
+class CScriptListItem
+{
+public:
+ CScriptListItem();
+ CScriptListItem( char const *strItem, char const *strValue );
+
+ char szItemText[128];
+ char szValue[256];
+
+ CScriptListItem *pNext;
+};
+
+class CScriptObject : public vgui::Panel
+{
+public:
+ void AddItem( CScriptListItem *pItem );
+ void RemoveAndDeleteAllItems( void );
+ CScriptObject( void );
+ ~CScriptObject();
+
+ bool ReadFromBuffer( const char **pBuffer, bool isNewObject );
+ void WriteToConfig();
+ void WriteToFile( FileHandle_t fp );
+ void WriteToScriptFile( FileHandle_t fp );
+ void SetCurValue( char const *strValue );
+
+ objtype_t GetType( char *pszType );
+
+ objtype_t type;
+
+ char cvarname[64 ];
+ char prompt[ 256 ];
+ char tooltip[ 256 ];
+
+ CScriptListItem *pListItems;
+
+ float fMin, fMax;
+
+ char defValue[ 128 ]; // Default value string
+ float fdefValue; // Float version of default value.
+
+ char curValue[ 128 ];
+ float fcurValue;
+
+ bool bSetInfo; // Prepend "Setinfo" to keyvalue pair in config?
+ // Linked list of default list box items.
+
+ CScriptObject *pNext;
+};
+
+abstract_class CDescription
+{
+public:
+ CDescription( void );
+ virtual ~CDescription();
+
+ bool ReadFromBuffer( const char **pBuffer, bool bAllowNewObject );
+ bool InitFromFile( const char *pszFileName, bool bAllowNewObject = true );
+ void TransferCurrentValues( const char *pszConfigFile );
+
+ void AddObject( CScriptObject *pItem );
+ void WriteToConfig();
+ void WriteToFile( FileHandle_t fp );
+ void WriteToScriptFile( FileHandle_t fp );
+
+ virtual void WriteScriptHeader( FileHandle_t fp ) = 0; // Clients must implement this.
+ virtual void WriteFileHeader( FileHandle_t fp ) = 0; // Clients must implement this.
+
+ void setDescription( const char *pszDesc );
+ void setHint( const char *pszHint );
+
+ const char *GetDescription( void ) { return m_pszDescriptionType; };
+ const char *getHint( void ) { return m_pszHintText; } ;
+public:
+ CScriptObject *pObjList;
+ CScriptObject *FindObject( const char *pszObjectName );
+
+private:
+
+ char *m_pszHintText;
+ char *m_pszDescriptionType;
+};
+
+namespace vgui
+{
+ class Label;
+ class Panel;
+}
+
+class mpcontrol_t : public vgui::Panel
+{
+public:
+ mpcontrol_t( vgui::Panel *parent, char const *panelName );
+
+ virtual void OnSizeChanged( int wide, int tall ) OVERRIDE;
+
+ objtype_t type;
+ vgui::Panel *pControl;
+ vgui::Label *pPrompt;
+ CScriptObject *pScrObj;
+
+ mpcontrol_t *next;
+};
+
+class CInfoDescription : public CDescription
+{
+public:
+ CInfoDescription( void );
+
+ virtual void WriteScriptHeader( FileHandle_t fp ) OVERRIDE;
+ virtual void WriteFileHeader( FileHandle_t fp ) OVERRIDE;
+};
+
+void UTIL_StripInvalidCharacters( char *pszInput, int maxlen );
+
+#endif // SCRIPTOBJECT_H