summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/legion/basemenu.cpp95
-rw-r--r--app/legion/basemenu.h39
-rw-r--r--app/legion/gamemanager.cpp342
-rw-r--r--app/legion/gamemanager.h160
-rw-r--r--app/legion/heightfield.cpp276
-rw-r--r--app/legion/heightfield.h77
-rw-r--r--app/legion/hostgamemenu.cpp201
-rw-r--r--app/legion/inetworkmessagelistener.h47
-rw-r--r--app/legion/inputmanager.cpp311
-rw-r--r--app/legion/inputmanager.h55
-rw-r--r--app/legion/joingamemenu.cpp213
-rw-r--r--app/legion/legion.cpp167
-rw-r--r--app/legion/legion.h64
-rw-r--r--app/legion/legion.vcproj289
-rw-r--r--app/legion/mainmenu.cpp46
-rw-r--r--app/legion/menumanager.cpp195
-rw-r--r--app/legion/menumanager.h140
-rw-r--r--app/legion/networkmanager.cpp393
-rw-r--r--app/legion/networkmanager.h159
-rw-r--r--app/legion/networkmessages.cpp51
-rw-r--r--app/legion/networkmessages.h54
-rw-r--r--app/legion/physicsmanager.cpp29
-rw-r--r--app/legion/physicsmanager.h43
-rw-r--r--app/legion/rendermanager.cpp255
-rw-r--r--app/legion/rendermanager.h94
-rw-r--r--app/legion/uimanager.cpp244
-rw-r--r--app/legion/uimanager.h95
-rw-r--r--app/legion/worldmanager.cpp166
-rw-r--r--app/legion/worldmanager.h84
29 files changed, 4384 insertions, 0 deletions
diff --git a/app/legion/basemenu.cpp b/app/legion/basemenu.cpp
new file mode 100644
index 0000000..1d8c9e9
--- /dev/null
+++ b/app/legion/basemenu.cpp
@@ -0,0 +1,95 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Base class menus should all inherit from
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "basemenu.h"
+#include "menumanager.h"
+#include <ctype.h>
+#include "vgui/iinput.h"
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+CBaseMenu::CBaseMenu( vgui::Panel *pParent, const char *pPanelName ) :
+ BaseClass( pParent, pPanelName )
+{
+ SetKeyBoardInputEnabled( true );
+ SetMouseInputEnabled( true );
+ SetSizeable( false );
+ SetMoveable( false );
+}
+
+CBaseMenu::~CBaseMenu()
+{
+}
+
+
+void CBaseMenu::OnKeyCodeTyped( vgui::KeyCode code )
+{
+ BaseClass::OnKeyCodeTyped( code );
+
+ bool shift = (vgui::input()->IsKeyDown(vgui::KEY_LSHIFT) || vgui::input()->IsKeyDown(vgui::KEY_RSHIFT));
+ bool ctrl = (vgui::input()->IsKeyDown(vgui::KEY_LCONTROL) || vgui::input()->IsKeyDown(vgui::KEY_RCONTROL));
+ bool alt = (vgui::input()->IsKeyDown(vgui::KEY_LALT) || vgui::input()->IsKeyDown(vgui::KEY_RALT));
+
+ if ( ctrl && shift && alt && code == vgui::KEY_B)
+ {
+ // enable build mode
+ ActivateBuildMode();
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Commands
+//-----------------------------------------------------------------------------
+void CBaseMenu::OnCommand( const char *pCommand )
+{
+ if ( !Q_stricmp( pCommand, "quit" ) )
+ {
+ IGameManager::Stop();
+ return;
+ }
+
+ if ( !Q_stricmp( pCommand, "popmenu" ) )
+ {
+ g_pMenuManager->PopMenu();
+ return;
+ }
+
+ if ( !Q_stricmp( pCommand, "popallmenus" ) )
+ {
+ g_pMenuManager->PopAllMenus();
+ return;
+ }
+
+ if ( !Q_strnicmp( pCommand, "pushmenu ", 9 ) )
+ {
+ const char *pMenuName = pCommand + 9;
+ while( isspace(*pMenuName) )
+ {
+ ++pMenuName;
+ }
+ g_pMenuManager->PushMenu( pMenuName );
+ return;
+ }
+
+ if ( !Q_strnicmp( pCommand, "switchmenu ", 11 ) )
+ {
+ const char *pMenuName = pCommand + 11;
+ while( isspace(*pMenuName) )
+ {
+ ++pMenuName;
+ }
+ g_pMenuManager->SwitchToMenu( pMenuName );
+ return;
+ }
+
+ BaseClass::OnCommand( pCommand );
+}
+
diff --git a/app/legion/basemenu.h b/app/legion/basemenu.h
new file mode 100644
index 0000000..5841852
--- /dev/null
+++ b/app/legion/basemenu.h
@@ -0,0 +1,39 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Base class menus should all inherit from
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef BASEMENU_H
+#define BASEMENU_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "vgui_controls/frame.h"
+#include "vgui/keycode.h"
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+class CBaseMenu : public vgui::Frame
+{
+ DECLARE_CLASS_SIMPLE( CBaseMenu, vgui::Frame );
+
+public:
+ CBaseMenu( vgui::Panel *pParent, const char *pPanelName );
+ virtual ~CBaseMenu();
+
+ // Commands
+ virtual void OnCommand( const char *pCommand );
+ virtual void OnKeyCodeTyped( vgui::KeyCode code );
+
+private:
+};
+
+#endif // BASEMENU_H
+
diff --git a/app/legion/gamemanager.cpp b/app/legion/gamemanager.cpp
new file mode 100644
index 0000000..a7934db
--- /dev/null
+++ b/app/legion/gamemanager.cpp
@@ -0,0 +1,342 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: List of game managers to update
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "gamemanager.h"
+#include "tier0/icommandline.h"
+
+// FIXME: REMOVE (for Sleep)
+#include <windows.h>
+
+
+//-----------------------------------------------------------------------------
+// globals
+//-----------------------------------------------------------------------------
+int IGameManager::m_nFrameNumber = 0;
+bool IGameManager::m_bStopRequested = false;
+bool IGameManager::m_bIsRunning = false;
+bool IGameManager::m_bIsInitialized = false;
+bool IGameManager::m_bLevelStartRequested = false;
+bool IGameManager::m_bLevelShutdownRequested = false;
+float IGameManager::m_flCurrentTime = 0.0f;
+float IGameManager::m_flLastTime = 0.0f;
+LevelState_t IGameManager::m_LevelState = NOT_IN_LEVEL;
+
+CUtlVector< IGameManager* > IGameManager::m_GameManagers;
+
+
+//-----------------------------------------------------------------------------
+// Adds a system to the list of systems to run
+//-----------------------------------------------------------------------------
+void IGameManager::Add( IGameManager* pSys )
+{
+ Assert( !m_bIsRunning );
+ m_GameManagers.AddToTail( pSys );
+}
+
+
+//-----------------------------------------------------------------------------
+// Removes a system from the list of systems to update
+//-----------------------------------------------------------------------------
+void IGameManager::Remove( IGameManager* pSys )
+{
+ Assert( !m_bIsRunning );
+ m_GameManagers.FindAndRemove( pSys );
+}
+
+
+//-----------------------------------------------------------------------------
+// Removes *all* systems from the list of systems to update
+//-----------------------------------------------------------------------------
+void IGameManager::RemoveAll( )
+{
+ m_GameManagers.RemoveAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// Invokes a method on all installed game systems in proper order
+//-----------------------------------------------------------------------------
+void IGameManager::InvokeMethod( GameManagerFunc_t f )
+{
+ int i;
+ int nCount = m_GameManagers.Count();
+ for ( i = 0; i < nCount; ++i )
+ {
+ (m_GameManagers[i]->*f)();
+ }
+}
+
+void IGameManager::InvokeMethodReverseOrder( GameManagerFunc_t f )
+{
+ int i;
+ int nCount = m_GameManagers.Count();
+ for ( i = nCount; --i >= 0; )
+ {
+ (m_GameManagers[i]->*f)();
+ }
+}
+
+bool IGameManager::InvokeMethod( GameManagerInitFunc_t f )
+{
+ int i;
+ int nCount = m_GameManagers.Count();
+ for ( i = 0; i < nCount; ++i )
+ {
+ if ( !(m_GameManagers[i]->*f)() )
+ return false;
+ }
+ return true;
+}
+
+LevelRetVal_t IGameManager::InvokeLevelMethod( GameManagerLevelFunc_t f, bool bFirstCall )
+{
+ LevelRetVal_t nRetVal = FINISHED;
+ int i;
+ int nCount = m_GameManagers.Count();
+ for ( i = 0; i < nCount; ++i )
+ {
+ LevelRetVal_t val = (m_GameManagers[i]->*f)( bFirstCall );
+ if ( val == FAILED )
+ return FAILED;
+ if ( val == MORE_WORK )
+ {
+ nRetVal = MORE_WORK;
+ }
+ }
+ return nRetVal;
+}
+
+LevelRetVal_t IGameManager::InvokeLevelMethodReverseOrder( GameManagerLevelFunc_t f, bool bFirstCall )
+{
+ LevelRetVal_t nRetVal = FINISHED;
+ int i;
+ int nCount = m_GameManagers.Count();
+ for ( i = 0; i < nCount; ++i )
+ {
+ LevelRetVal_t val = ( m_GameManagers[i]->*f )( bFirstCall );
+ if ( val == FAILED )
+ {
+ nRetVal = FAILED;
+ }
+ if ( ( val == MORE_WORK ) && ( nRetVal != FAILED ) )
+ {
+ nRetVal = MORE_WORK;
+ }
+ }
+ return nRetVal;
+}
+
+
+//-----------------------------------------------------------------------------
+// Init, shutdown game system
+//-----------------------------------------------------------------------------
+bool IGameManager::InitAllManagers()
+{
+ m_nFrameNumber = 0;
+ if ( !InvokeMethod( &IGameManager::Init ) )
+ return false;
+
+ m_bIsInitialized = true;
+ return true;
+}
+
+void IGameManager::ShutdownAllManagers()
+{
+ if ( m_bIsInitialized )
+ {
+ InvokeMethodReverseOrder( &IGameManager::Shutdown );
+ m_bIsInitialized = false;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Updates the state machine related to loading levels
+//-----------------------------------------------------------------------------
+void IGameManager::UpdateLevelStateMachine()
+{
+ // Do we want to switch into the level shutdown state?
+ bool bFirstLevelShutdownFrame = false;
+ if ( m_bLevelShutdownRequested )
+ {
+ if ( m_LevelState != LOADING_LEVEL )
+ {
+ m_bLevelShutdownRequested = false;
+ }
+ if ( m_LevelState == IN_LEVEL )
+ {
+ m_LevelState = SHUTTING_DOWN_LEVEL;
+ bFirstLevelShutdownFrame = true;
+ }
+ }
+
+ // Perform level shutdown
+ if ( m_LevelState == SHUTTING_DOWN_LEVEL )
+ {
+ LevelRetVal_t val = InvokeLevelMethodReverseOrder( &IGameManager::LevelShutdown, bFirstLevelShutdownFrame );
+ if ( val != MORE_WORK )
+ {
+ m_LevelState = NOT_IN_LEVEL;
+ }
+ }
+
+ // Do we want to switch into the level startup state?
+ bool bFirstLevelStartFrame = false;
+ if ( m_bLevelStartRequested )
+ {
+ if ( m_LevelState != SHUTTING_DOWN_LEVEL )
+ {
+ m_bLevelStartRequested = false;
+ }
+ if ( m_LevelState == NOT_IN_LEVEL )
+ {
+ m_LevelState = LOADING_LEVEL;
+ bFirstLevelStartFrame = true;
+ }
+ }
+
+ // Perform level load
+ if ( m_LevelState == LOADING_LEVEL )
+ {
+ LevelRetVal_t val = InvokeLevelMethod( &IGameManager::LevelInit, bFirstLevelStartFrame );
+ if ( val == FAILED )
+ {
+ m_LevelState = NOT_IN_LEVEL;
+ }
+ else if ( val == FINISHED )
+ {
+ m_LevelState = IN_LEVEL;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Runs the main loop.
+//-----------------------------------------------------------------------------
+void IGameManager::Start()
+{
+ Assert( !m_bIsRunning && m_bIsInitialized );
+
+ m_bIsRunning = true;
+ m_bStopRequested = false;
+
+ // This option is useful when running the app twice on the same machine
+ // It makes the 2nd instance of the app run a lot faster
+ bool bPlayNice = ( CommandLine()->CheckParm( "-yieldcycles" ) != 0 );
+
+ float flStartTime = m_flCurrentTime = m_flLastTime = Plat_FloatTime();
+ int nFramesSimulated = 0;
+ int nCount = m_GameManagers.Count();
+ while ( !m_bStopRequested )
+ {
+ UpdateLevelStateMachine();
+
+ m_flLastTime = m_flCurrentTime;
+ m_flCurrentTime = Plat_FloatTime();
+ int nSimulationFramesNeeded = 1 + (int)( ( m_flCurrentTime - flStartTime ) / TICK_INTERVAL );
+ while( nSimulationFramesNeeded > nFramesSimulated )
+ {
+ for ( int i = 0; i < nCount; ++i )
+ {
+ if ( m_GameManagers[i]->PerformsSimulation() )
+ {
+ m_GameManagers[i]->Update();
+ }
+ }
+ ++m_nFrameNumber;
+ ++nFramesSimulated;
+ }
+
+ // Always do I/O related managers regardless of framerate
+ for ( int i = 0; i < nCount; ++i )
+ {
+ if ( !m_GameManagers[i]->PerformsSimulation() )
+ {
+ m_GameManagers[i]->Update();
+ }
+ }
+
+ if ( bPlayNice )
+ {
+ Sleep( 1 );
+ }
+ }
+
+ m_bIsRunning = false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Stops the main loop at the next appropriate time
+//-----------------------------------------------------------------------------
+void IGameManager::Stop()
+{
+ if ( m_bIsRunning )
+ {
+ m_bStopRequested = true;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the current frame number
+//-----------------------------------------------------------------------------
+int IGameManager::FrameNumber()
+{
+ return m_nFrameNumber;
+}
+
+float IGameManager::CurrentSimulationTime()
+{
+ return m_nFrameNumber * TICK_INTERVAL;
+}
+
+float IGameManager::SimulationDeltaTime()
+{
+ return TICK_INTERVAL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Used in rendering
+//-----------------------------------------------------------------------------
+float IGameManager::CurrentTime()
+{
+ return m_flCurrentTime;
+}
+
+float IGameManager::DeltaTime()
+{
+ return m_flCurrentTime - m_flLastTime;
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the current level state
+//-----------------------------------------------------------------------------
+LevelState_t IGameManager::GetLevelState()
+{
+ return m_LevelState;
+}
+
+
+//-----------------------------------------------------------------------------
+// Start loading a level
+//-----------------------------------------------------------------------------
+void IGameManager::StartNewLevel()
+{
+ m_bLevelShutdownRequested = true;
+ m_bLevelStartRequested = true;
+}
+
+void IGameManager::ShutdownLevel()
+{
+ m_bLevelShutdownRequested = true;
+}
+
diff --git a/app/legion/gamemanager.h b/app/legion/gamemanager.h
new file mode 100644
index 0000000..845d7d5
--- /dev/null
+++ b/app/legion/gamemanager.h
@@ -0,0 +1,160 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef GAMEMANAGER_H
+#define GAMEMANAGER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier1/utlvector.h"
+
+
+//-----------------------------------------------------------------------------
+// State we are in
+//-----------------------------------------------------------------------------
+enum LevelState_t
+{
+ NOT_IN_LEVEL = 0,
+ LOADING_LEVEL,
+ IN_LEVEL,
+ SHUTTING_DOWN_LEVEL,
+};
+
+
+//-----------------------------------------------------------------------------
+// State we are in
+//-----------------------------------------------------------------------------
+enum LevelRetVal_t
+{
+ FAILED = 0,
+ MORE_WORK,
+ FINISHED,
+};
+
+
+//-----------------------------------------------------------------------------
+// Tick interval
+//-----------------------------------------------------------------------------
+#define TICK_INTERVAL 0.015f
+
+
+//-----------------------------------------------------------------------------
+// Game managers are singleton objects in the game code responsible for various tasks
+// The order in which the server systems appear in this list are the
+// order in which they are initialized and updated. They are shut down in
+// reverse order from which they are initialized.
+//-----------------------------------------------------------------------------
+abstract_class IGameManager
+{
+public:
+ // GameManagers are expected to implement these methods.
+ virtual bool Init() = 0;
+ virtual LevelRetVal_t LevelInit( bool bFirstCall ) = 0;
+ virtual void Update( ) = 0;
+ virtual LevelRetVal_t LevelShutdown( bool bFirstCall ) = 0;
+ virtual void Shutdown() = 0;
+
+ // Called during game save
+ virtual void OnSave() = 0;
+
+ // Called during game restore
+ virtual void OnRestore() = 0;
+
+ // This this game manager involved in I/O or simulation?
+ virtual bool PerformsSimulation() = 0;
+
+ // Add, remove game managers
+ static void Add( IGameManager* pSys );
+ static void Remove( IGameManager* pSys );
+ static void RemoveAll( );
+
+ // Init, shutdown game managers
+ static bool InitAllManagers();
+ static void ShutdownAllManagers();
+
+ // Start, stop running game managers
+ static void Start ();
+ static void Stop ();
+ static int FrameNumber();
+
+ // Used in simulation
+ static float CurrentSimulationTime();
+ static float SimulationDeltaTime();
+
+ // Used in rendering
+ static float CurrentTime();
+ static float DeltaTime();
+
+ // Start loading a level
+ static void StartNewLevel();
+ static void ShutdownLevel();
+ static LevelState_t GetLevelState();
+
+protected:
+ // Updates the state machine related to loading levels
+ static void UpdateLevelStateMachine();
+
+ virtual ~IGameManager() {}
+
+ typedef LevelRetVal_t (IGameManager::*GameManagerLevelFunc_t)( bool bFirstCall );
+ typedef bool (IGameManager::*GameManagerInitFunc_t)();
+ typedef void (IGameManager::*GameManagerFunc_t)();
+
+ // Used to invoke a method of all added game managers in order
+ static void InvokeMethod( GameManagerFunc_t f );
+ static void InvokeMethodReverseOrder( GameManagerFunc_t f );
+ static bool InvokeMethod( GameManagerInitFunc_t f );
+ static LevelRetVal_t InvokeLevelMethod( GameManagerLevelFunc_t f, bool bFirstCall );
+ static LevelRetVal_t InvokeLevelMethodReverseOrder( GameManagerLevelFunc_t f, bool bFirstCall );
+
+ static bool m_bLevelShutdownRequested;
+ static bool m_bLevelStartRequested;
+ static bool m_bStopRequested;
+ static CUtlVector< IGameManager* > m_GameManagers;
+ static bool m_bIsRunning;
+ static bool m_bIsInitialized;
+ static int m_nFrameNumber;
+ static float m_flCurrentTime;
+ static float m_flLastTime;
+ static LevelState_t m_LevelState;
+};
+
+
+//-----------------------------------------------------------------------------
+// Default decorator base-class for IGameManager
+//-----------------------------------------------------------------------------
+template< class BaseClass = IGameManager >
+class CGameManager : public BaseClass
+{
+public:
+ virtual ~CGameManager();
+
+ // GameManagers are expected to implement these methods.
+ // NOTE: If Init or LevelInit fail, they are expected to call
+ virtual bool Init() { return true; }
+ virtual LevelRetVal_t LevelInit( bool bFirstCall ) { return FINISHED; }
+ virtual void Update( ) {}
+ virtual LevelRetVal_t LevelShutdown( bool bFirstCall ) { return FINISHED; }
+ virtual void Shutdown() {}
+ virtual void OnSave() {}
+ virtual void OnRestore() {}
+ virtual bool PerformsSimulation() { return false; }
+};
+
+
+//-----------------------------------------------------------------------------
+// Automatically remove the game system if it gets deleted.
+//-----------------------------------------------------------------------------
+template< class BaseClass >
+inline CGameManager< BaseClass >::~CGameManager()
+{
+ Remove( this );
+}
+
+
+#endif // GAMEMANAGER_H
diff --git a/app/legion/heightfield.cpp b/app/legion/heightfield.cpp
new file mode 100644
index 0000000..9daf046
--- /dev/null
+++ b/app/legion/heightfield.cpp
@@ -0,0 +1,276 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Heightfield class
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "heightfield.h"
+#include "materialsystem/imaterial.h"
+#include "legion.h"
+#include "materialsystem/imaterialsystem.h"
+#include "materialsystem/imesh.h"
+#include "tier2/tier2.h"
+#include "tier2/utlstreambuffer.h"
+#include "bitmap/bitmap.h"
+#include "bitmap/psd.h"
+#include "tier1/KeyValues.h"
+
+
+//-----------------------------------------------------------------------------
+// Utility macro
+//-----------------------------------------------------------------------------
+#define HEIGHT( _x, _y ) m_pHeightField[ ( (_y) << m_nPowX ) + (_x) ]
+#define ROW( _y ) &m_pHeightField[ (_y) << m_nPowX ]
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+CHeightField::CHeightField( int nPowX, int nPowY, int nPowScale )
+{
+ m_nPowX = nPowX;
+ m_nPowY = nPowY;
+ m_nPowScale = nPowScale;
+ m_nWidth = ( 1 << nPowX );
+ m_nHeight = ( 1 << nPowY );
+ m_nScale = ( 1 << nPowScale );
+ m_flOOScale = 1.0f / m_nScale;
+ m_pHeightField = (float*)malloc( m_nWidth * m_nHeight * sizeof(float) );
+ memset( m_pHeightField, 0, m_nWidth * m_nHeight * sizeof(float) );
+
+ KeyValues *pKeyValues = new KeyValues( "Wireframe" );
+ pKeyValues->SetInt( "$nocull", 1 );
+ m_Material.Init( "__Temp", pKeyValues );
+}
+
+CHeightField::~CHeightField()
+{
+ free( m_pHeightField );
+}
+
+
+//-----------------------------------------------------------------------------
+// Bilinearly filters a sample out of a bitmap at a particular (x,y)
+// NOTE: x,y are not normalized and are expected to go in the range of (0->w-1, 0->h-1)
+//-----------------------------------------------------------------------------
+float BilerpBitmap( Bitmap_t &bitmap, float x, float y )
+{
+ Assert( bitmap.m_ImageFormat == IMAGE_FORMAT_RGBA8888 );
+
+ float w = (float)bitmap.m_nWidth;
+ float h = (float)bitmap.m_nHeight;
+
+ // Clamp to a valid range
+ x = clamp( x, 0, w - 1.0f );
+ y = clamp( y, 0, h - 1.0f );
+
+ // pick bilerp coordinates
+ int i0 = (int)floor( x );
+ int i1 = i0 + 1;
+ int j0 = (int)floor( y );
+ int j1 = j0 + 1;
+ if ( i1 >= bitmap.m_nWidth )
+ {
+ i1 = bitmap.m_nWidth - 1;
+ }
+ if ( j1 >= bitmap.m_nHeight )
+ {
+ j1 = bitmap.m_nHeight - 1;
+ }
+
+ float fx = x - i0;
+ float fy = y - j0;
+
+ RGBA8888_t* pPixel00 = (RGBA8888_t*)bitmap.GetPixel( i0, j0 );
+ RGBA8888_t* pPixel10 = (RGBA8888_t*)bitmap.GetPixel( i1, j0 );
+ RGBA8888_t* pPixel01 = (RGBA8888_t*)bitmap.GetPixel( i0, j1 );
+ RGBA8888_t* pPixel11 = (RGBA8888_t*)bitmap.GetPixel( i1, j1 );
+
+ float v00 = pPixel00->r / 255.0f;
+ float v10 = pPixel10->r / 255.0f;
+ float v01 = pPixel01->r / 255.0f;
+ float v11 = pPixel11->r / 255.0f;
+
+ // do the bilerp
+ return (1-fx)*(1-fy)*v00 + fx*(1-fy)*v10 + (1-fx)*fy*v01 + fx*fy*v11;
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads the heightfield from a file
+//-----------------------------------------------------------------------------
+bool CHeightField::LoadHeightFromFile( const char *pFileName )
+{
+ Bitmap_t bitmap;
+ CUtlStreamBuffer buf( pFileName, "GAME", CUtlBuffer::READ_ONLY );
+ if ( IsPSDFile( buf ) )
+ {
+ if ( !PSDReadFileRGBA8888( buf, bitmap ) )
+ return false;
+ }
+
+ // map from height field into map, ensuring corner pixel centers line up
+ // hfx -> mapx: 0 -> 0.5, hfw-1 -> mapw-0.5
+ // x (mapw - 1)/(hfw - 1) + 0.5
+ // mapx -> worldx: 0 -> 0, mapw -> worldw
+ float fx = (float)( bitmap.m_nWidth - 1) / (float)( m_nWidth - 1 );
+ float fy = (float)( bitmap.m_nHeight - 1) / (float)( m_nHeight - 1 );
+
+ for( int i = 0; i < m_nHeight; ++i )
+ {
+ float *pRow = ROW( i );
+ for( int j = 0; j < m_nWidth; ++j, ++pRow )
+ {
+ *pRow = 50.0f * BilerpBitmap( bitmap, i * fx, j * fy );
+ }
+ }
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the height at a particular point
+//-----------------------------------------------------------------------------
+float CHeightField::GetHeight( float x, float y )
+{
+ x *= m_flOOScale;
+ y *= m_flOOScale;
+
+ int gx = (int)floor( x );
+ int gy = (int)floor( y );
+ x -= gx;
+ y -= gy;
+
+ // Check for out of range
+ if ( gx < -1 || gy < -1 || gx >= m_nWidth || gy >= m_nHeight )
+ return 0.0f;
+
+ float h00 = ( gx >= 0 && gy >= 0 ) ? HEIGHT(gx , gy ) : 0.0f;
+ float h01 = ( gx < (m_nWidth-1) && gy >= 0 ) ? HEIGHT(gx+1, gy ) : 0.0f;
+ float h10 = ( gx >= 0 && gy < (m_nHeight-1) ) ? HEIGHT(gx , gy+1) : 0.0f;
+ float h11 = ( gx<(m_nWidth-1) && gy<(m_nHeight-1) ) ? HEIGHT(gx+1, gy+1) : 0.0f;
+
+ // This fixup accounts for the triangularization of the mesh
+ if (x > y)
+ {
+ h10 = h00 + h11 - h01;
+ }
+ else
+ {
+ h01 = h00 + h11 - h10;
+ }
+
+ // Bilinear filter
+ float h0 = h00 + ( h01 - h00 ) * x;
+ float h1 = h10 + ( h11 - h10 ) * x;
+ float h = h0 + (h1-h0)*y;
+
+ return h;
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the height + slope at a particular point
+//-----------------------------------------------------------------------------
+float CHeightField::GetHeightAndSlope( float x, float y, float *dx, float *dy )
+{
+ x *= m_flOOScale;
+ y *= m_flOOScale;
+
+ int gx = (int)floor(x);
+ int gy = (int)floor(y);
+ x -= gx;
+ y -= gy;
+
+ if ( gx < -1 || gy < -1 || gx >= m_nWidth || gy >= m_nHeight )
+ {
+ *dx = 0;
+ *dy = 0;
+ return 0.0f;
+ }
+
+ float h00 = ( gx >= 0 && gy >= 0 ) ? HEIGHT(gx , gy ) : 0.0f;
+ float h01 = ( gx < (m_nWidth-1) && gy >= 0 ) ? HEIGHT(gx+1, gy ) : 0.0f;
+ float h10 = ( gx >= 0 && gy < (m_nHeight-1) ) ? HEIGHT(gx , gy+1) : 0.0f;
+ float h11 = ( gx<(m_nWidth-1) && gy<(m_nHeight-1) ) ? HEIGHT(gx+1, gy+1) : 0.0f;
+
+ if (x > y)
+ {
+ h10 = h00 + h11 - h01;
+ }
+ else
+ {
+ h01 = h00 + h11 - h10;
+ }
+
+ *dx = ( h01 - h00 ) * m_flOOScale;
+ *dy = ( h10 - h00 ) * m_flOOScale;
+
+ // Bilinear filter
+ float h0 = h00 + ( h01 - h00 ) * x;
+ float h1 = h10 + ( h11 - h10 ) * x;
+ float h = h0 + ( h1 - h0 )* y;
+
+ return h;
+}
+
+
+//-----------------------------------------------------------------------------
+// Draws the height field
+//-----------------------------------------------------------------------------
+void CHeightField::Draw( )
+{
+ int nVertexCount = m_nWidth * m_nHeight;
+ int nIndexCount = 6 * ( m_nWidth - 1 ) * ( m_nHeight - 1 );
+
+ float flOOTexWidth = 1.0f / m_Material->GetMappingWidth();
+ float flOOTexHeight = 1.0f / m_Material->GetMappingHeight();
+ float iu = 0.5f * flOOTexWidth;
+ float iv = 1.0f - ( 0.5f * flOOTexHeight );
+ float du = ( 1.0f - flOOTexWidth ) / ( m_nWidth - 1 );
+ float dv = -( 1.0f - flOOTexHeight ) / ( m_nHeight - 1 );
+
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ pRenderContext->Bind( m_Material );
+ IMesh *pMesh = pRenderContext->GetDynamicMesh( );
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, nVertexCount, nIndexCount );
+
+ // Deal with vertices
+ float v = iv;
+ float y = 0.0f;
+ for ( int i = 0; i < m_nHeight; ++i, y += m_nScale, v += dv )
+ {
+ float u = iu;
+ float x = 0.0f;
+ for ( int j = 0; j < m_nWidth; ++j, x += m_nScale, u += du )
+ {
+ meshBuilder.Position3f( x, y, HEIGHT( j, i ) );
+ meshBuilder.TexCoord2f( 0, u, v );
+ meshBuilder.AdvanceVertex();
+ }
+ }
+
+ // Deal with indices
+ for ( int i = 0; i < (m_nHeight - 1); ++i )
+ {
+ int nRow0 = m_nWidth * i;
+ int nRow1 = nRow0 + m_nWidth;
+ for ( int j = 0; j < (m_nWidth - 1); ++j )
+ {
+ meshBuilder.FastIndex( nRow0+j );
+ meshBuilder.FastIndex( nRow0+j+1 );
+ meshBuilder.FastIndex( nRow1+j+1 );
+
+ meshBuilder.FastIndex( nRow0+j );
+ meshBuilder.FastIndex( nRow1+j+1 );
+ meshBuilder.FastIndex( nRow1+j );
+ }
+ }
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
diff --git a/app/legion/heightfield.h b/app/legion/heightfield.h
new file mode 100644
index 0000000..5267109
--- /dev/null
+++ b/app/legion/heightfield.h
@@ -0,0 +1,77 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Heightfield class
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef HEIGHTFIELD_H
+#define HEIGHTFIELD_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "materialsystem/MaterialSystemUtil.h"
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class CMeshBuilder;
+
+
+//-----------------------------------------------------------------------------
+// Definition of a heightfield
+//-----------------------------------------------------------------------------
+class CHeightField
+{
+public:
+ CHeightField( int nPowX, int nPowY, int nPowScale );
+ ~CHeightField();
+
+ // Loads the heights from a file
+ bool LoadHeightFromFile( const char *pFileName );
+
+ // Returns the max range of x, y
+ int GetWidth();
+ int GetHeight();
+
+ // Returns the height of the field at a paticular (x,y)
+ float GetHeight( float x, float y );
+ float GetHeightAndSlope( float x, float y, float *dx, float *dy );
+
+ // Draws the heightfield
+ void Draw( );
+
+private:
+ int m_nPowX;
+ int m_nPowY;
+ int m_nWidth;
+ int m_nHeight;
+ int m_nScale;
+ int m_nPowScale;
+ float m_flOOScale;
+ float *m_pHeightField;
+
+ CMaterialReference m_Material;
+ CTextureReference m_Texture;
+};
+
+
+//-----------------------------------------------------------------------------
+// Returns the max range of x, y (for use in GetHeight)
+//-----------------------------------------------------------------------------
+inline int CHeightField::GetWidth()
+{
+ return m_nWidth << m_nPowScale;
+}
+
+inline int CHeightField::GetHeight()
+{
+ return m_nHeight << m_nPowScale;
+}
+
+
+#endif // HEIGHTFIELD_H
diff --git a/app/legion/hostgamemenu.cpp b/app/legion/hostgamemenu.cpp
new file mode 100644
index 0000000..858bbe8
--- /dev/null
+++ b/app/legion/hostgamemenu.cpp
@@ -0,0 +1,201 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The menu that allows a player to start a game
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "menumanager.h"
+#include "basemenu.h"
+#include "vgui_controls/listpanel.h"
+#include "vgui_controls/textentry.h"
+#include "vgui_controls/Button.h"
+#include "tier1/KeyValues.h"
+#include "networkmanager.h"
+#include "legion.h"
+#include "inetworkmessagelistener.h"
+#include "networkmessages.h"
+#include "tier2/tier2.h"
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+class CHostGameMenu : public CBaseMenu, public INetworkMessageListener
+{
+ DECLARE_CLASS_SIMPLE( CHostGameMenu, CBaseMenu );
+
+public:
+ CHostGameMenu( vgui::Panel *pParent, const char *pPanelName );
+ virtual ~CHostGameMenu();
+
+ // Called when a particular network message occurs
+ virtual void OnNetworkMessage( NetworkMessageRoute_t route, INetworkMessage *pNetworkMessage );
+ virtual void OnCommand( const char *pCommand );
+
+ MESSAGE_FUNC( OnTextNewLine, "TextNewLine" );
+
+private:
+ vgui::ListPanel *m_pPlayerList;
+ vgui::TextEntry *m_pServerIP;
+ vgui::TextEntry *m_pServerName;
+ vgui::TextEntry *m_pChatLog;
+ vgui::TextEntry *m_pChatEntry;
+ vgui::TextEntry *m_pPlayerName;
+ vgui::Button *m_pStartGame;
+};
+
+
+//-----------------------------------------------------------------------------
+// Hooks the menu into the menu system
+//-----------------------------------------------------------------------------
+REGISTER_MENU( "HostGameMenu", CHostGameMenu );
+
+
+//-----------------------------------------------------------------------------
+// Sort by player name
+//-----------------------------------------------------------------------------
+static int __cdecl PlayerNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
+{
+ const char *string1 = item1.kv->GetString("player");
+ const char *string2 = item2.kv->GetString("player");
+ return stricmp( string1, string2 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+CHostGameMenu::CHostGameMenu( vgui::Panel *pParent, const char *pPanelName ) :
+ BaseClass( pParent, pPanelName )
+{
+ m_pPlayerList = new vgui::ListPanel( this, "PlayerList" );
+ m_pPlayerList->AddColumnHeader( 0, "color", "Color", 52, 0 );
+ m_pPlayerList->AddColumnHeader( 1, "player", "Player Name", 128, 0 );
+ m_pPlayerList->SetSelectIndividualCells( false );
+ m_pPlayerList->SetEmptyListText( "No Players" );
+ m_pPlayerList->SetDragEnabled( false );
+ m_pPlayerList->AddActionSignalTarget( this );
+ m_pPlayerList->SetSortFunc( 0, PlayerNameSortFunc );
+ m_pPlayerList->SetSortFunc( 1, PlayerNameSortFunc );
+ m_pPlayerList->SetSortColumn( 1 );
+
+ m_pServerIP = new vgui::TextEntry( this, "ServerIP" );
+ m_pServerName = new vgui::TextEntry( this, "ServerName" );
+
+ m_pPlayerName = new vgui::TextEntry( this, "PlayerName" );
+ m_pPlayerName->SetMultiline( false );
+
+ m_pChatLog = new vgui::TextEntry( this, "ChatLog" );
+ m_pChatLog->SetMultiline( true );
+ m_pChatLog->SetVerticalScrollbar( true );
+
+ m_pChatEntry = new vgui::TextEntry( this, "ChatEntry" );
+ m_pChatEntry->AddActionSignalTarget( this );
+ m_pChatEntry->SetMultiline( false );
+ m_pChatEntry->SendNewLine( true );
+
+ m_pStartGame = new vgui::Button( this, "StartGame", "Start Game", this );
+
+ LoadControlSettings( "resource/hostgamemenu.res", "GAME" );
+
+ m_pPlayerName->SetText( "Unnamed" );
+
+ if ( !g_pNetworkManager->HostGame() )
+ {
+ m_pStartGame->SetEnabled( false );
+ return;
+ }
+
+ m_pServerIP->SetText( g_pNetworkSystem->GetLocalAddress() );
+ m_pServerName->SetText( g_pNetworkSystem->GetLocalHostName() );
+
+ g_pNetworkManager->AddListener( NETWORK_MESSAGE_SERVER_TO_CLIENT, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this );
+ g_pNetworkManager->AddListener( NETWORK_MESSAGE_CLIENT_TO_SERVER, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this );
+}
+
+CHostGameMenu::~CHostGameMenu()
+{
+ g_pNetworkManager->RemoveListener( NETWORK_MESSAGE_SERVER_TO_CLIENT, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this );
+ g_pNetworkManager->RemoveListener( NETWORK_MESSAGE_CLIENT_TO_SERVER, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this );
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when a particular network message occurs
+//-----------------------------------------------------------------------------
+void CHostGameMenu::OnNetworkMessage( NetworkMessageRoute_t route, INetworkMessage *pNetworkMessage )
+{
+ if ( route == NETWORK_MESSAGE_SERVER_TO_CLIENT )
+ {
+ CNetworkMessage_Chat *pChatMsg = static_cast<CNetworkMessage_Chat*>( pNetworkMessage );
+ m_pChatLog->InsertString( pChatMsg->m_Message.Get() );
+ m_pChatLog->InsertChar( '\n' );
+ }
+ else
+ {
+ // If this message was received from an client, broadcast it to all other clients
+ g_pNetworkManager->BroadcastServerToClientMessage( pNetworkMessage );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when the enter key is hit in the chat entry window
+//-----------------------------------------------------------------------------
+void CHostGameMenu::OnTextNewLine()
+{
+ CNetworkMessage_Chat msg;
+
+ int nLen = m_pChatEntry->GetTextLength();
+ if ( nLen > 0 )
+ {
+ char *pText = (char*)_alloca( (nLen+1) * sizeof(char) );
+ m_pChatEntry->GetText( pText, nLen+1 );
+ m_pChatEntry->SetText( "" );
+
+ int nLenName = m_pPlayerName->GetTextLength();
+ char *pName = (char*)_alloca( (nLenName+8) * sizeof(char) );
+ if ( nLenName == 0 )
+ {
+ nLenName = 7;
+ Q_strcpy( pName, "unnamed" );
+ }
+ else
+ {
+ m_pPlayerName->GetText( pName, nLenName+1 );
+ }
+
+ int nTotalLen = nLen + nLenName;
+ msg.m_Message.SetLength( nTotalLen + 3 );
+ Q_snprintf( msg.m_Message.Get(), nTotalLen+3, "[%s] %s", pName, pText );
+
+ g_pNetworkManager->PostClientToServerMessage( &msg );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when the enter key is hit in the chat entry window
+//-----------------------------------------------------------------------------
+void CHostGameMenu::OnCommand( const char *pCommand )
+{
+ if ( !Q_stricmp( pCommand, "CancelHostGame" ) )
+ {
+ g_pNetworkManager->StopHostingGame();
+ g_pMenuManager->PopMenu();
+ return;
+ }
+
+ if ( !Q_stricmp( pCommand, "StartGame" ) )
+ {
+ IGameManager::StartNewLevel();
+ g_pMenuManager->PopAllMenus();
+ return;
+ }
+
+ BaseClass::OnCommand( pCommand );
+}
+
+
diff --git a/app/legion/inetworkmessagelistener.h b/app/legion/inetworkmessagelistener.h
new file mode 100644
index 0000000..7aa27c3
--- /dev/null
+++ b/app/legion/inetworkmessagelistener.h
@@ -0,0 +1,47 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the networking code in the game
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef INETWORKMESSAGELISTENER_H
+#define INETWORKMESSAGELISTENER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class INetworkMessage;
+
+
+//-----------------------------------------------------------------------------
+// Message route type
+//-----------------------------------------------------------------------------
+enum NetworkMessageRoute_t
+{
+ NETWORK_MESSAGE_SERVER_TO_CLIENT = 0,
+ NETWORK_MESSAGE_CLIENT_TO_SERVER,
+
+ NETWORK_MESSAGE_ROUTE_COUNT,
+};
+
+
+//-----------------------------------------------------------------------------
+// Interface used to listen to network messages
+//-----------------------------------------------------------------------------
+abstract_class INetworkMessageListener
+{
+public:
+ // Called when a particular network message occurs
+ virtual void OnNetworkMessage( NetworkMessageRoute_t route, INetworkMessage *pNetworkMessage ) = 0;
+};
+
+
+#endif // INETWORKMESSAGELISTENER_H
+
diff --git a/app/legion/inputmanager.cpp b/app/legion/inputmanager.cpp
new file mode 100644
index 0000000..716f7a0
--- /dev/null
+++ b/app/legion/inputmanager.cpp
@@ -0,0 +1,311 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the UI
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "inputmanager.h"
+#include "legion.h"
+#include "uimanager.h"
+#include "inputsystem/iinputsystem.h"
+#include "tier2/tier2.h"
+#include "tier1/convar.h"
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+static CInputManager s_InputManager;
+extern CInputManager *g_pInputManager = &s_InputManager;
+
+
+//-----------------------------------------------------------------------------
+// Initialization
+//-----------------------------------------------------------------------------
+bool CInputManager::Init()
+{
+ // FIXME: Read keybindings from a file
+ m_KeyBindings.SetBinding( "w", "+forward" );
+ m_KeyBindings.SetBinding( "s", "+back" );
+ m_KeyBindings.SetBinding( "`", "toggleconsole" );
+ m_ButtonUpToEngine.ClearAll();
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Add a command into the command queue
+//-----------------------------------------------------------------------------
+void CInputManager::AddCommand( const char *pCommand )
+{
+ m_CommandBuffer.AddText( pCommand );
+}
+
+
+//-----------------------------------------------------------------------------
+// FIXME! This is necessary only because of an artifact of how ConCommands used to work
+//-----------------------------------------------------------------------------
+static ConCommand *FindNamedCommand( char const *name )
+{
+ // look through the command list for all matches
+ ConCommandBase const *cmd = (ConCommandBase const *)vgui::icvar()->GetCommands();
+ while (cmd)
+ {
+ if (!Q_strcmp( name, cmd->GetName() ) )
+ {
+ if ( cmd->IsCommand() )
+ {
+ return ( ConCommand * )cmd;
+ }
+ }
+ cmd = cmd->GetNext();
+ }
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CInputManager::PrintConCommandBaseDescription( const ConCommandBase *pVar )
+{
+ bool bMin, bMax;
+ float fMin, fMax;
+ const char *pStr;
+
+ Assert( pVar );
+
+ Color clr;
+ clr.SetColor( 255, 100, 100, 255 );
+
+ if ( !pVar->IsCommand() )
+ {
+ ConVar *var = ( ConVar * )pVar;
+
+ bMin = var->GetMin( fMin );
+ bMax = var->GetMax( fMax );
+
+ char const *value = NULL;
+ char tempVal[ 32 ];
+
+ if ( var->IsBitSet( FCVAR_NEVER_AS_STRING ) )
+ {
+ value = tempVal;
+
+ if ( fabs( (float)var->GetInt() - var->GetFloat() ) < 0.000001 )
+ {
+ Q_snprintf( tempVal, sizeof( tempVal ), "%d", var->GetInt() );
+ }
+ else
+ {
+ Q_snprintf( tempVal, sizeof( tempVal ), "%f", var->GetFloat() );
+ }
+ }
+ else
+ {
+ value = var->GetString();
+ }
+
+ if ( value )
+ {
+ Msg( "\"%s\" = \"%s\"", var->GetName(), value );
+
+ if ( Q_stricmp( value, var->GetDefault() ) )
+ {
+ Msg( " ( def. \"%s\" )", var->GetDefault() );
+ }
+ }
+
+ if ( bMin )
+ {
+ Msg( " min. %f", fMin );
+ }
+ if ( bMax )
+ {
+ Msg( " max. %f", fMax );
+ }
+
+ Msg( "\n" );
+ }
+ else
+ {
+ ConCommand *var = ( ConCommand * )pVar;
+
+ Msg( "\"%s\"\n", var->GetName() );
+ }
+
+// PrintConCommandBaseFlags( pVar );
+
+ pStr = pVar->GetHelpText();
+ if ( pStr && pStr[0] )
+ {
+ Msg( " - %s\n", pStr );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Per-frame update
+//-----------------------------------------------------------------------------
+void CInputManager::ProcessCommands( )
+{
+ m_CommandBuffer.BeginProcessingCommands( 1 );
+ while ( m_CommandBuffer.DequeueNextCommand() )
+ {
+ const CCommand& args = m_CommandBuffer.GetCommand();
+ const ConCommandBase *pCommand = FindNamedCommand( args[ 0 ] );
+ if ( pCommand && pCommand->IsCommand() )
+ {
+ // FIXME: Um... yuck!?!
+ ConCommand *pConCommand = const_cast<ConCommand*>( static_cast<const ConCommand*>( pCommand ) );
+ pConCommand->Dispatch( args );
+ continue;
+ }
+
+ ConVar *pConVar = g_pCVar->FindVar( args[0] );
+ if ( !pConVar )
+ continue;
+
+ // perform a variable print or set
+ if ( args.ArgC() == 1 )
+ {
+ PrintConCommandBaseDescription( pConVar );
+ continue;
+ }
+
+ // Note that we don't want the tokenized list, send down the entire string
+ // except for surrounding quotes
+ char remaining[1024];
+ const char *pArgS = args.ArgS();
+ int nLen = Q_strlen( pArgS );
+ bool bIsQuoted = pArgS[0] == '\"';
+ if ( !bIsQuoted )
+ {
+ Q_strncpy( remaining, args.ArgS(), sizeof(remaining) );
+ }
+ else
+ {
+ --nLen;
+ Q_strncpy( remaining, &pArgS[1], sizeof(remaining) );
+ }
+
+ // Now strip off any trailing spaces
+ char *p = remaining + nLen - 1;
+ while ( p >= remaining )
+ {
+ if ( *p > ' ' )
+ break;
+
+ *p-- = 0;
+ }
+
+ // Strip off ending quote
+ if ( bIsQuoted && p >= remaining )
+ {
+ if ( *p == '\"' )
+ {
+ *p = 0;
+ }
+ }
+
+ if ( pConVar->IsBitSet( FCVAR_NEVER_AS_STRING ) )
+ {
+ pConVar->SetValue( (float)atof( remaining ) );
+ }
+ else
+ {
+ pConVar->SetValue( remaining );
+ }
+
+ }
+ m_CommandBuffer.EndProcessingCommands();
+}
+
+
+//-----------------------------------------------------------------------------
+// Per-frame update
+//-----------------------------------------------------------------------------
+void CInputManager::Update( )
+{
+ char cmd[1024];
+
+ g_pInputSystem->PollInputState();
+ int nEventCount = g_pInputSystem->GetEventCount();
+ const InputEvent_t* pEvents = g_pInputSystem->GetEventData( );
+ for ( int i = 0; i < nEventCount; ++i )
+ {
+ if ( pEvents[i].m_nType == IE_Quit )
+ {
+ IGameManager::Stop();
+ break;
+ }
+
+ bool bBypassVGui = false;
+ switch( pEvents[i].m_nType )
+ {
+ case IE_AppActivated:
+ if ( pEvents[i].m_nData == 0 )
+ {
+ m_ButtonUpToEngine.ClearAll();
+ }
+ break;
+
+ case IE_ButtonReleased:
+ {
+ // This logic is necessary to deal with switching back + forth
+ // between vgui + the engine. If we downclick in the engine,
+ // the engine must get the upclick.
+ ButtonCode_t code = (ButtonCode_t)pEvents[i].m_nData;
+ if ( m_ButtonUpToEngine[ code ] )
+ {
+ m_ButtonUpToEngine.Clear( code );
+ bBypassVGui = true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+ if ( !bBypassVGui )
+ {
+ if ( g_pUIManager->ProcessInputEvent( pEvents[i] ) )
+ continue;
+ }
+
+ // FIXME: Add game keybinding system here
+ bool bButtonDown = ( pEvents[i].m_nType == IE_ButtonPressed );
+ bool bButtonUp = ( pEvents[i].m_nType == IE_ButtonReleased );
+ if ( bButtonDown || bButtonUp )
+ {
+ ButtonCode_t code = (ButtonCode_t)pEvents[i].m_nData;
+ if ( bButtonDown )
+ {
+ m_ButtonUpToEngine.Set( code );
+ }
+ const char *pBinding = m_KeyBindings.GetBindingForButton( code );
+ if ( !pBinding )
+ continue;
+
+ if ( pBinding[0] != '+' )
+ {
+ if ( bButtonDown )
+ {
+ m_CommandBuffer.AddText( pBinding );
+ }
+ continue;
+ }
+
+ Q_snprintf( cmd, sizeof(cmd), "%c%s %i\n", bButtonUp ? '-' : '+', &pBinding[1], code );
+ m_CommandBuffer.AddText( cmd );
+ continue;
+ }
+ }
+
+ ProcessCommands();
+}
+
diff --git a/app/legion/inputmanager.h b/app/legion/inputmanager.h
new file mode 100644
index 0000000..82517df
--- /dev/null
+++ b/app/legion/inputmanager.h
@@ -0,0 +1,55 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the input
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef INPUTMANAGER_H
+#define INPUTMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gamemanager.h"
+#include "tier2/keybindings.h"
+#include "tier1/commandbuffer.h"
+#include "bitvec.h"
+
+
+//-----------------------------------------------------------------------------
+// Input management
+//-----------------------------------------------------------------------------
+class CInputManager : public CGameManager<>
+{
+public:
+ // Inherited from IGameManager
+ virtual bool Init();
+ virtual void Update( );
+
+ // Add a command into the command queue
+ void AddCommand( const char *pCommand );
+
+private:
+ // Per-frame update of commands
+ void ProcessCommands( );
+
+ // Purpose:
+ void PrintConCommandBaseDescription( const ConCommandBase *pVar );
+
+ CKeyBindings m_KeyBindings;
+ CBitVec<BUTTON_CODE_LAST> m_ButtonUpToEngine;
+ CCommandBuffer m_CommandBuffer;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+extern CInputManager *g_pInputManager;
+
+
+#endif // INPUTMANAGER_H
+
diff --git a/app/legion/joingamemenu.cpp b/app/legion/joingamemenu.cpp
new file mode 100644
index 0000000..e3b1311
--- /dev/null
+++ b/app/legion/joingamemenu.cpp
@@ -0,0 +1,213 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Menu responsible for allowing players to join a game
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "menumanager.h"
+#include "basemenu.h"
+#include "vgui_controls/listpanel.h"
+#include "vgui_controls/textentry.h"
+#include "vgui_controls/button.h"
+#include "networkmessages.h"
+#include "networkmanager.h"
+#include "tier1/KeyValues.h"
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+class CJoinGameMenu : public CBaseMenu, public INetworkMessageListener
+{
+ DECLARE_CLASS_SIMPLE( CJoinGameMenu, CBaseMenu );
+
+public:
+ CJoinGameMenu( vgui::Panel *pParent, const char *pPanelName );
+ virtual ~CJoinGameMenu();
+
+ // Called when a particular network message occurs
+ virtual void OnNetworkMessage( NetworkMessageRoute_t route, INetworkMessage *pNetworkMessage );
+ virtual void OnCommand( const char *pCommand );
+
+ MESSAGE_FUNC( OnTextNewLine, "TextNewLine" );
+
+private:
+ vgui::ListPanel *m_pPlayerList;
+ vgui::TextEntry *m_pChatLog;
+ vgui::TextEntry *m_pServerName;
+ vgui::TextEntry *m_pServerPort;
+ vgui::TextEntry *m_pChatEntry;
+ vgui::TextEntry *m_pPlayerName;
+ vgui::Button *m_pJoinGame;
+ bool m_bJoiningGame;
+};
+
+
+//-----------------------------------------------------------------------------
+// Hooks the menu into the menu manager
+//-----------------------------------------------------------------------------
+REGISTER_MENU( "JoinGameMenu", CJoinGameMenu );
+
+
+//-----------------------------------------------------------------------------
+// Sort by player name
+//-----------------------------------------------------------------------------
+static int __cdecl PlayerNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
+{
+ const char *string1 = item1.kv->GetString("player");
+ const char *string2 = item2.kv->GetString("player");
+ return stricmp( string1, string2 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+CJoinGameMenu::CJoinGameMenu( vgui::Panel *pParent, const char *pPanelName ) :
+ BaseClass( pParent, pPanelName )
+{
+ m_pPlayerList = new vgui::ListPanel( this, "PlayerList" );
+ m_pPlayerList->AddColumnHeader( 0, "color", "Color", 52, 0 );
+ m_pPlayerList->AddColumnHeader( 1, "player", "Player Name", 128, 0 );
+ m_pPlayerList->SetSelectIndividualCells( false );
+ m_pPlayerList->SetEmptyListText( "No Players" );
+ m_pPlayerList->SetDragEnabled( false );
+ m_pPlayerList->AddActionSignalTarget( this );
+ m_pPlayerList->SetSortFunc( 0, PlayerNameSortFunc );
+ m_pPlayerList->SetSortFunc( 1, PlayerNameSortFunc );
+ m_pPlayerList->SetSortColumn( 1 );
+
+ m_pServerName = new vgui::TextEntry( this, "ServerName" );
+
+ m_pServerPort = new vgui::TextEntry( this, "ServerPort" );
+ char pInitialPort[16];
+ Q_snprintf( pInitialPort, sizeof(pInitialPort), "%d", NETWORKSYSTEM_DEFAULT_SERVER_PORT );
+ m_pServerPort->SetText( pInitialPort );
+
+ m_pPlayerName = new vgui::TextEntry( this, "PlayerName" );
+ m_pPlayerName->SetMultiline( false );
+
+ m_pChatLog = new vgui::TextEntry( this, "ChatLog" );
+ m_pChatLog->SetMultiline( true );
+ m_pChatLog->SetVerticalScrollbar( true );
+
+ m_pChatEntry = new vgui::TextEntry( this, "ChatEntry" );
+ m_pChatEntry->AddActionSignalTarget( this );
+ m_pChatEntry->SetMultiline( false );
+ m_pChatEntry->SendNewLine( true );
+
+ m_pJoinGame = new vgui::Button( this, "JoinGame", "Join Game", this );
+
+ LoadControlSettings( "resource/joingamemenu.res", "GAME" );
+
+ m_pPlayerName->SetText( "Unnamed" );
+ m_pChatEntry->SetEnabled( false );
+
+ if ( !g_pNetworkManager->StartClient() )
+ {
+ m_pJoinGame->SetEnabled( false );
+ return;
+ }
+
+ g_pNetworkManager->AddListener( NETWORK_MESSAGE_SERVER_TO_CLIENT, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this );
+}
+
+CJoinGameMenu::~CJoinGameMenu()
+{
+ g_pNetworkManager->RemoveListener( NETWORK_MESSAGE_SERVER_TO_CLIENT, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this );
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when a particular network message occurs
+//-----------------------------------------------------------------------------
+void CJoinGameMenu::OnNetworkMessage( NetworkMessageRoute_t route, INetworkMessage *pNetworkMessage )
+{
+ CNetworkMessage_Chat *pChatMsg = static_cast<CNetworkMessage_Chat*>( pNetworkMessage );
+ m_pChatLog->InsertString( pChatMsg->m_Message.Get() );
+ m_pChatLog->InsertChar( '\n' );
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when the enter key is hit in the chat entry window
+//-----------------------------------------------------------------------------
+void CJoinGameMenu::OnTextNewLine()
+{
+ CNetworkMessage_Chat msg;
+
+ int nLen = m_pChatEntry->GetTextLength();
+ if ( nLen > 0 )
+ {
+ char *pText = (char*)_alloca( (nLen+1) * sizeof(char) );
+ m_pChatEntry->GetText( pText, nLen+1 );
+ m_pChatEntry->SetText( "" );
+
+ int nLenName = m_pPlayerName->GetTextLength();
+ char *pName = (char*)_alloca( (nLenName+8) * sizeof(char) );
+ if ( nLenName == 0 )
+ {
+ nLenName = 7;
+ Q_strcpy( pName, "unnamed" );
+ }
+ else
+ {
+ m_pPlayerName->GetText( pName, nLenName+1 );
+ }
+
+ int nTotalLen = nLen + nLenName;
+ msg.m_Message.SetLength( nTotalLen + 3 );
+ Q_snprintf( msg.m_Message.Get(), nTotalLen+3, "[%s] %s", pName, pText );
+
+ g_pNetworkManager->PostClientToServerMessage( &msg );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when the enter key is hit in the chat entry window
+//-----------------------------------------------------------------------------
+void CJoinGameMenu::OnCommand( const char *pCommand )
+{
+ if ( !Q_stricmp( pCommand, "Cancel" ) )
+ {
+ g_pNetworkManager->ShutdownClient();
+ g_pMenuManager->PopMenu();
+ return;
+ }
+
+ if ( !Q_stricmp( pCommand, "JoinGame" ) )
+ {
+ if ( !m_bJoiningGame )
+ {
+ g_pNetworkManager->DisconnectClientFromServer();
+ m_pChatEntry->SetEnabled( false );
+ m_pChatEntry->SetText( "" );
+ m_bJoiningGame = true;
+ m_pJoinGame->SetText( "Join Game" );
+ }
+ else
+ {
+ int nLen = m_pServerName->GetTextLength();
+ char *pServer = (char*)_alloca( (nLen+1) * sizeof(char) );
+ m_pServerName->GetText( pServer, nLen+1 );
+
+ char pPort[32];
+ m_pServerPort->GetText( pPort, sizeof(pPort) );
+
+ if ( g_pNetworkManager->ConnectClientToServer( pServer, atoi( pPort ) ) )
+ {
+ m_pChatEntry->SetEnabled( true );
+ m_bJoiningGame = false;
+ m_pJoinGame->SetText( "Leave Game" );
+ }
+ }
+ return;
+ }
+
+ BaseClass::OnCommand( pCommand );
+}
+
+
diff --git a/app/legion/legion.cpp b/app/legion/legion.cpp
new file mode 100644
index 0000000..33a6c09
--- /dev/null
+++ b/app/legion/legion.cpp
@@ -0,0 +1,167 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// The copyright to the contents herein is the property of Valve, L.L.C.
+// The contents may be used and/or copied only with the written permission of
+// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
+// the agreement/contract under which the contents have been supplied.
+//
+// $Header: $
+// $NoKeywords: $
+//
+// An RTS!
+//=============================================================================
+
+#include "legion.h"
+#include <windows.h>
+#include "inputsystem/iinputsystem.h"
+#include "networksystem/inetworksystem.h"
+#include "filesystem.h"
+#include "materialsystem/imaterialsystem.h"
+#include "vgui/IVGui.h"
+#include "vgui/ISurface.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "vgui_controls/controls.h"
+#include "vgui/ILocalize.h"
+#include "vgui_controls/AnimationController.h"
+#include "gamemanager.h"
+#include "menumanager.h"
+#include "physicsmanager.h"
+#include "rendermanager.h"
+#include "uimanager.h"
+#include "inputmanager.h"
+#include "networkmanager.h"
+#include "worldmanager.h"
+#include "tier3/tier3.h"
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Warning/Msg call back through this API
+// Input : type -
+// *pMsg -
+// Output : SpewRetval_t
+//-----------------------------------------------------------------------------
+SpewRetval_t SpewFunc( SpewType_t type, char const *pMsg )
+{
+ OutputDebugString( pMsg );
+ if ( type == SPEW_ASSERT )
+ {
+ DebuggerBreak();
+ }
+ return SPEW_CONTINUE;
+}
+
+
+static CLegionApp s_LegionApp;
+extern CLegionApp *g_pApp = &s_LegionApp;
+DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT_GLOBALVAR( CLegionApp, s_LegionApp );
+
+
+//-----------------------------------------------------------------------------
+// Create all singleton systems
+//-----------------------------------------------------------------------------
+bool CLegionApp::Create()
+{
+ SpewOutputFunc( SpewFunc );
+
+ // FIXME: Put this into tier1librariesconnect
+ MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false );
+
+ if ( !BaseClass::Create() )
+ return false;
+
+ AppSystemInfo_t appSystems[] =
+ {
+ { "networksystem.dll", NETWORKSYSTEM_INTERFACE_VERSION },
+ { "", "" } // Required to terminate the list
+ };
+
+ return AddSystems( appSystems );
+}
+
+bool CLegionApp::PreInit( )
+{
+ if ( !BaseClass::PreInit() )
+ return false;
+
+ if ( !g_pInputSystem || !g_pFullFileSystem || !g_pNetworkSystem || !g_pMaterialSystem || !g_pVGui || !g_pVGuiSurface || !g_pMatSystemSurface )
+ {
+ Warning( "Legion is missing a required interface!\n" );
+ return false;
+ }
+ return true;
+}
+
+
+void CLegionApp::PostShutdown()
+{
+ BaseClass::PostShutdown();
+}
+
+
+bool CLegionApp::RegisterConCommandBase( ConCommandBase *pCommand )
+{
+ // Mark for easy removal
+ pCommand->AddFlags( FCVAR_CLIENTDLL );
+ pCommand->SetNext( 0 );
+
+ // Link to variable list
+ g_pCVar->RegisterConCommandBase( pCommand );
+ return true;
+}
+
+void CLegionApp::UnregisterConCommandBase( ConCommandBase *pCommand )
+{
+ // Unlink from variable list
+ g_pCVar->UnlinkVariable( pCommand );
+}
+
+
+//-----------------------------------------------------------------------------
+// main application
+//-----------------------------------------------------------------------------
+int CLegionApp::Main()
+{
+ if (!SetVideoMode())
+ return 0;
+
+ ConCommandBaseMgr::OneTimeInit( this );
+
+ g_pMaterialSystem->ModInit();
+
+ // World database
+ IGameManager::Add( g_pWorldManager );
+
+ // Output
+ IGameManager::Add( g_pRenderManager );
+
+ // Input
+ IGameManager::Add( g_pNetworkManager );
+ IGameManager::Add( g_pInputManager );
+ IGameManager::Add( g_pMenuManager );
+ IGameManager::Add( g_pUIManager );
+
+ // Simulation
+ IGameManager::Add( g_pPhysicsManager );
+
+ // Init the game managers
+ if ( !IGameManager::InitAllManagers() )
+ return 0;
+
+ // First menu to start on
+ g_pMenuManager->PushMenu( "MainMenu" );
+
+ // This is the main game loop
+ IGameManager::Start();
+
+ // Shut down game systems
+ IGameManager::ShutdownAllManagers();
+
+ g_pMaterialSystem->ModShutdown();
+
+ g_pCVar->UnlinkVariables( FCVAR_CLIENTDLL );
+
+ return 1;
+}
+
+
+
diff --git a/app/legion/legion.h b/app/legion/legion.h
new file mode 100644
index 0000000..b998bfb
--- /dev/null
+++ b/app/legion/legion.h
@@ -0,0 +1,64 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// The copyright to the contents herein is the property of Valve, L.L.C.
+// The contents may be used and/or copied only with the written permission of
+// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
+// the agreement/contract under which the contents have been supplied.
+//
+// $Header: $
+// $NoKeywords: $
+//
+// An RTS!
+//=============================================================================
+
+#ifndef LEGION_H
+#define LEGION_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "appframework/vguimatsysapp.h"
+#include "tier1/convar.h"
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class CLegionApp;
+
+
+//-----------------------------------------------------------------------------
+// Singleton interfaces
+//-----------------------------------------------------------------------------
+extern CLegionApp *g_pApp;
+
+
+//-----------------------------------------------------------------------------
+// The application object
+//-----------------------------------------------------------------------------
+class CLegionApp : public CVguiMatSysApp, public IConCommandBaseAccessor
+{
+ typedef CVguiMatSysApp BaseClass;
+
+public:
+ // Methods of IApplication
+ virtual bool Create();
+ virtual bool PreInit( );
+ virtual int Main();
+ virtual void PostShutdown( );
+ virtual const char *GetAppName() { return "Legion"; }
+
+ // Methods of IConCommandBaseAccessor
+ virtual bool RegisterConCommandBase( ConCommandBase *pCommand );
+ virtual void UnregisterConCommandBase( ConCommandBase *pCommand );
+
+ // Promote to public
+ void AppPumpMessages() { BaseClass::AppPumpMessages(); }
+
+private:
+};
+
+
+#endif // LEGION_H
+
+
diff --git a/app/legion/legion.vcproj b/app/legion/legion.vcproj
new file mode 100644
index 0000000..8570646
--- /dev/null
+++ b/app/legion/legion.vcproj
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="legion"
+ ProjectGUID="{B0B64755-2419-4946-A726-881A1D884F65}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\public;..\..\public\tier1;..\..\common"
+ PreprocessorDefinitions="_WIN32;_DEBUG;_WINDOWS"
+ MinimalRebuild="TRUE"
+ ExceptionHandling="FALSE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="$(IntDir)/legion.pdb"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="if exist ..\..\..\game\bin\legion.exe attrib -r ..\..\..\game\bin\legion.exe
+copy &quot;$(TargetPath)&quot; ..\..\..\game\bin
+if exist ..\..\..\game\bin\legion.pdb attrib -r ..\..\..\game\bin\legion.pdb
+copy &quot;$(TargetDir)&quot;legion.pdb ..\..\..\game\bin
+"
+ Outputs="..\..\..\game\bin\legion.exe;..\..\..\game\bin\legion.pdb"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ OutputFile="$(OutDir)/legion.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="TRUE"
+ AdditionalLibraryDirectories="..\..\lib\public;..\..\lib\common"
+ IgnoreDefaultLibraryNames="libcmt.lib"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/legion.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="3"
+ AdditionalIncludeDirectories="..\..\public;..\..\public\tier1;..\..\common"
+ PreprocessorDefinitions="_WIN32;NDEBUG;_WINDOWS"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="0"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="$(IntDir)/legion.pdb"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="if exist ..\..\..\game\bin\legion.exe attrib -r ..\..\..\game\bin\legion.exe
+copy &quot;$(TargetPath)&quot; ..\..\..\game\bin
+if exist ..\..\..\game\bin\legion.pdb attrib -r ..\..\..\game\bin\legion.pdb
+copy &quot;$(TargetDir)&quot;legion.pdb ..\..\..\game\bin
+"
+ Outputs="..\..\..\game\bin\legion.exe;..\..\..\game\bin\legion.pdb"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ OutputFile="$(OutDir)/legion.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ AdditionalLibraryDirectories="..\..\lib\public;..\..\lib\common"
+ IgnoreDefaultLibraryNames="libcmtd.lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\basemenu.cpp">
+ </File>
+ <File
+ RelativePath=".\gamemanager.cpp">
+ </File>
+ <File
+ RelativePath=".\heightfield.cpp">
+ </File>
+ <File
+ RelativePath=".\hostgamemenu.cpp">
+ </File>
+ <File
+ RelativePath=".\inputmanager.cpp">
+ </File>
+ <File
+ RelativePath=".\joingamemenu.cpp">
+ </File>
+ <File
+ RelativePath=".\legion.cpp">
+ </File>
+ <File
+ RelativePath=".\mainmenu.cpp">
+ </File>
+ <File
+ RelativePath="..\..\public\tier0\memoverride.cpp">
+ </File>
+ <File
+ RelativePath=".\menumanager.cpp">
+ </File>
+ <File
+ RelativePath=".\networkmanager.cpp">
+ </File>
+ <File
+ RelativePath=".\networkmessages.cpp">
+ </File>
+ <File
+ RelativePath=".\networkmessages.h">
+ </File>
+ <File
+ RelativePath=".\physicsmanager.cpp">
+ </File>
+ <File
+ RelativePath=".\rendermanager.cpp">
+ </File>
+ <File
+ RelativePath=".\uimanager.cpp">
+ </File>
+ <File
+ RelativePath=".\worldmanager.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\basemenu.h">
+ </File>
+ <File
+ RelativePath=".\gamemanager.h">
+ </File>
+ <File
+ RelativePath=".\heightfield.h">
+ </File>
+ <File
+ RelativePath=".\inetworkmessagelistener.h">
+ </File>
+ <File
+ RelativePath=".\inputmanager.h">
+ </File>
+ <File
+ RelativePath=".\legion.h">
+ </File>
+ <File
+ RelativePath=".\menumanager.h">
+ </File>
+ <File
+ RelativePath=".\networkmanager.h">
+ </File>
+ <File
+ RelativePath=".\physicsmanager.h">
+ </File>
+ <File
+ RelativePath=".\rendermanager.h">
+ </File>
+ <File
+ RelativePath=".\uimanager.h">
+ </File>
+ <File
+ RelativePath=".\worldmanager.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="External Dependencies"
+ Filter="">
+ <File
+ RelativePath="..\..\public\mathlib\math_base.h">
+ </File>
+ <File
+ RelativePath="..\..\public\tier1\utlstack.h">
+ </File>
+ <File
+ RelativePath="..\..\public\tier1\utlstring.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\lib\public\appframework.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\bitmap.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\mathlib.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\matsys_controls.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\tier0.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\tier1.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\tier2.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\tier3.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\vgui_controls.lib">
+ </File>
+ <File
+ RelativePath="..\..\lib\public\vstdlib.lib">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/app/legion/mainmenu.cpp b/app/legion/mainmenu.cpp
new file mode 100644
index 0000000..b60b4d6
--- /dev/null
+++ b/app/legion/mainmenu.cpp
@@ -0,0 +1,46 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: List of game systems to update
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "menumanager.h"
+#include "basemenu.h"
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+class CMainMenu : public CBaseMenu
+{
+ DECLARE_CLASS_SIMPLE( CMainMenu, CBaseMenu );
+
+public:
+ CMainMenu( vgui::Panel *pParent, const char *pPanelName );
+ virtual ~CMainMenu();
+
+private:
+};
+
+
+//-----------------------------------------------------------------------------
+// Hooks the menu into the menu manager
+//-----------------------------------------------------------------------------
+REGISTER_MENU( "MainMenu", CMainMenu );
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+CMainMenu::CMainMenu( vgui::Panel *pParent, const char *pPanelName ) :
+ BaseClass( pParent, pPanelName )
+{
+ LoadControlSettings( "resource/mainmenu.res", "GAME" );
+}
+
+CMainMenu::~CMainMenu()
+{
+}
+
diff --git a/app/legion/menumanager.cpp b/app/legion/menumanager.cpp
new file mode 100644
index 0000000..9fdd438
--- /dev/null
+++ b/app/legion/menumanager.cpp
@@ -0,0 +1,195 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The menu manager
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "menumanager.h"
+#include "vgui_controls/panel.h"
+#include "vgui_controls/frame.h"
+#include "uimanager.h"
+
+
+//-----------------------------------------------------------------------------
+// Singleton
+//-----------------------------------------------------------------------------
+static CMenuManager s_MenuManager;
+extern CMenuManager *g_pMenuManager = &s_MenuManager;
+
+
+//-----------------------------------------------------------------------------
+// Static members.
+// NOTE: Do *not* set this to 0; it could cause us to lose some registered
+// menus since that list is set up during construction
+//-----------------------------------------------------------------------------
+IMenuFactory *CMenuManager::m_pFirstFactory;
+
+
+//-----------------------------------------------------------------------------
+// Call to register methods which can construct menus w/ particular names
+//-----------------------------------------------------------------------------
+IMenuFactory *CMenuManager::RegisterMenu( IMenuFactory *pMenuFactory )
+{
+ // NOTE: This method is expected to be called during global constructor
+ // time, so it must not require any global constructors to be called to work
+ IMenuFactory *pPrevFactory = m_pFirstFactory;
+ m_pFirstFactory = pMenuFactory;
+ return pPrevFactory;
+}
+
+
+//-----------------------------------------------------------------------------
+// Init, shutdown
+//-----------------------------------------------------------------------------
+bool CMenuManager::Init()
+{
+ // Build a dictionary of all registered menus
+ IMenuFactory *pFactory;
+ for ( pFactory = m_pFirstFactory; pFactory; pFactory = pFactory->GetNextFactory() )
+ {
+ m_MenuFactories.Insert( pFactory->GetMenuName(), pFactory );
+ }
+
+ m_bPopRequested = false;
+ m_bPopAllRequested = false;
+ m_pPushRequested = NULL;
+
+ return true;
+}
+
+void CMenuManager::Shutdown()
+{
+ CleanUpAllMenus();
+}
+
+
+//-----------------------------------------------------------------------------
+// Push, pop menus
+//-----------------------------------------------------------------------------
+void CMenuManager::PushMenu( const char *pMenuName )
+{
+ AssertMsg( !m_pPushRequested, "Can't request to push two menus in a single frame!" );
+
+ MenuFactoryIndex_t i = m_MenuFactories.Find( pMenuName );
+ if ( i == m_MenuFactories.InvalidIndex() )
+ {
+ Warning( "Tried to push unknown menu %s\n", pMenuName );
+ return;
+ }
+ m_pPushRequested = m_MenuFactories[i];
+}
+
+void CMenuManager::PopMenu( )
+{
+ AssertMsg( !m_bPopRequested, "Can't request to pop two menus in a single frame!" );
+ AssertMsg( !m_pPushRequested, "Can't request to pop after requesting to push a menu in a single frame!" );
+ m_bPopRequested = true;
+}
+
+void CMenuManager::PopAllMenus( )
+{
+ AssertMsg( !m_pPushRequested, "Can't request to pop after requesting to push a menu in a single frame!" );
+ m_bPopAllRequested = true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Request a menu to switch to
+//-----------------------------------------------------------------------------
+void CMenuManager::SwitchToMenu( const char *pMenuName )
+{
+ AssertMsg( !m_bPopRequested, "Can't request to pop two menus in a single frame!" );
+ AssertMsg( !m_pPushRequested, "Can't request to push two menus in a single frame!" );
+
+ MenuFactoryIndex_t i = m_MenuFactories.Find( pMenuName );
+ if ( i == m_MenuFactories.InvalidIndex() )
+ {
+ Warning( "Tried to switch to unknown menu %s\n", pMenuName );
+ return;
+ }
+ m_bPopRequested = true;
+ m_pPushRequested = m_MenuFactories[i];
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the name of the topmost panel
+//-----------------------------------------------------------------------------
+const char *CMenuManager::GetTopmostPanelName()
+{
+ if ( !m_nActiveMenu.Count() )
+ return NULL;
+ return m_nActiveMenu.Top()->GetName();
+}
+
+
+//-----------------------------------------------------------------------------
+// Request a menu to switch to
+//-----------------------------------------------------------------------------
+void CMenuManager::Update( )
+{
+ if ( m_bPopAllRequested )
+ {
+ CleanUpAllMenus();
+ m_bPopAllRequested = false;
+ return;
+ }
+
+ if ( m_bPopRequested )
+ {
+ AssertMsg( m_nActiveMenu.Count(), "Tried to pop a menu when no menus are active" );
+ vgui::Panel *pTop = m_nActiveMenu.Top();
+ pTop->MarkForDeletion();
+ m_nActiveMenu.Pop();
+
+ // Mark the new active menu as visible, attach it to hierarchy.
+ if ( m_nActiveMenu.Count() > 0 )
+ {
+ vgui::Panel *pTop = m_nActiveMenu.Top();
+ pTop->SetVisible( true );
+ pTop->SetParent( g_pUIManager->GetRootPanel( UI_ROOT_MENU ) );
+ }
+ else
+ {
+ g_pUIManager->EnablePanel( UI_ROOT_MENU, false );
+ }
+ m_bPopRequested = false;
+ }
+
+ if ( m_pPushRequested )
+ {
+ // Mark the previous menu as not visible, detach it from hierarchy.
+ if ( m_nActiveMenu.Count() > 0 )
+ {
+ vgui::Panel *pTop = m_nActiveMenu.Top();
+ pTop->SetVisible( false );
+ pTop->SetParent( (vgui::Panel*)NULL );
+ }
+ else
+ {
+ g_pUIManager->EnablePanel( UI_ROOT_MENU, true );
+ }
+ vgui::Panel *pMenu = m_pPushRequested->CreateMenu( g_pUIManager->GetRootPanel( UI_ROOT_MENU ) );
+ m_nActiveMenu.Push( pMenu );
+ static_cast<vgui::Frame*>( pMenu )->Activate();
+ m_pPushRequested = NULL;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Cleans up all menus
+//-----------------------------------------------------------------------------
+void CMenuManager::CleanUpAllMenus()
+{
+ while ( m_nActiveMenu.Count() )
+ {
+ vgui::Panel *pTop = m_nActiveMenu.Top();
+ pTop->MarkForDeletion();
+ m_nActiveMenu.Pop();
+ }
+ g_pUIManager->EnablePanel( UI_ROOT_MENU, false );
+}
+
diff --git a/app/legion/menumanager.h b/app/legion/menumanager.h
new file mode 100644
index 0000000..e3096cd
--- /dev/null
+++ b/app/legion/menumanager.h
@@ -0,0 +1,140 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The manager that deals with menus
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef MENUMANAGER_H
+#define MENUMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gamemanager.h"
+#include "tier1/utldict.h"
+#include "tier1/utlstack.h"
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+namespace vgui
+{
+ class Panel;
+}
+
+
+//-----------------------------------------------------------------------------
+// Interface used to create menus
+//-----------------------------------------------------------------------------
+abstract_class IMenuFactory
+{
+public:
+ // Returns the name of the menu it will create
+ virtual const char *GetMenuName() = 0;
+
+ // Creates the menu
+ virtual vgui::Panel *CreateMenu( vgui::Panel *pParent ) = 0;
+
+ // Used to build a list during construction
+ virtual IMenuFactory *GetNextFactory( ) = 0;
+
+protected:
+ virtual ~IMenuFactory() {}
+};
+
+
+//-----------------------------------------------------------------------------
+// Menu managemer
+//-----------------------------------------------------------------------------
+class CMenuManager : public CGameManager<>
+{
+public:
+ typedef vgui::Panel* (*MenuFactory_t)( vgui::Panel *pParent );
+
+ // Inherited from IGameManager
+ virtual bool Init();
+ virtual void Update( );
+ virtual void Shutdown();
+
+ // Push, pop menus
+ void PushMenu( const char *pMenuName );
+ void PopMenu( );
+ void PopAllMenus( );
+
+ // Pop the top menu, push specified menu
+ void SwitchToMenu( const char *pMenuName );
+
+ // Returns the name of the topmost panel
+ const char *GetTopmostPanelName();
+
+ // Call to register methods which can construct menus w/ particular ids
+ // NOTE: This method is not expected to be called directly. Use the REGISTER_MENU macro instead
+ // It returns the previous head of the list of factories
+ static IMenuFactory* RegisterMenu( IMenuFactory *pMenuFactory );
+
+private:
+ void CleanUpAllMenus();
+
+ typedef unsigned char MenuFactoryIndex_t;
+ CUtlDict< IMenuFactory *, MenuFactoryIndex_t > m_MenuFactories;
+ CUtlStack< vgui::Panel * > m_nActiveMenu;
+ bool m_bPopRequested;
+ bool m_bPopAllRequested;
+ IMenuFactory *m_pPushRequested;
+ static IMenuFactory *m_pFirstFactory;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+extern CMenuManager *g_pMenuManager;
+
+
+//-----------------------------------------------------------------------------
+// Macro used to register menus with the menu manager
+// For example, add the line REGISTER_MENU( "MainMenu", CMainMenu );
+// into the class defining the main menu
+//-----------------------------------------------------------------------------
+template < class T >
+class CMenuFactory : public IMenuFactory
+{
+public:
+ CMenuFactory( const char *pMenuName ) : m_pMenuName( pMenuName )
+ {
+ m_pNextFactory = CMenuManager::RegisterMenu( this );
+ }
+
+ // Returns the name of the menu it will create
+ virtual const char *GetMenuName()
+ {
+ return m_pMenuName;
+ }
+
+ // Creates the menu
+ virtual vgui::Panel *CreateMenu( vgui::Panel *pParent )
+ {
+ return new T( pParent, m_pMenuName );
+ }
+
+ // Used to build a list during construction
+ virtual IMenuFactory *GetNextFactory( )
+ {
+ return m_pNextFactory;
+ }
+
+private:
+ const char* m_pMenuName;
+ IMenuFactory *m_pNextFactory;
+};
+
+#define REGISTER_MENU( _name, _className ) \
+ static CMenuFactory< _className > s_Factory ## _className( _name )
+
+
+#endif // MENUMANAGER_H
+
diff --git a/app/legion/networkmanager.cpp b/app/legion/networkmanager.cpp
new file mode 100644
index 0000000..062e066
--- /dev/null
+++ b/app/legion/networkmanager.cpp
@@ -0,0 +1,393 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the networking code in the game
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "networkmanager.h"
+#include "legion.h"
+#include "networksystem/inetworkmessage.h"
+#include "tier1/bitbuf.h"
+#include "inetworkmessagelistener.h"
+#include "tier0/icommandline.h"
+#include "tier2/tier2.h"
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+static CNetworkManager s_NetworkManager;
+extern CNetworkManager *g_pNetworkManager = &s_NetworkManager;
+
+
+//-----------------------------------------------------------------------------
+// Static members.
+// NOTE: Do *not* set this to 0; it could cause us to lose some registered
+// menus since that list is set up during construction
+//-----------------------------------------------------------------------------
+INetworkMessageFactory *CNetworkManager::m_pFirstFactory;
+
+
+//-----------------------------------------------------------------------------
+// Call to register methods to register network messages
+//-----------------------------------------------------------------------------
+INetworkMessageFactory *CNetworkManager::RegisterNetworkMessage( INetworkMessageFactory *pNetworkMessageFactory )
+{
+ // NOTE: This method is expected to be called during global constructor
+ // time, so it must not require any global constructors to be called to work
+ INetworkMessageFactory *pPrevFactory = m_pFirstFactory;
+ m_pFirstFactory = pNetworkMessageFactory;
+ return pPrevFactory;
+}
+
+
+//-----------------------------------------------------------------------------
+// Init, shutdown
+//-----------------------------------------------------------------------------
+bool CNetworkManager::Init()
+{
+ m_bIsClient = m_bIsServer = false;
+ m_pClientToServerConnection = NULL;
+
+ // Make a listener array for each message type
+
+ // Register all network messages
+ INetworkMessageFactory *pFactory;
+ for ( pFactory = m_pFirstFactory; pFactory; pFactory = pFactory->GetNextFactory() )
+ {
+ INetworkMessage *pNetworkMessage = pFactory->CreateNetworkMessage();
+ g_pNetworkSystem->RegisterMessage( pNetworkMessage );
+ }
+
+ return true;
+}
+
+void CNetworkManager::Shutdown()
+{
+ ShutdownClient();
+ ShutdownServer();
+}
+
+
+//-----------------------------------------------------------------------------
+// Start a server up
+//-----------------------------------------------------------------------------
+bool CNetworkManager::StartServer( unsigned short nServerListenPort )
+{
+ ShutdownServer( );
+ if ( nServerListenPort == LEGION_DEFAULT_SERVER_PORT )
+ {
+ nServerListenPort = CommandLine()->ParmValue( "-serverport", NETWORKSYSTEM_DEFAULT_SERVER_PORT );
+ }
+ m_bIsServer = g_pNetworkSystem->StartServer( nServerListenPort );
+ return m_bIsServer;
+}
+
+void CNetworkManager::ShutdownServer( )
+{
+ if ( m_bIsServer )
+ {
+ g_pNetworkSystem->ShutdownServer( );
+ m_bIsServer = false;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Start a client up
+//-----------------------------------------------------------------------------
+bool CNetworkManager::StartClient( unsigned short nClientListenPort )
+{
+ ShutdownClient( );
+
+ if ( nClientListenPort == LEGION_DEFAULT_CLIENT_PORT )
+ {
+ nClientListenPort = CommandLine()->ParmValue( "-clientport", NETWORKSYSTEM_DEFAULT_CLIENT_PORT );
+ }
+
+ m_bIsClient = g_pNetworkSystem->StartClient( nClientListenPort );
+ return m_bIsClient;
+}
+
+void CNetworkManager::ShutdownClient( )
+{
+ if ( m_bIsClient )
+ {
+ DisconnectClientFromServer();
+ g_pNetworkSystem->ShutdownClient( );
+ m_bIsClient = false;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Connects/disconnects the client to a server
+//-----------------------------------------------------------------------------
+bool CNetworkManager::ConnectClientToServer( const char *pServerName, unsigned short nServerListenPort )
+{
+ DisconnectClientFromServer();
+ if ( !IsClient() )
+ return false;
+
+ if ( nServerListenPort == LEGION_DEFAULT_SERVER_PORT )
+ {
+ nServerListenPort = CommandLine()->ParmValue( "-serverport", NETWORKSYSTEM_DEFAULT_SERVER_PORT );
+ }
+ m_pClientToServerConnection = g_pNetworkSystem->ConnectClientToServer( pServerName, nServerListenPort );
+ return ( m_pClientToServerConnection != NULL );
+}
+
+void CNetworkManager::DisconnectClientFromServer( )
+{
+ if ( m_pClientToServerConnection )
+ {
+ g_pNetworkSystem->DisconnectClientFromServer( m_pClientToServerConnection );
+ m_pClientToServerConnection = NULL;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Start up a game where the local player is playing
+//-----------------------------------------------------------------------------
+bool CNetworkManager::HostGame()
+{
+ if ( !StartServer() )
+ return false;
+
+ if ( !StartClient() )
+ {
+ ShutdownServer();
+ return false;
+ }
+
+ if ( !ConnectClientToServer( "localhost" ) )
+ {
+ ShutdownClient();
+ ShutdownServer();
+ return false;
+ }
+
+ return true;
+}
+
+void CNetworkManager::StopHostingGame()
+{
+ ShutdownClient();
+ ShutdownServer();
+}
+
+
+//-----------------------------------------------------------------------------
+// Are we a client?/Are we a server? (we can be both)
+//-----------------------------------------------------------------------------
+bool CNetworkManager::IsClient()
+{
+ return m_bIsClient;
+}
+
+bool CNetworkManager::IsServer()
+{
+ return m_bIsServer;
+}
+
+
+//-----------------------------------------------------------------------------
+// If we are a client, are we connected to the server?
+//-----------------------------------------------------------------------------
+bool CNetworkManager::IsClientConnected()
+{
+ return m_bIsClient && ( m_pClientToServerConnection != NULL ) && ( m_pClientToServerConnection->GetConnectionState() == CONNECTION_STATE_CONNECTED );
+}
+
+
+//-----------------------------------------------------------------------------
+// Post a network message to the server
+//-----------------------------------------------------------------------------
+void CNetworkManager::PostClientToServerMessage( INetworkMessage *pMessage )
+{
+ if ( IsClientConnected() )
+ {
+ m_pClientToServerConnection->AddNetMsg( pMessage );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Broadcast a network message to all clients
+//-----------------------------------------------------------------------------
+void CNetworkManager::BroadcastServerToClientMessage( INetworkMessage *pMessage )
+{
+ if ( IsServer() )
+ {
+ int nCount = m_ServerToClientConnection.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ m_ServerToClientConnection[i]->AddNetMsg( pMessage );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Add, remove network message listeners
+//-----------------------------------------------------------------------------
+void CNetworkManager::AddListener( NetworkMessageRoute_t route, int nGroup, int nType, INetworkMessageListener *pListener )
+{
+ CUtlVector< CUtlVector< CUtlVector < INetworkMessageListener* > > > &listeners = m_Listeners[ route ];
+ if ( listeners.Count() <= nGroup )
+ {
+ listeners.AddMultipleToTail( nGroup - listeners.Count() + 1 );
+ }
+
+ if ( listeners[nGroup].Count() <= nType )
+ {
+ listeners[nGroup].AddMultipleToTail( nType - listeners[nGroup].Count() + 1 );
+ }
+
+ Assert( listeners[nGroup][nType].Find( pListener ) < 0 );
+ listeners[nGroup][nType].AddToTail( pListener );
+}
+
+void CNetworkManager::RemoveListener( NetworkMessageRoute_t route, int nGroup, int nType, INetworkMessageListener *pListener )
+{
+ CUtlVector< CUtlVector< CUtlVector < INetworkMessageListener* > > > &listeners = m_Listeners[ route ];
+ if ( listeners.Count() > nGroup )
+ {
+ if( listeners[nGroup].Count() > nType )
+ {
+ // Maintain order of listeners (not sure if it matters)
+ listeners[nGroup][nType].FindAndRemove( pListener );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Notifies listeners about a network message
+//-----------------------------------------------------------------------------
+void CNetworkManager::NotifyListeners( NetworkMessageRoute_t route, INetworkMessage *pMessage )
+{
+ CUtlVector< CUtlVector< CUtlVector < INetworkMessageListener* > > > &listeners = m_Listeners[ route ];
+
+ // based on id, search for installed listeners
+ int nGroup = pMessage->GetGroup();
+ if ( listeners.Count() > nGroup )
+ {
+ int nType = pMessage->GetType();
+ if ( listeners[nGroup].Count() > nType )
+ {
+ CUtlVector< INetworkMessageListener* > &list = listeners[nGroup][nType];
+ int nCount = list.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ list[i]->OnNetworkMessage( route, pMessage );
+ }
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Process messages received by the client
+//-----------------------------------------------------------------------------
+void CNetworkManager::ProcessClientMessages()
+{
+ NetworkEvent_t *pEvent = g_pNetworkSystem->FirstNetworkEvent();
+ for ( ; pEvent; pEvent = g_pNetworkSystem->NextNetworkEvent( ) )
+ {
+ switch ( pEvent->m_nType )
+ {
+ /*
+ case NETWORK_EVENT_CONNECTED:
+ {
+ NetworkConnectionEvent_t* pConnectEvent = static_cast<NetworkConnectionEvent_t*>( pEvent );
+ m_pClientToServerConnection = pConnectEvent->m_pChannel;
+ }
+ break;
+
+ case NETWORK_EVENT_DISCONNECTED:
+ {
+ NetworkDisconnectionEvent_t* pDisconnectEvent = static_cast<NetworkDisconnectionEvent_t*>( pEvent );
+ Assert( m_pClientToServerConnection == pDisconnectEvent->m_pChannel );
+ if ( m_pClientToServerConnection == pDisconnectEvent->m_pChannel )
+ {
+ m_pClientToServerConnection = NULL;
+ }
+ }
+ break;
+ */
+
+ case NETWORK_EVENT_MESSAGE_RECEIVED:
+ {
+ NetworkMessageReceivedEvent_t* pPacketEvent = static_cast<NetworkMessageReceivedEvent_t*>( pEvent );
+ NotifyListeners( NETWORK_MESSAGE_SERVER_TO_CLIENT, pPacketEvent->m_pNetworkMessage );
+ }
+ break;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Process messages received by the server
+//-----------------------------------------------------------------------------
+void CNetworkManager::ProcessServerMessages()
+{
+ NetworkEvent_t *pEvent = g_pNetworkSystem->FirstNetworkEvent();
+ for ( ; pEvent; pEvent = g_pNetworkSystem->NextNetworkEvent( ) )
+ {
+ switch ( pEvent->m_nType )
+ {
+ case NETWORK_EVENT_CONNECTED:
+ {
+ NetworkConnectionEvent_t* pConnectEvent = static_cast<NetworkConnectionEvent_t*>( pEvent );
+ m_ServerToClientConnection.AddToTail( pConnectEvent->m_pChannel );
+ }
+ break;
+
+ case NETWORK_EVENT_DISCONNECTED:
+ {
+ NetworkDisconnectionEvent_t* pDisconnectEvent = static_cast<NetworkDisconnectionEvent_t*>( pEvent );
+ m_ServerToClientConnection.FindAndRemove( pDisconnectEvent->m_pChannel );
+ }
+ break;
+
+ case NETWORK_EVENT_MESSAGE_RECEIVED:
+ {
+ NetworkMessageReceivedEvent_t* pPacketEvent = static_cast<NetworkMessageReceivedEvent_t*>( pEvent );
+ NotifyListeners( NETWORK_MESSAGE_CLIENT_TO_SERVER, pPacketEvent->m_pNetworkMessage );
+ }
+ break;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Per-frame update
+//-----------------------------------------------------------------------------
+void CNetworkManager::Update( )
+{
+ if ( IsClient() )
+ {
+ g_pNetworkSystem->ClientSendMessages();
+ }
+
+ if ( IsServer() )
+ {
+ g_pNetworkSystem->ServerReceiveMessages();
+ ProcessServerMessages();
+ g_pNetworkSystem->ServerSendMessages();
+ }
+
+ if ( IsClient() )
+ {
+ g_pNetworkSystem->ClientReceiveMessages();
+ ProcessClientMessages();
+ }
+}
+
+
diff --git a/app/legion/networkmanager.h b/app/legion/networkmanager.h
new file mode 100644
index 0000000..7383587
--- /dev/null
+++ b/app/legion/networkmanager.h
@@ -0,0 +1,159 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the networking code in the game
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef NETWORKMANAGER_H
+#define NETWORKMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gamemanager.h"
+#include "networksystem/inetworksystem.h"
+#include "inetworkmessagelistener.h"
+
+
+//-----------------------------------------------------------------------------
+// Default ports
+//-----------------------------------------------------------------------------
+enum
+{
+ LEGION_DEFAULT_SERVER_PORT = 0xFFFF,
+ LEGION_DEFAULT_CLIENT_PORT = 0xFFFF,
+};
+
+
+//-----------------------------------------------------------------------------
+// Interface used to create network messages
+//-----------------------------------------------------------------------------
+abstract_class INetworkMessageFactory
+{
+public:
+ // Creates the menu
+ virtual INetworkMessage *CreateNetworkMessage( ) = 0;
+
+ // Used to build a list during construction
+ virtual INetworkMessageFactory *GetNextFactory( ) = 0;
+
+protected:
+ virtual ~INetworkMessageFactory() {}
+};
+
+
+//-----------------------------------------------------------------------------
+// Network management system
+//-----------------------------------------------------------------------------
+class CNetworkManager : public CGameManager<>
+{
+public:
+ // Inherited from IGameManager
+ virtual bool Init();
+ virtual void Update( );
+ virtual void Shutdown();
+
+ // Are we a client?/Are we a server? (we can be both)
+ bool IsClient();
+ bool IsServer();
+
+ // If we are a client, are we connected to the server?
+ bool IsClientConnected();
+
+ // Start a server up
+ bool StartServer( unsigned short nServerListenPort = LEGION_DEFAULT_SERVER_PORT );
+ void ShutdownServer( );
+
+ // Start a client up
+ bool StartClient( unsigned short nClientListenPort = LEGION_DEFAULT_CLIENT_PORT );
+ void ShutdownClient( );
+
+ // Connects the client to a server
+ bool ConnectClientToServer( const char *pServerName, unsigned short nServerListenPort = LEGION_DEFAULT_SERVER_PORT );
+ void DisconnectClientFromServer();
+
+ // Add, remove network message listeners
+ void AddListener( NetworkMessageRoute_t route, int nGroup, int nType, INetworkMessageListener *pListener );
+ void RemoveListener( NetworkMessageRoute_t route, int nGroup, int nType, INetworkMessageListener *hListener );
+
+ // Post a network message to the server
+ void PostClientToServerMessage( INetworkMessage *pMessage );
+
+ // Broadcast a network message to all clients
+ void BroadcastServerToClientMessage( INetworkMessage *pMessage );
+
+ // Start up a game where the local player is playing
+ bool HostGame();
+ void StopHostingGame();
+
+ // Call to register methods which can construct menus w/ particular ids
+ // NOTE: This method is not expected to be called directly. Use the REGISTER_NETWORK_MESSAGE macro instead
+ // It returns the previous head of the list of factories
+ static INetworkMessageFactory* RegisterNetworkMessage( INetworkMessageFactory *pMenuFactory );
+
+private:
+ // Process messages received by the client
+ void ProcessClientMessages();
+
+ // Process messages received by the server
+ void ProcessServerMessages();
+
+ // Notifies listeners about a network message
+ void NotifyListeners( NetworkMessageRoute_t route, INetworkMessage *pMessage );
+
+ bool m_bIsClient;
+ bool m_bIsServer;
+
+ INetChannel *m_pClientToServerConnection;
+ CUtlVector< INetChannel* > m_ServerToClientConnection;
+ CUtlVector< CUtlVector< CUtlVector < INetworkMessageListener* > > > m_Listeners[ NETWORK_MESSAGE_ROUTE_COUNT ];
+ static INetworkMessageFactory* m_pFirstFactory;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+extern CNetworkManager *g_pNetworkManager;
+
+
+//-----------------------------------------------------------------------------
+// Macro used to register menus with the menu system
+// For example, add the line REGISTER_NETWORK_MESSAGE( CNetworkMessageChat );
+// into the file defining the chat message
+//-----------------------------------------------------------------------------
+template < class T >
+class CNetworkMessageFactory : public INetworkMessageFactory
+{
+public:
+ CNetworkMessageFactory( )
+ {
+ m_pNextFactory = CNetworkManager::RegisterNetworkMessage( this );
+ }
+
+ // Creates the network message
+ virtual INetworkMessage *CreateNetworkMessage( )
+ {
+ return new T;
+ }
+
+ // Used to build a list during construction
+ virtual INetworkMessageFactory *GetNextFactory( )
+ {
+ return m_pNextFactory;
+ }
+
+private:
+ INetworkMessage *m_pMessage;
+ INetworkMessageFactory *m_pNextFactory;
+};
+
+#define REGISTER_NETWORK_MESSAGE( _className ) \
+ static CNetworkMessageFactory< _className > __s_Factory ## _className
+
+
+#endif // NETWORKMANAGER_H
+
diff --git a/app/legion/networkmessages.cpp b/app/legion/networkmessages.cpp
new file mode 100644
index 0000000..3b382a9
--- /dev/null
+++ b/app/legion/networkmessages.cpp
@@ -0,0 +1,51 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: A network message that sends chat messages
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "networkmessages.h"
+#include "networkmanager.h"
+#include "tier1/bitbuf.h"
+
+
+//-----------------------------------------------------------------------------
+// Chat network message
+//-----------------------------------------------------------------------------
+REGISTER_NETWORK_MESSAGE( CNetworkMessage_Chat );
+
+CNetworkMessage_Chat::CNetworkMessage_Chat()
+{
+ SetReliable( false );
+}
+
+bool CNetworkMessage_Chat::WriteToBuffer( bf_write &buffer )
+{
+ int nLen = m_Message.Length();
+ buffer.WriteShort( nLen );
+ if ( nLen )
+ {
+ buffer.WriteBytes( m_Message.Get(), nLen );
+ }
+ return !buffer.IsOverflowed();
+}
+
+bool CNetworkMessage_Chat::ReadFromBuffer( bf_read &buffer )
+{
+ int nLen = buffer.ReadShort();
+ if ( nLen )
+ {
+ m_Message.SetLength( nLen + 1 );
+ char *pDest = m_Message.Get();
+ buffer.ReadBytes( pDest, nLen );
+ pDest[ nLen ] = 0;
+ }
+ else
+ {
+ m_Message.Set( NULL );
+ }
+ return !buffer.IsOverflowed();
+}
+
diff --git a/app/legion/networkmessages.h b/app/legion/networkmessages.h
new file mode 100644
index 0000000..ea29773
--- /dev/null
+++ b/app/legion/networkmessages.h
@@ -0,0 +1,54 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the networking code in the game
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef NETWORKMESSAGES_H
+#define NETWORKMESSAGES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "networksystem/inetworkmessage.h"
+#include "tier1/utlstring.h"
+
+
+//-----------------------------------------------------------------------------
+// Network message group
+//-----------------------------------------------------------------------------
+enum LegionNetworkGroups_t
+{
+ LEGION_NETMESSAGE_GROUP = NETWORKSYSTEM_FIRST_GROUP,
+};
+
+
+//-----------------------------------------------------------------------------
+// Network message types
+//-----------------------------------------------------------------------------
+enum LegionNetworkTypes_t
+{
+ CHAT_MESSAGE = 0,
+};
+
+
+//-----------------------------------------------------------------------------
+// Chat network message
+//-----------------------------------------------------------------------------
+class CNetworkMessage_Chat : public CNetworkMessage
+{
+public:
+ CNetworkMessage_Chat();
+
+ DECLARE_BASE_MESSAGE( LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, "Chat Message" )
+
+ CUtlString m_Message;
+};
+
+#endif // NETWORKMESSAGES_H
+
+
diff --git a/app/legion/physicsmanager.cpp b/app/legion/physicsmanager.cpp
new file mode 100644
index 0000000..66a4650
--- /dev/null
+++ b/app/legion/physicsmanager.cpp
@@ -0,0 +1,29 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the physics
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "physicsmanager.h"
+#include "legion.h"
+#include "tier2/tier2.h"
+#include "tier1/convar.h"
+
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+static CPhysicsManager s_PhysicsManager;
+extern CPhysicsManager *g_pPhysicsManager = &s_PhysicsManager;
+
+
+//-----------------------------------------------------------------------------
+// Per-frame update
+//-----------------------------------------------------------------------------
+void CPhysicsManager::Update( )
+{
+}
+
diff --git a/app/legion/physicsmanager.h b/app/legion/physicsmanager.h
new file mode 100644
index 0000000..10ea08f
--- /dev/null
+++ b/app/legion/physicsmanager.h
@@ -0,0 +1,43 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the physics
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef PHYSICSMANAGER_H
+#define PHYSICSMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gamemanager.h"
+#include "tier2/keybindings.h"
+#include "tier1/commandbuffer.h"
+#include "bitvec.h"
+
+
+//-----------------------------------------------------------------------------
+// Input management
+//-----------------------------------------------------------------------------
+class CPhysicsManager : public CGameManager<>
+{
+public:
+ // Inherited from IGameManager
+ virtual void Update( );
+ virtual bool PerformsSimulation() { return true; }
+
+private:
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+extern CPhysicsManager *g_pPhysicsManager;
+
+
+#endif // PHYSICSMANAGER_H
+
diff --git a/app/legion/rendermanager.cpp b/app/legion/rendermanager.cpp
new file mode 100644
index 0000000..5d2e2a4
--- /dev/null
+++ b/app/legion/rendermanager.cpp
@@ -0,0 +1,255 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the rendering
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "rendermanager.h"
+#include "legion.h"
+#include "uimanager.h"
+#include "worldmanager.h"
+#include "materialsystem/imaterialsystem.h"
+#include "tier2/tier2.h"
+
+
+//-----------------------------------------------------------------------------
+// Camera property
+//-----------------------------------------------------------------------------
+DEFINE_FIXEDSIZE_ALLOCATOR( CCameraProperty, 1, CMemoryPool::GROW_SLOW );
+
+
+CCameraProperty::CCameraProperty()
+{
+ m_Origin.Init();
+ m_Angles.Init();
+ m_Velocity.Init();
+ m_AngVelocity.Init();
+}
+
+void CCameraProperty::GetForward( Vector *pForward )
+{
+ AngleVectors( m_Angles, pForward );
+}
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+static CRenderManager s_RenderManager;
+extern CRenderManager *g_pRenderManager = &s_RenderManager;
+
+
+//-----------------------------------------------------------------------------
+// Game initialization
+//-----------------------------------------------------------------------------
+bool CRenderManager::Init()
+{
+ m_bRenderWorldFullscreen = true;
+ return true;
+}
+
+void CRenderManager::Shutdown()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Level initialization
+//-----------------------------------------------------------------------------
+LevelRetVal_t CRenderManager::LevelInit( bool bFirstCall )
+{
+ return FINISHED;
+}
+
+LevelRetVal_t CRenderManager::LevelShutdown( bool bFirstCall )
+{
+ return FINISHED;
+}
+
+
+//-----------------------------------------------------------------------------
+// Property allocation
+//-----------------------------------------------------------------------------
+CCameraProperty *CRenderManager::CreateCameraProperty()
+{
+ return new CCameraProperty;
+}
+
+void CRenderManager::DestroyCameraProperty( CCameraProperty *pProperty )
+{
+ delete pProperty;
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets the rectangle to draw into
+//-----------------------------------------------------------------------------
+void CRenderManager::RenderWorldFullscreen()
+{
+ m_bRenderWorldFullscreen = true;
+}
+
+void CRenderManager::RenderWorldInRect( int x, int y, int nWidth, int nHeight )
+{
+ m_bRenderWorldFullscreen = false;
+ m_nRenderX = x;
+ m_nRenderY = y;
+ m_nRenderWidth = nWidth;
+ m_nRenderHeight = nHeight;
+}
+
+
+//-----------------------------------------------------------------------------
+// Done completely client-side, want total smoothness, so simulate at render interval
+//-----------------------------------------------------------------------------
+void CRenderManager::UpdateLocalPlayerCamera()
+{
+ float dt = IGameManager::DeltaTime();
+ CCameraProperty *pCamera = g_pWorldManager->GetLocalPlayer()->m_pCameraProperty;
+ VectorMA( pCamera->m_Origin, dt, pCamera->m_Velocity, pCamera->m_Origin );
+ VectorMA( pCamera->m_Angles, dt, pCamera->m_AngVelocity, pCamera->m_Angles );
+}
+
+
+//-----------------------------------------------------------------------------
+// Per-frame update
+//-----------------------------------------------------------------------------
+void CRenderManager::Update( )
+{
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ if ( GetLevelState() == NOT_IN_LEVEL )
+ {
+ g_pMaterialSystem->BeginFrame( 0 );
+ pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
+ pRenderContext->ClearBuffers( true, true );
+ g_pUIManager->DrawUI();
+ g_pMaterialSystem->EndFrame();
+ g_pMaterialSystem->SwapBuffers();
+ return;
+ }
+
+ UpdateLocalPlayerCamera();
+
+ g_pMaterialSystem->BeginFrame( 0 );
+ pRenderContext->ClearColor4ub( 0, 0, 0, 255 );
+ pRenderContext->ClearBuffers( true, true );
+ RenderWorld();
+ g_pUIManager->DrawUI();
+ g_pMaterialSystem->EndFrame();
+ g_pMaterialSystem->SwapBuffers();
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets up the camera
+//-----------------------------------------------------------------------------
+void CRenderManager::SetupCameraRenderState( )
+{
+ CCameraProperty *pCamera = g_pWorldManager->GetLocalPlayer()->m_pCameraProperty;
+
+ matrix3x4_t cameraToWorld;
+ AngleMatrix( pCamera->m_Angles, pCamera->m_Origin, cameraToWorld );
+
+ matrix3x4_t matRotate;
+ matrix3x4_t matRotateZ;
+ MatrixBuildRotationAboutAxis( Vector(0,0,1), -90, matRotateZ );
+ MatrixMultiply( cameraToWorld, matRotateZ, matRotate );
+
+ matrix3x4_t matRotateX;
+ MatrixBuildRotationAboutAxis( Vector(1,0,0), 90, matRotateX );
+ MatrixMultiply( matRotate, matRotateX, matRotate );
+
+ matrix3x4_t view;
+ MatrixInvert( matRotate, view );
+
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ pRenderContext->MatrixMode( MATERIAL_VIEW );
+ pRenderContext->LoadMatrix( view );
+}
+
+
+//-----------------------------------------------------------------------------
+// Set up a projection matrix for a 90 degree fov
+//-----------------------------------------------------------------------------
+
+// FIXME: Better control over Z range
+#define ZNEAR 0.1f
+#define ZFAR 10000.0f
+
+void CRenderManager::SetupProjectionMatrix( int nWidth, int nHeight, float flFOV )
+{
+ VMatrix proj;
+ float flZNear = ZNEAR;
+ float flZFar = ZFAR;
+ float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f;
+
+ float halfWidth = tan( flFOV * M_PI / 360.0 );
+ float halfHeight = halfWidth / flApsectRatio;
+
+ memset( proj.Base(), 0, sizeof( proj ) );
+ proj[0][0] = 1.0f / halfWidth;
+ proj[1][1] = 1.0f / halfHeight;
+ proj[2][2] = flZFar / ( flZNear - flZFar );
+ proj[3][2] = -1.0f;
+ proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
+
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->LoadMatrix( proj );
+}
+
+
+//-----------------------------------------------------------------------------
+// Set up a orthographic projection matrix
+//-----------------------------------------------------------------------------
+void CRenderManager::SetupOrthoMatrix( int nWidth, int nHeight )
+{
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->LoadIdentity();
+ pRenderContext->Ortho( 0, 0, nWidth, nHeight, -1.0f, 1.0f );
+}
+
+
+//-----------------------------------------------------------------------------
+// Renders the world
+//-----------------------------------------------------------------------------
+void CRenderManager::RenderWorld()
+{
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->PushMatrix();
+
+ pRenderContext->MatrixMode( MATERIAL_VIEW );
+ pRenderContext->PushMatrix();
+
+ pRenderContext->MatrixMode( MATERIAL_MODEL );
+ pRenderContext->PushMatrix();
+ pRenderContext->LoadIdentity();
+
+ if ( m_bRenderWorldFullscreen )
+ {
+ m_nRenderX = m_nRenderY = 0;
+ pRenderContext->GetRenderTargetDimensions( m_nRenderWidth, m_nRenderHeight );
+ }
+
+ pRenderContext->DepthRange( 0, 1 );
+ pRenderContext->Viewport( m_nRenderX, m_nRenderY, m_nRenderWidth, m_nRenderHeight );
+
+ SetupProjectionMatrix( m_nRenderWidth, m_nRenderHeight, 90 );
+
+ SetupCameraRenderState();
+
+ g_pWorldManager->DrawWorld();
+
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->PopMatrix();
+
+ pRenderContext->MatrixMode( MATERIAL_VIEW );
+ pRenderContext->PopMatrix();
+
+ pRenderContext->MatrixMode( MATERIAL_MODEL );
+ pRenderContext->PopMatrix();
+} \ No newline at end of file
diff --git a/app/legion/rendermanager.h b/app/legion/rendermanager.h
new file mode 100644
index 0000000..555d7b8
--- /dev/null
+++ b/app/legion/rendermanager.h
@@ -0,0 +1,94 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of rendering
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef RENDERMANAGER_H
+#define RENDERMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gamemanager.h"
+#include "tier1/mempool.h"
+#include "mathlib/mathlib.h"
+
+
+//-----------------------------------------------------------------------------
+// Physics property for entities
+//-----------------------------------------------------------------------------
+class CCameraProperty
+{
+ DECLARE_FIXEDSIZE_ALLOCATOR( CCameraProperty );
+
+public:
+ CCameraProperty();
+ void GetForward( Vector *pForward );
+
+ // Array used for fixed-timestep simulation
+ Vector m_Origin;
+ QAngle m_Angles;
+ Vector m_Velocity;
+ QAngle m_AngVelocity;
+
+private:
+ friend class CRenderManager;
+};
+
+
+//-----------------------------------------------------------------------------
+// Rendering management
+//-----------------------------------------------------------------------------
+class CRenderManager : public CGameManager<>
+{
+public:
+ // Inherited from IGameManager
+ virtual bool Init();
+ virtual LevelRetVal_t LevelInit( bool bFirstCall );
+ virtual void Update( );
+ virtual LevelRetVal_t LevelShutdown( bool bFirstCall );
+ virtual void Shutdown();
+
+ // Property allocation
+ CCameraProperty *CreateCameraProperty();
+ void DestroyCameraProperty( CCameraProperty *pProperty );
+
+ void RenderWorldInRect( int x, int y, int nWidth, int nHeight );
+ void RenderWorldFullscreen();
+
+private:
+ // Set up a projection matrix for a 90 degree fov
+ void SetupProjectionMatrix( int nWidth, int nHeight, float flFOV );
+
+ // Set up a orthographic projection matrix
+ void SetupOrthoMatrix( int nWidth, int nHeight );
+
+ // Sets up the camera
+ void SetupCameraRenderState( );
+
+ // Draws the world
+ void RenderWorld();
+
+ // Done completely client-side, want total smoothness, so simulate at render interval
+ void UpdateLocalPlayerCamera();
+
+ bool m_bRenderWorldFullscreen;
+ int m_nRenderX;
+ int m_nRenderY;
+ int m_nRenderWidth;
+ int m_nRenderHeight;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+extern CRenderManager *g_pRenderManager;
+
+
+#endif // RENDERMANAGER_H
+
diff --git a/app/legion/uimanager.cpp b/app/legion/uimanager.cpp
new file mode 100644
index 0000000..ef731f2
--- /dev/null
+++ b/app/legion/uimanager.cpp
@@ -0,0 +1,244 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the UI
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "uimanager.h"
+#include "legion.h"
+#include "appframework/vguimatsysapp.h"
+#include "vgui/IVGui.h"
+#include "vgui/ISurface.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "vgui_controls/controls.h"
+#include "vgui/ILocalize.h"
+#include "vgui_controls/EditablePanel.h"
+#include "vgui_controls/AnimationController.h"
+#include "filesystem.h"
+#include "tier3/tier3.h"
+#include "vgui_controls/consoledialog.h"
+#include "inputmanager.h"
+
+
+//-----------------------------------------------------------------------------
+// Console dialog for use in legion
+//-----------------------------------------------------------------------------
+class CLegionConsoleDialog : public vgui::CConsoleDialog
+{
+ DECLARE_CLASS_SIMPLE( CLegionConsoleDialog, vgui::CConsoleDialog );
+
+public:
+ CLegionConsoleDialog( vgui::Panel *pParent, const char *pName );
+ virtual ~CLegionConsoleDialog();
+
+ virtual void OnClose();
+ MESSAGE_FUNC_CHARPTR( OnCommandSubmitted, "CommandSubmitted", command );
+};
+
+
+CLegionConsoleDialog::CLegionConsoleDialog( vgui::Panel *pParent, const char *pName ) : BaseClass ( pParent, pName )
+{
+ AddActionSignalTarget( this );
+}
+
+CLegionConsoleDialog::~CLegionConsoleDialog()
+{
+ g_pUIManager->HideConsole( );
+}
+
+
+//-----------------------------------------------------------------------------
+// A command was sent by the console
+//-----------------------------------------------------------------------------
+void CLegionConsoleDialog::OnCommandSubmitted( const char *pCommand )
+{
+ g_pInputManager->AddCommand( pCommand );
+}
+
+
+//-----------------------------------------------------------------------------
+// Deals with close
+//-----------------------------------------------------------------------------
+void CLegionConsoleDialog::OnClose()
+{
+ g_pUIManager->HideConsole( );
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+static CUIManager s_UIManager;
+extern CUIManager *g_pUIManager = &s_UIManager;
+
+
+static const char *s_pRootPanelNames[UI_ROOT_PANEL_COUNT] =
+{
+ "RootGamePanel",
+ "RootMenuPanel",
+ "RootToolsPanel",
+};
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CUIManager::CUIManager()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Init, shutdown
+//-----------------------------------------------------------------------------
+bool CUIManager::Init()
+{
+ COMPILE_TIME_ASSERT( sizeof(s_pRootPanelNames) / sizeof(const char*) == UI_ROOT_PANEL_COUNT );
+
+ // load the base localization file
+ if (! vgui::scheme()->LoadSchemeFromFile("resource/legion.res", "Legion" ) )
+ return false;
+
+ vgui::filesystem()->AddSearchPath( "platform", "PLATFORM" );
+ vgui::localize()->AddFile( vgui::filesystem(), "Resource/vgui_%language%.txt" );
+
+ // start vgui
+ g_pVGui->Start();
+
+ // Run a frame to get the embedded panel to be the right size
+ g_pVGui->RunFrame();
+
+ int w, h;
+ m_hEmbeddedPanel = g_pVGuiSurface->GetEmbeddedPanel();
+ vgui::ipanel()->GetSize( m_hEmbeddedPanel, w, h );
+
+ // add our root panels
+ for ( int i = 0; i < UI_ROOT_PANEL_COUNT; ++i )
+ {
+ m_pRootPanels[i] = new vgui::EditablePanel( NULL, s_pRootPanelNames[i] );
+ m_pRootPanels[i]->SetParent( m_hEmbeddedPanel );
+ m_pRootPanels[i]->SetZPos( i );
+ m_pRootPanels[i]->SetBounds( 0, 0, w, h );
+ m_pRootPanels[i]->SetPaintBorderEnabled( false );
+ m_pRootPanels[i]->SetPaintBackgroundEnabled( false );
+ m_pRootPanels[i]->SetPaintEnabled( false );
+ m_pRootPanels[i]->SetKeyBoardInputEnabled( i != UI_ROOT_GAME );
+ m_pRootPanels[i]->SetMouseInputEnabled( i != UI_ROOT_GAME );
+ m_pRootPanels[i]->SetVisible( false );
+ m_pRootPanels[i]->SetCursor( vgui::dc_crosshair );
+ m_pRootPanels[i]->SetAutoResize( vgui::Panel::PIN_TOPLEFT, vgui::Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
+ }
+
+ m_hConsole = NULL;
+
+ vgui::surface()->Invalidate( m_hEmbeddedPanel );
+ return true;
+}
+
+void CUIManager::Shutdown()
+{
+ g_pVGui->Stop();
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets particular root panels to be visible
+//-----------------------------------------------------------------------------
+void CUIManager::EnablePanel( UIRootPanel_t id, bool bEnable )
+{
+ m_pRootPanels[id]->SetVisible( bEnable );
+}
+
+
+//-----------------------------------------------------------------------------
+// Toggles the console
+//-----------------------------------------------------------------------------
+void CUIManager::ToggleConsole( const CCommand &args )
+{
+ if ( !m_hConsole.Get() )
+ {
+ m_hConsole = new CLegionConsoleDialog( m_pRootPanels[UI_ROOT_TOOLS], "Console" );
+
+ // set the console to taking up most of the right-half of the screen
+ int swide, stall;
+ vgui::surface()->GetScreenSize(swide, stall);
+ int offset = vgui::scheme()->GetProportionalScaledValue(16);
+
+ m_hConsole->SetBounds(
+ swide / 2 - (offset * 4),
+ offset,
+ (swide / 2) + (offset * 3),
+ stall - (offset * 8));
+
+ m_hConsole->SetVisible( false );
+ }
+
+ bool bMakeVisible = !m_hConsole->IsVisible();
+ EnablePanel( UI_ROOT_TOOLS, bMakeVisible );
+ if ( bMakeVisible )
+ {
+ m_hConsole->Activate();
+ }
+ else
+ {
+ m_hConsole->Hide();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Hides the console
+//-----------------------------------------------------------------------------
+void CUIManager::HideConsole()
+{
+ EnablePanel( UI_ROOT_TOOLS, false );
+ if ( m_hConsole.Get() )
+ {
+ m_hConsole->SetVisible( false );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Per-frame update
+//-----------------------------------------------------------------------------
+void CUIManager::Update( )
+{
+ vgui::GetAnimationController()->UpdateAnimations( IGameManager::CurrentTime() );
+ g_pVGui->RunFrame();
+ if ( !g_pVGui->IsRunning() )
+ {
+ IGameManager::Stop();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Attempt to process an input event, return true if it sholdn't be chained to the rest of the game
+//-----------------------------------------------------------------------------
+bool CUIManager::ProcessInputEvent( const InputEvent_t& event )
+{
+ return g_pMatSystemSurface->HandleInputEvent( event );
+}
+
+
+//-----------------------------------------------------------------------------
+// Draws the UI
+//-----------------------------------------------------------------------------
+void CUIManager::DrawUI()
+{
+ g_pVGuiSurface->PaintTraverseEx( m_hEmbeddedPanel, true );
+}
+
+
+//-----------------------------------------------------------------------------
+// Push, pop menus
+//-----------------------------------------------------------------------------
+vgui::Panel *CUIManager::GetRootPanel( UIRootPanel_t id )
+{
+ return m_pRootPanels[id];
+}
+
diff --git a/app/legion/uimanager.h b/app/legion/uimanager.h
new file mode 100644
index 0000000..290b0ae
--- /dev/null
+++ b/app/legion/uimanager.h
@@ -0,0 +1,95 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The main manager of the UI
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef UIMANAGER_H
+#define UIMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gamemanager.h"
+#include "vgui/vgui.h"
+#include "tier1/convar.h"
+#include "vgui_controls/panel.h"
+#include "vgui_controls/phandle.h"
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+struct InputEvent_t;
+class CLegionConsoleDialog;
+
+namespace vgui
+{
+ class Panel;
+}
+
+
+//-----------------------------------------------------------------------------
+// Enum indicating the various main UI panels
+// NOTE: The order in which they appear here is the order in which they will draw
+//-----------------------------------------------------------------------------
+enum UIRootPanel_t
+{
+ UI_ROOT_GAME = 0,
+ UI_ROOT_MENU,
+ UI_ROOT_TOOLS,
+
+ UI_ROOT_PANEL_COUNT,
+};
+
+
+//-----------------------------------------------------------------------------
+// UI management
+//-----------------------------------------------------------------------------
+class CUIManager : public CGameManager<>
+{
+public:
+ CUIManager();
+
+ // Inherited from IGameManager
+ virtual bool Init();
+ virtual void Update( );
+ virtual void Shutdown();
+
+ // Root panels
+ vgui::Panel *GetRootPanel( UIRootPanel_t id );
+
+ // Sets particular root panels to be visible
+ void EnablePanel( UIRootPanel_t id, bool bEnable );
+
+ // Attempt to process an input event, return true if it sholdn't be chained to the rest of the game
+ bool ProcessInputEvent( const InputEvent_t& event );
+
+ // Draws the UI
+ void DrawUI();
+
+ // Hides the console
+ void HideConsole();
+
+private:
+ CON_COMMAND_MEMBER_F( CUIManager, "toggleconsole", ToggleConsole, "Toggle Console", 0 );
+
+ vgui::VPANEL m_hEmbeddedPanel;
+ vgui::Panel *m_pRootPanels[ UI_ROOT_PANEL_COUNT ];
+ int m_nWindowWidth;
+ int m_nWindowHeight;
+ vgui::DHANDLE< CLegionConsoleDialog > m_hConsole;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+extern CUIManager *g_pUIManager;
+
+
+#endif // UIMANAGER_H
+
diff --git a/app/legion/worldmanager.cpp b/app/legion/worldmanager.cpp
new file mode 100644
index 0000000..abd5d96
--- /dev/null
+++ b/app/legion/worldmanager.cpp
@@ -0,0 +1,166 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Contains all world state--the main game database
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#include "worldmanager.h"
+#include "legion.h"
+#include "heightfield.h"
+#include "rendermanager.h"
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+static CWorldManager s_WorldManager;
+extern CWorldManager *g_pWorldManager = &s_WorldManager;
+
+
+//-----------------------------------------------------------------------------
+// ConVars
+//-----------------------------------------------------------------------------
+static ConVar cam_forwardspeed( "cam_forwardspeed", "100", FCVAR_CHEAT, "Sets the camera forward speed" );
+static ConVar cam_backwardspeed( "cam_backwardspeed", "100", FCVAR_CHEAT, "Sets the camera backward speed" );
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+CWorldManager::CWorldManager()
+{
+ m_pHeightField = NULL;
+}
+
+CWorldManager::~CWorldManager()
+{
+ Assert( m_pHeightField == NULL );
+}
+
+
+//-----------------------------------------------------------------------------
+// Level init, shutdown
+//-----------------------------------------------------------------------------
+LevelRetVal_t CWorldManager::LevelInit( bool bFirstCall )
+{
+ if ( !bFirstCall )
+ return FINISHED;
+
+ Assert( !m_pHeightField );
+ m_pHeightField = new CHeightField( 6, 6, 4 );
+ if ( !m_pHeightField->LoadHeightFromFile( "maps/testheight.psd" ) )
+ return FAILED;
+
+ CreateEntities();
+ SetInitialLocalPlayerPosition();
+ return FINISHED;
+}
+
+LevelRetVal_t CWorldManager::LevelShutdown( bool bFirstCall )
+{
+ if ( !bFirstCall )
+ return FINISHED;
+
+ DestroyEntities();
+
+ if ( m_pHeightField )
+ {
+ delete m_pHeightField;
+ m_pHeightField = NULL;
+ }
+ return FINISHED;
+}
+
+
+//-----------------------------------------------------------------------------
+// Create/ destroy entities
+//-----------------------------------------------------------------------------
+void CWorldManager::CreateEntities()
+{
+ m_PlayerEntity.m_pCameraProperty = g_pRenderManager->CreateCameraProperty();
+}
+
+void CWorldManager::DestroyEntities()
+{
+ g_pRenderManager->DestroyCameraProperty( m_PlayerEntity.m_pCameraProperty );
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets the camera to world matrix
+//-----------------------------------------------------------------------------
+CPlayerEntity* CWorldManager::GetLocalPlayer()
+{
+ return &m_PlayerEntity;
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets the initial camera position
+//-----------------------------------------------------------------------------
+void CWorldManager::SetInitialLocalPlayerPosition()
+{
+ float flDistance = 1024.0;
+ Vector vecCameraDirection( 1.0f, 1.0f, -0.5f );
+ VectorNormalize( vecCameraDirection );
+
+ VectorMA( Vector( 512, 512, 0 ), -flDistance, vecCameraDirection, m_PlayerEntity.m_pCameraProperty->m_Origin );
+
+ QAngle angles;
+ VectorAngles( vecCameraDirection, m_PlayerEntity.m_pCameraProperty->m_Angles );
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Draws the UI
+//-----------------------------------------------------------------------------
+void CWorldManager::DrawWorld()
+{
+ m_pHeightField->Draw( );
+}
+
+
+//-----------------------------------------------------------------------------
+// Commands
+//-----------------------------------------------------------------------------
+void CWorldManager::ForwardStart( const CCommand &args )
+{
+ CCameraProperty *pCamera = m_PlayerEntity.m_pCameraProperty;
+
+ Vector vecForward;
+ pCamera->GetForward( &vecForward );
+
+ VectorMA( pCamera->m_Velocity, cam_forwardspeed.GetFloat(), vecForward, pCamera->m_Velocity );
+}
+
+void CWorldManager::ForwardStop( const CCommand &args )
+{
+ CCameraProperty *pCamera = m_PlayerEntity.m_pCameraProperty;
+
+ Vector vecForward;
+ pCamera->GetForward( &vecForward );
+
+ VectorMA( pCamera->m_Velocity, -cam_forwardspeed.GetFloat(), vecForward, pCamera->m_Velocity );
+}
+
+void CWorldManager::BackwardStart( const CCommand &args )
+{
+ CCameraProperty *pCamera = m_PlayerEntity.m_pCameraProperty;
+
+ Vector vecForward;
+ pCamera->GetForward( &vecForward );
+
+ VectorMA( pCamera->m_Velocity, -cam_backwardspeed.GetFloat(), vecForward, pCamera->m_Velocity );
+}
+
+void CWorldManager::BackwardStop( const CCommand &args )
+{
+ CCameraProperty *pCamera = m_PlayerEntity.m_pCameraProperty;
+
+ Vector vecForward;
+ pCamera->GetForward( &vecForward );
+
+ VectorMA( pCamera->m_Velocity, cam_backwardspeed.GetFloat(), vecForward, pCamera->m_Velocity );
+} \ No newline at end of file
diff --git a/app/legion/worldmanager.h b/app/legion/worldmanager.h
new file mode 100644
index 0000000..b1aa526
--- /dev/null
+++ b/app/legion/worldmanager.h
@@ -0,0 +1,84 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Contains all world state--the main game database
+//
+// $Revision: $
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef WORLDMANAGER_H
+#define WORLDMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gamemanager.h"
+#include "mathlib/mathlib.h"
+#include "tier1/convar.h"
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class CHeightField;
+class CCameraProperty;
+
+
+//-----------------------------------------------------------------------------
+// Entity types
+//-----------------------------------------------------------------------------
+class CPlayerEntity
+{
+public:
+ CCameraProperty *m_pCameraProperty;
+};
+
+
+//-----------------------------------------------------------------------------
+// World state
+//-----------------------------------------------------------------------------
+class CWorldManager : public CGameManager<>
+{
+public:
+ CWorldManager();
+ virtual ~CWorldManager();
+
+ // Inherited from IGameManager
+ virtual LevelRetVal_t LevelInit( bool bFirstCall );
+// virtual void Update( );
+ virtual LevelRetVal_t LevelShutdown( bool bFirstCall );
+
+ // Draws the world
+ void DrawWorld();
+
+ // Gets the local player
+ CPlayerEntity *GetLocalPlayer();
+
+private:
+ CON_COMMAND_MEMBER_F( CWorldManager, "+forward", ForwardStart, "Start forward movement", 0 );
+ CON_COMMAND_MEMBER_F( CWorldManager, "-forward", ForwardStop, "Stop forward movement", 0 );
+ CON_COMMAND_MEMBER_F( CWorldManager, "+back", BackwardStart, "Start backward movement", 0 );
+ CON_COMMAND_MEMBER_F( CWorldManager, "-back", BackwardStop, "Stop backward movement", 0 );
+
+ // Creates, destroys entities
+ void CreateEntities();
+ void DestroyEntities();
+
+ // Sets the initial camera position
+ void SetInitialLocalPlayerPosition();
+
+ CHeightField *m_pHeightField;
+
+ CPlayerEntity m_PlayerEntity;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton accessor
+//-----------------------------------------------------------------------------
+extern CWorldManager *g_pWorldManager;
+
+
+#endif // WORLDMANAGER_H
+