This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions

95
app/legion/basemenu.cpp Normal file
View File

@ -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 );
}

39
app/legion/basemenu.h Normal file
View File

@ -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

342
app/legion/gamemanager.cpp Normal file
View File

@ -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;
}

160
app/legion/gamemanager.h Normal file
View File

@ -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

276
app/legion/heightfield.cpp Normal file
View File

@ -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();
}

77
app/legion/heightfield.h Normal file
View File

@ -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

201
app/legion/hostgamemenu.cpp Normal file
View File

@ -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 );
}

View File

@ -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

311
app/legion/inputmanager.cpp Normal file
View File

@ -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();
}

55
app/legion/inputmanager.h Normal file
View File

@ -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

213
app/legion/joingamemenu.cpp Normal file
View File

@ -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 );
}

167
app/legion/legion.cpp Normal file
View File

@ -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;
}

64
app/legion/legion.h Normal file
View File

@ -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

289
app/legion/legion.vcproj Normal file
View File

@ -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>

46
app/legion/mainmenu.cpp Normal file
View File

@ -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()
{
}

195
app/legion/menumanager.cpp Normal file
View File

@ -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 );
}

140
app/legion/menumanager.h Normal file
View File

@ -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

View File

@ -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();
}
}

159
app/legion/networkmanager.h Normal file
View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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( )
{
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

244
app/legion/uimanager.cpp Normal file
View File

@ -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];
}

95
app/legion/uimanager.h Normal file
View File

@ -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

166
app/legion/worldmanager.cpp Normal file
View File

@ -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 );
}

84
app/legion/worldmanager.h Normal file
View File

@ -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

View File

@ -0,0 +1,573 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Defines a group of app systems that all have the same lifetime
// that need to be connected/initialized, etc. in a well-defined order
//
// $Revision: $
// $NoKeywords: $
//=============================================================================//
#include "appframework/IAppSystemGroup.h"
#include "appframework/IAppSystem.h"
#include "interface.h"
#include "filesystem.h"
#include "filesystem_init.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
//extern ILoggingListener *g_pDefaultLoggingListener;
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
CAppSystemGroup::CAppSystemGroup( CAppSystemGroup *pAppSystemParent ) : m_SystemDict(false, 0, 16)
{
m_pParentAppSystem = pAppSystemParent;
}
//-----------------------------------------------------------------------------
// Actually loads a DLL
//-----------------------------------------------------------------------------
CSysModule *CAppSystemGroup::LoadModuleDLL( const char *pDLLName )
{
return Sys_LoadModule( pDLLName );
}
//-----------------------------------------------------------------------------
// Methods to load + unload DLLs
//-----------------------------------------------------------------------------
AppModule_t CAppSystemGroup::LoadModule( const char *pDLLName )
{
// Remove the extension when creating the name.
int nLen = Q_strlen( pDLLName ) + 1;
char *pModuleName = (char*)stackalloc( nLen );
Q_StripExtension( pDLLName, pModuleName, nLen );
// See if we already loaded it...
for ( int i = m_Modules.Count(); --i >= 0; )
{
if ( m_Modules[i].m_pModuleName )
{
if ( !Q_stricmp( pModuleName, m_Modules[i].m_pModuleName ) )
return i;
}
}
CSysModule *pSysModule = LoadModuleDLL( pDLLName );
if (!pSysModule)
{
Warning("AppFramework : Unable to load module %s!\n", pDLLName );
return APP_MODULE_INVALID;
}
int nIndex = m_Modules.AddToTail();
m_Modules[nIndex].m_pModule = pSysModule;
m_Modules[nIndex].m_Factory = 0;
m_Modules[nIndex].m_pModuleName = (char*)malloc( nLen );
Q_strncpy( m_Modules[nIndex].m_pModuleName, pModuleName, nLen );
return nIndex;
}
AppModule_t CAppSystemGroup::LoadModule( CreateInterfaceFn factory )
{
if (!factory)
{
Warning("AppFramework : Unable to load module %p!\n", factory );
return APP_MODULE_INVALID;
}
// See if we already loaded it...
for ( int i = m_Modules.Count(); --i >= 0; )
{
if ( m_Modules[i].m_Factory )
{
if ( m_Modules[i].m_Factory == factory )
return i;
}
}
int nIndex = m_Modules.AddToTail();
m_Modules[nIndex].m_pModule = NULL;
m_Modules[nIndex].m_Factory = factory;
m_Modules[nIndex].m_pModuleName = NULL;
return nIndex;
}
void CAppSystemGroup::UnloadAllModules()
{
// NOTE: Iterate in reverse order so they are unloaded in opposite order
// from loading
for (int i = m_Modules.Count(); --i >= 0; )
{
if ( m_Modules[i].m_pModule )
{
Sys_UnloadModule( m_Modules[i].m_pModule );
}
if ( m_Modules[i].m_pModuleName )
{
free( m_Modules[i].m_pModuleName );
}
}
m_Modules.RemoveAll();
}
//-----------------------------------------------------------------------------
// Methods to add/remove various global singleton systems
//-----------------------------------------------------------------------------
IAppSystem *CAppSystemGroup::AddSystem( AppModule_t module, const char *pInterfaceName )
{
if (module == APP_MODULE_INVALID)
return NULL;
Assert( (module >= 0) && (module < m_Modules.Count()) );
CreateInterfaceFn pFactory = m_Modules[module].m_pModule ? Sys_GetFactory( m_Modules[module].m_pModule ) : m_Modules[module].m_Factory;
int retval;
void *pSystem = pFactory( pInterfaceName, &retval );
if ((retval != IFACE_OK) || (!pSystem))
{
Warning("AppFramework : Unable to create system %s!\n", pInterfaceName );
return NULL;
}
IAppSystem *pAppSystem = static_cast<IAppSystem*>(pSystem);
int sysIndex = m_Systems.AddToTail( pAppSystem );
// Inserting into the dict will help us do named lookup later
MEM_ALLOC_CREDIT();
m_SystemDict.Insert( pInterfaceName, sysIndex );
return pAppSystem;
}
static char const *g_StageLookup[] =
{
"CREATION",
"CONNECTION",
"PREINITIALIZATION",
"INITIALIZATION",
"SHUTDOWN",
"POSTSHUTDOWN",
"DISCONNECTION",
"DESTRUCTION",
"NONE",
};
void CAppSystemGroup::ReportStartupFailure( int nErrorStage, int nSysIndex )
{
char const *pszStageDesc = "Unknown";
if ( nErrorStage >= 0 && nErrorStage < ARRAYSIZE( g_StageLookup ) )
{
pszStageDesc = g_StageLookup[ nErrorStage ];
}
char const *pszSystemName = "(Unknown)";
for ( int i = m_SystemDict.First(); i != m_SystemDict.InvalidIndex(); i = m_SystemDict.Next( i ) )
{
if ( m_SystemDict[ i ] != nSysIndex )
continue;
pszSystemName = m_SystemDict.GetElementName( i );
break;
}
// Walk the dictionary
Warning( "System (%s) failed during stage %s\n", pszSystemName, pszStageDesc );
}
void CAppSystemGroup::AddSystem( IAppSystem *pAppSystem, const char *pInterfaceName )
{
if ( !pAppSystem )
return;
int sysIndex = m_Systems.AddToTail( pAppSystem );
// Inserting into the dict will help us do named lookup later
MEM_ALLOC_CREDIT();
m_SystemDict.Insert( pInterfaceName, sysIndex );
}
void CAppSystemGroup::RemoveAllSystems()
{
// NOTE: There's no deallcation here since we don't really know
// how the allocation has happened. We could add a deallocation method
// to the code in interface.h; although when the modules are unloaded
// the deallocation will happen anyways
m_Systems.RemoveAll();
m_SystemDict.RemoveAll();
}
//-----------------------------------------------------------------------------
// Simpler method of doing the LoadModule/AddSystem thing.
//-----------------------------------------------------------------------------
bool CAppSystemGroup::AddSystems( AppSystemInfo_t *pSystemList )
{
while ( pSystemList->m_pModuleName[0] )
{
AppModule_t module = LoadModule( pSystemList->m_pModuleName );
IAppSystem *pSystem = AddSystem( module, pSystemList->m_pInterfaceName );
if ( !pSystem )
{
Warning( "Unable to load interface %s from %s\n", pSystemList->m_pInterfaceName, pSystemList->m_pModuleName );
return false;
}
++pSystemList;
}
return true;
}
//-----------------------------------------------------------------------------
// Methods to find various global singleton systems
//-----------------------------------------------------------------------------
void *CAppSystemGroup::FindSystem( const char *pSystemName )
{
unsigned short i = m_SystemDict.Find( pSystemName );
if (i != m_SystemDict.InvalidIndex())
return m_Systems[m_SystemDict[i]];
// If it's not an interface we know about, it could be an older
// version of an interface, or maybe something implemented by
// one of the instantiated interfaces...
// QUESTION: What order should we iterate this in?
// It controls who wins if multiple ones implement the same interface
for ( i = 0; i < m_Systems.Count(); ++i )
{
void *pInterface = m_Systems[i]->QueryInterface( pSystemName );
if (pInterface)
return pInterface;
}
if ( m_pParentAppSystem )
{
void* pInterface = m_pParentAppSystem->FindSystem( pSystemName );
if ( pInterface )
return pInterface;
}
// No dice..
return NULL;
}
//-----------------------------------------------------------------------------
// Gets at the parent appsystem group
//-----------------------------------------------------------------------------
CAppSystemGroup *CAppSystemGroup::GetParent()
{
return m_pParentAppSystem;
}
//-----------------------------------------------------------------------------
// Method to connect/disconnect all systems
//-----------------------------------------------------------------------------
bool CAppSystemGroup::ConnectSystems()
{
for (int i = 0; i < m_Systems.Count(); ++i )
{
IAppSystem *sys = m_Systems[i];
if (!sys->Connect( GetFactory() ))
{
ReportStartupFailure( CONNECTION, i );
return false;
}
}
return true;
}
void CAppSystemGroup::DisconnectSystems()
{
// Disconnect in reverse order of connection
for (int i = m_Systems.Count(); --i >= 0; )
{
m_Systems[i]->Disconnect();
}
}
//-----------------------------------------------------------------------------
// Method to initialize/shutdown all systems
//-----------------------------------------------------------------------------
InitReturnVal_t CAppSystemGroup::InitSystems()
{
for (int i = 0; i < m_Systems.Count(); ++i )
{
InitReturnVal_t nRetVal = m_Systems[i]->Init();
if ( nRetVal != INIT_OK )
{
ReportStartupFailure( INITIALIZATION, i );
return nRetVal;
}
}
return INIT_OK;
}
void CAppSystemGroup::ShutdownSystems()
{
// Shutdown in reverse order of initialization
for (int i = m_Systems.Count(); --i >= 0; )
{
m_Systems[i]->Shutdown();
}
}
//-----------------------------------------------------------------------------
// Returns the stage at which the app system group ran into an error
//-----------------------------------------------------------------------------
CAppSystemGroup::AppSystemGroupStage_t CAppSystemGroup::GetErrorStage() const
{
return m_nErrorStage;
}
//-----------------------------------------------------------------------------
// Gets at a factory that works just like FindSystem
//-----------------------------------------------------------------------------
// This function is used to make this system appear to the outside world to
// function exactly like the currently existing factory system
CAppSystemGroup *s_pCurrentAppSystem;
void *AppSystemCreateInterfaceFn(const char *pName, int *pReturnCode)
{
void *pInterface = s_pCurrentAppSystem->FindSystem( pName );
if ( pReturnCode )
{
*pReturnCode = pInterface ? IFACE_OK : IFACE_FAILED;
}
return pInterface;
}
//-----------------------------------------------------------------------------
// Gets at a class factory for the topmost appsystem group in an appsystem stack
//-----------------------------------------------------------------------------
CreateInterfaceFn CAppSystemGroup::GetFactory()
{
return AppSystemCreateInterfaceFn;
}
//-----------------------------------------------------------------------------
// Main application loop
//-----------------------------------------------------------------------------
int CAppSystemGroup::Run()
{
// The factory now uses this app system group
s_pCurrentAppSystem = this;
// Load, connect, init
int nRetVal = OnStartup();
if ( m_nErrorStage != NONE )
return nRetVal;
// Main loop implemented by the application
// FIXME: HACK workaround to avoid vgui porting
nRetVal = Main();
// Shutdown, disconnect, unload
OnShutdown();
// The factory now uses the parent's app system group
s_pCurrentAppSystem = GetParent();
return nRetVal;
}
//-----------------------------------------------------------------------------
// Virtual methods for override
//-----------------------------------------------------------------------------
int CAppSystemGroup::Startup()
{
return OnStartup();
}
void CAppSystemGroup::Shutdown()
{
return OnShutdown();
}
//-----------------------------------------------------------------------------
// Use this version in cases where you can't control the main loop and
// expect to be ticked
//-----------------------------------------------------------------------------
int CAppSystemGroup::OnStartup()
{
// The factory now uses this app system group
s_pCurrentAppSystem = this;
m_nErrorStage = NONE;
// Call an installed application creation function
if ( !Create() )
{
m_nErrorStage = CREATION;
return -1;
}
// Let all systems know about each other
if ( !ConnectSystems() )
{
m_nErrorStage = CONNECTION;
return -1;
}
// Allow the application to do some work before init
if ( !PreInit() )
{
m_nErrorStage = PREINITIALIZATION;
return -1;
}
// Call Init on all App Systems
int nRetVal = InitSystems();
if ( nRetVal != INIT_OK )
{
m_nErrorStage = INITIALIZATION;
return -1;
}
return nRetVal;
}
void CAppSystemGroup::OnShutdown()
{
// The factory now uses this app system group
s_pCurrentAppSystem = this;
switch( m_nErrorStage )
{
case NONE:
break;
case PREINITIALIZATION:
case INITIALIZATION:
goto disconnect;
case CREATION:
case CONNECTION:
goto destroy;
}
// Cal Shutdown on all App Systems
ShutdownSystems();
// Allow the application to do some work after shutdown
PostShutdown();
disconnect:
// Systems should disconnect from each other
DisconnectSystems();
destroy:
// Unload all DLLs loaded in the AppCreate block
RemoveAllSystems();
// Have to do this because the logging listeners & response policies may live in modules which are being unloaded
// @TODO: this seems like a bad legacy practice... app systems should unload their spew handlers gracefully.
// LoggingSystem_ResetCurrentLoggingState();
// Assert( g_pDefaultLoggingListener != NULL );
// LoggingSystem_RegisterLoggingListener( g_pDefaultLoggingListener );
UnloadAllModules();
// Call an installed application destroy function
Destroy();
}
//-----------------------------------------------------------------------------
//
// This class represents a group of app systems that are loaded through steam
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CSteamAppSystemGroup::CSteamAppSystemGroup( IFileSystem *pFileSystem, CAppSystemGroup *pAppSystemParent )
{
m_pFileSystem = pFileSystem;
m_pGameInfoPath[0] = 0;
}
//-----------------------------------------------------------------------------
// Used by CSteamApplication to set up necessary pointers if we can't do it in the constructor
//-----------------------------------------------------------------------------
void CSteamAppSystemGroup::Setup( IFileSystem *pFileSystem, CAppSystemGroup *pParentAppSystem )
{
m_pFileSystem = pFileSystem;
m_pParentAppSystem = pParentAppSystem;
}
//-----------------------------------------------------------------------------
// Loads the module from Steam
//-----------------------------------------------------------------------------
CSysModule *CSteamAppSystemGroup::LoadModuleDLL( const char *pDLLName )
{
return m_pFileSystem->LoadModule( pDLLName );
}
//-----------------------------------------------------------------------------
// Returns the game info path
//-----------------------------------------------------------------------------
const char *CSteamAppSystemGroup::GetGameInfoPath() const
{
return m_pGameInfoPath;
}
//-----------------------------------------------------------------------------
// Sets up the search paths
//-----------------------------------------------------------------------------
bool CSteamAppSystemGroup::SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool )
{
CFSSteamSetupInfo steamInfo;
steamInfo.m_pDirectoryName = pStartingDir;
steamInfo.m_bOnlyUseDirectoryName = bOnlyUseStartingDir;
steamInfo.m_bToolsMode = bIsTool;
steamInfo.m_bSetSteamDLLPath = true;
steamInfo.m_bSteam = m_pFileSystem->IsSteam();
if ( FileSystem_SetupSteamEnvironment( steamInfo ) != FS_OK )
return false;
CFSMountContentInfo fsInfo;
fsInfo.m_pFileSystem = m_pFileSystem;
fsInfo.m_bToolsMode = bIsTool;
fsInfo.m_pDirectoryName = steamInfo.m_GameInfoPath;
if ( FileSystem_MountContent( fsInfo ) != FS_OK )
return false;
// Finally, load the search paths for the "GAME" path.
CFSSearchPathsInit searchPathsInit;
searchPathsInit.m_pDirectoryName = steamInfo.m_GameInfoPath;
searchPathsInit.m_pFileSystem = fsInfo.m_pFileSystem;
if ( FileSystem_LoadSearchPaths( searchPathsInit ) != FS_OK )
return false;
FileSystem_AddSearchPath_Platform( fsInfo.m_pFileSystem, steamInfo.m_GameInfoPath );
Q_strncpy( m_pGameInfoPath, steamInfo.m_GameInfoPath, sizeof(m_pGameInfoPath) );
return true;
}

View File

@ -0,0 +1,308 @@
//========= 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.
//
//=============================================================================
#ifdef _WIN32
#if defined( _WIN32 ) && !defined( _X360 )
#include <windows.h>
#endif
#include "appframework/vguimatsysapp.h"
#include "filesystem.h"
#include "materialsystem/imaterialsystem.h"
#include "vgui/ivgui.h"
#include "vgui/ISurface.h"
#include "vgui_controls/controls.h"
#include "vgui/ischeme.h"
#include "vgui/ilocalize.h"
#include "tier0/dbg.h"
#include "tier0/icommandline.h"
#include "materialsystem/materialsystem_config.h"
#include "filesystem_init.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "inputsystem/iinputsystem.h"
#include "tier3/tier3.h"
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CVguiMatSysApp::CVguiMatSysApp()
{
}
//-----------------------------------------------------------------------------
// Create all singleton systems
//-----------------------------------------------------------------------------
bool CVguiMatSysApp::Create()
{
AppSystemInfo_t appSystems[] =
{
{ "inputsystem.dll", INPUTSYSTEM_INTERFACE_VERSION },
{ "materialsystem.dll", MATERIAL_SYSTEM_INTERFACE_VERSION },
// NOTE: This has to occur before vgui2.dll so it replaces vgui2's surface implementation
{ "vguimatsurface.dll", VGUI_SURFACE_INTERFACE_VERSION },
{ "vgui2.dll", VGUI_IVGUI_INTERFACE_VERSION },
// Required to terminate the list
{ "", "" }
};
if ( !AddSystems( appSystems ) )
return false;
IMaterialSystem *pMaterialSystem = (IMaterialSystem*)FindSystem( MATERIAL_SYSTEM_INTERFACE_VERSION );
if ( !pMaterialSystem )
{
Warning( "CVguiMatSysApp::Create: Unable to connect to necessary interface!\n" );
return false;
}
pMaterialSystem->SetShaderAPI( "shaderapidx9.dll" );
return true;
}
void CVguiMatSysApp::Destroy()
{
}
//-----------------------------------------------------------------------------
// Window management
//-----------------------------------------------------------------------------
void*CVguiMatSysApp::CreateAppWindow( char const *pTitle, bool bWindowed, int w, int h )
{
WNDCLASSEX wc;
memset( &wc, 0, sizeof( wc ) );
wc.cbSize = sizeof( wc );
wc.style = CS_OWNDC | CS_DBLCLKS;
wc.lpfnWndProc = DefWindowProc;
wc.hInstance = (HINSTANCE)GetAppInstance();
wc.lpszClassName = "Valve001";
wc.hIcon = NULL; //LoadIcon( s_HInstance, MAKEINTRESOURCE( IDI_LAUNCHER ) );
wc.hIconSm = wc.hIcon;
RegisterClassEx( &wc );
// Note, it's hidden
DWORD style = WS_POPUP | WS_CLIPSIBLINGS;
if ( bWindowed )
{
// Give it a frame
style |= WS_OVERLAPPEDWINDOW;
style &= ~WS_THICKFRAME;
}
// Never a max box
style &= ~WS_MAXIMIZEBOX;
RECT windowRect;
windowRect.top = 0;
windowRect.left = 0;
windowRect.right = w;
windowRect.bottom = h;
// Compute rect needed for that size client area based on window style
AdjustWindowRectEx(&windowRect, style, FALSE, 0);
// Create the window
void *hWnd = CreateWindow( wc.lpszClassName, pTitle, style, 0, 0,
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
NULL, NULL, (HINSTANCE)GetAppInstance(), NULL );
if (!hWnd)
return NULL;
int CenterX, CenterY;
CenterX = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
CenterY = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
CenterX = (CenterX < 0) ? 0: CenterX;
CenterY = (CenterY < 0) ? 0: CenterY;
// In VCR modes, keep it in the upper left so mouse coordinates are always relative to the window.
SetWindowPos( (HWND)hWnd, NULL, CenterX, CenterY, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME);
return hWnd;
}
//-----------------------------------------------------------------------------
// Pump messages
//-----------------------------------------------------------------------------
void CVguiMatSysApp::AppPumpMessages()
{
g_pInputSystem->PollInputState();
}
//-----------------------------------------------------------------------------
// Sets up the game path
//-----------------------------------------------------------------------------
bool CVguiMatSysApp::SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool )
{
if ( !BaseClass::SetupSearchPaths( pStartingDir, bOnlyUseStartingDir, bIsTool ) )
return false;
g_pFullFileSystem->AddSearchPath( GetGameInfoPath(), "SKIN", PATH_ADD_TO_HEAD );
return true;
}
//-----------------------------------------------------------------------------
// Init, shutdown
//-----------------------------------------------------------------------------
bool CVguiMatSysApp::PreInit( )
{
if ( !BaseClass::PreInit() )
return false;
if ( !g_pFullFileSystem || !g_pMaterialSystem || !g_pInputSystem || !g_pMatSystemSurface )
{
Warning( "CVguiMatSysApp::PreInit: Unable to connect to necessary interface!\n" );
return false;
}
// Add paths...
if ( !SetupSearchPaths( NULL, false, true ) )
return false;
const char *pArg;
int iWidth = 1024;
int iHeight = 768;
bool bWindowed = (CommandLine()->CheckParm( "-fullscreen" ) == NULL);
if (CommandLine()->CheckParm( "-width", &pArg ))
{
iWidth = atoi( pArg );
}
if (CommandLine()->CheckParm( "-height", &pArg ))
{
iHeight = atoi( pArg );
}
m_nWidth = iWidth;
m_nHeight = iHeight;
m_HWnd = CreateAppWindow( GetAppName(), bWindowed, iWidth, iHeight );
if ( !m_HWnd )
return false;
g_pInputSystem->AttachToWindow( m_HWnd );
g_pMatSystemSurface->AttachToWindow( m_HWnd );
// NOTE: If we specifically wanted to use a particular shader DLL, we set it here...
//m_pMaterialSystem->SetShaderAPI( "shaderapidx8" );
// Get the adapter from the command line....
const char *pAdapterString;
int adapter = 0;
if (CommandLine()->CheckParm( "-adapter", &pAdapterString ))
{
adapter = atoi( pAdapterString );
}
int adapterFlags = 0;
if ( CommandLine()->CheckParm( "-ref" ) )
{
adapterFlags |= MATERIAL_INIT_REFERENCE_RASTERIZER;
}
if ( AppUsesReadPixels() )
{
adapterFlags |= MATERIAL_INIT_ALLOCATE_FULLSCREEN_TEXTURE;
}
g_pMaterialSystem->SetAdapter( adapter, adapterFlags );
return true;
}
void CVguiMatSysApp::PostShutdown()
{
if ( g_pMatSystemSurface && g_pInputSystem )
{
g_pMatSystemSurface->AttachToWindow( NULL );
g_pInputSystem->DetachFromWindow( );
}
BaseClass::PostShutdown();
}
//-----------------------------------------------------------------------------
// Gets the window size
//-----------------------------------------------------------------------------
int CVguiMatSysApp::GetWindowWidth() const
{
return m_nWidth;
}
int CVguiMatSysApp::GetWindowHeight() const
{
return m_nHeight;
}
//-----------------------------------------------------------------------------
// Returns the window
//-----------------------------------------------------------------------------
void* CVguiMatSysApp::GetAppWindow()
{
return m_HWnd;
}
//-----------------------------------------------------------------------------
// Sets the video mode
//-----------------------------------------------------------------------------
bool CVguiMatSysApp::SetVideoMode( )
{
MaterialSystem_Config_t config;
if ( CommandLine()->CheckParm( "-fullscreen" ) )
{
config.SetFlag( MATSYS_VIDCFG_FLAGS_WINDOWED, false );
}
else
{
config.SetFlag( MATSYS_VIDCFG_FLAGS_WINDOWED, true );
}
if ( CommandLine()->CheckParm( "-resizing" ) )
{
config.SetFlag( MATSYS_VIDCFG_FLAGS_RESIZING, true );
}
if ( CommandLine()->CheckParm( "-mat_vsync" ) )
{
config.SetFlag( MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC, false );
}
config.m_nAASamples = CommandLine()->ParmValue( "-mat_antialias", 1 );
config.m_nAAQuality = CommandLine()->ParmValue( "-mat_aaquality", 0 );
config.m_VideoMode.m_Width = config.m_VideoMode.m_Height = 0;
config.m_VideoMode.m_Format = IMAGE_FORMAT_BGRX8888;
config.m_VideoMode.m_RefreshRate = 0;
config.SetFlag( MATSYS_VIDCFG_FLAGS_STENCIL, true );
bool modeSet = g_pMaterialSystem->SetMode( m_HWnd, config );
if (!modeSet)
{
Error( "Unable to set mode\n" );
return false;
}
g_pMaterialSystem->OverrideConfig( config, false );
return true;
}
#endif // _WIN32

248
appframework/WinApp.cpp Normal file
View File

@ -0,0 +1,248 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: An application framework
//
//=============================================================================//
#ifdef POSIX
#error
#else
#if defined( _WIN32 ) && !defined( _X360 )
#include <windows.h>
#endif
#include "appframework/appframework.h"
#include "tier0/dbg.h"
#include "tier0/icommandline.h"
#include "interface.h"
#include "filesystem.h"
#include "appframework/iappsystemgroup.h"
#include "filesystem_init.h"
#include "vstdlib/cvar.h"
#include "xbox/xbox_console.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Globals...
//-----------------------------------------------------------------------------
HINSTANCE s_HInstance;
//static CSimpleWindowsLoggingListener s_SimpleWindowsLoggingListener;
//static CSimpleLoggingListener s_SimpleLoggingListener;
//ILoggingListener *g_pDefaultLoggingListener = &s_SimpleLoggingListener;
//-----------------------------------------------------------------------------
// HACK: Since I don't want to refit vgui yet...
//-----------------------------------------------------------------------------
void *GetAppInstance()
{
return s_HInstance;
}
//-----------------------------------------------------------------------------
// Sets the application instance, should only be used if you're not calling AppMain.
//-----------------------------------------------------------------------------
void SetAppInstance( void* hInstance )
{
s_HInstance = (HINSTANCE)hInstance;
}
//-----------------------------------------------------------------------------
// Specific 360 environment setup.
//-----------------------------------------------------------------------------
#if defined( _X360 )
bool SetupEnvironment360()
{
CommandLine()->CreateCmdLine( GetCommandLine() );
if ( !CommandLine()->FindParm( "-game" ) && !CommandLine()->FindParm( "-vproject" ) )
{
// add the default game name due to lack of vproject environment
CommandLine()->AppendParm( "-game", "hl2" );
}
// success
return true;
}
#endif
//-----------------------------------------------------------------------------
// Version of AppMain used by windows applications
//-----------------------------------------------------------------------------
int AppMain( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup )
{
Assert( pAppSystemGroup );
// g_pDefaultLoggingListener = &s_SimpleWindowsLoggingListener;
s_HInstance = (HINSTANCE)hInstance;
#if !defined( _X360 )
CommandLine()->CreateCmdLine( ::GetCommandLine() );
#else
SetupEnvironment360();
#endif
return pAppSystemGroup->Run();
}
//-----------------------------------------------------------------------------
// Version of AppMain used by console applications
//-----------------------------------------------------------------------------
int AppMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
{
Assert( pAppSystemGroup );
// g_pDefaultLoggingListener = &s_SimpleLoggingListener;
s_HInstance = NULL;
#if !defined( _X360 )
CommandLine()->CreateCmdLine( argc, argv );
#else
SetupEnvironment360();
#endif
return pAppSystemGroup->Run();
}
//-----------------------------------------------------------------------------
// Used to startup/shutdown the application
//-----------------------------------------------------------------------------
int AppStartup( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup )
{
Assert( pAppSystemGroup );
// g_pDefaultLoggingListener = &s_SimpleWindowsLoggingListener;
s_HInstance = (HINSTANCE)hInstance;
#if !defined( _X360 )
CommandLine()->CreateCmdLine( ::GetCommandLine() );
#else
SetupEnvironment360();
#endif
return pAppSystemGroup->Startup();
}
int AppStartup( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
{
Assert( pAppSystemGroup );
// g_pDefaultLoggingListener = &s_SimpleLoggingListener;
s_HInstance = NULL;
#if !defined( _X360 )
CommandLine()->CreateCmdLine( argc, argv );
#else
SetupEnvironment360();
#endif
return pAppSystemGroup->Startup();
}
void AppShutdown( CAppSystemGroup *pAppSystemGroup )
{
Assert( pAppSystemGroup );
pAppSystemGroup->Shutdown();
}
//-----------------------------------------------------------------------------
//
// Default implementation of an application meant to be run using Steam
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CSteamApplication::CSteamApplication( CSteamAppSystemGroup *pAppSystemGroup )
{
m_pChildAppSystemGroup = pAppSystemGroup;
m_pFileSystem = NULL;
m_bSteam = false;
}
//-----------------------------------------------------------------------------
// Create necessary interfaces
//-----------------------------------------------------------------------------
bool CSteamApplication::Create()
{
FileSystem_SetErrorMode( FS_ERRORMODE_AUTO );
char pFileSystemDLL[MAX_PATH];
if ( FileSystem_GetFileSystemDLLName( pFileSystemDLL, MAX_PATH, m_bSteam ) != FS_OK )
return false;
// Add in the cvar factory
AppModule_t cvarModule = LoadModule( VStdLib_GetICVarFactory() );
AddSystem( cvarModule, CVAR_INTERFACE_VERSION );
AppModule_t fileSystemModule = LoadModule( pFileSystemDLL );
m_pFileSystem = (IFileSystem*)AddSystem( fileSystemModule, FILESYSTEM_INTERFACE_VERSION );
if ( !m_pFileSystem )
{
Error( "Unable to load %s", pFileSystemDLL );
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// The file system pointer is invalid at this point
//-----------------------------------------------------------------------------
void CSteamApplication::Destroy()
{
m_pFileSystem = NULL;
}
//-----------------------------------------------------------------------------
// Pre-init, shutdown
//-----------------------------------------------------------------------------
bool CSteamApplication::PreInit()
{
return true;
}
void CSteamApplication::PostShutdown()
{
}
//-----------------------------------------------------------------------------
// Run steam main loop
//-----------------------------------------------------------------------------
int CSteamApplication::Main()
{
// Now that Steam is loaded, we can load up main libraries through steam
if ( FileSystem_SetBasePaths( m_pFileSystem ) != FS_OK )
return 0;
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
return m_pChildAppSystemGroup->Run();
}
//-----------------------------------------------------------------------------
// Use this version in cases where you can't control the main loop and
// expect to be ticked
//-----------------------------------------------------------------------------
int CSteamApplication::Startup()
{
int nRetVal = BaseClass::Startup();
if ( GetErrorStage() != NONE )
return nRetVal;
if ( FileSystem_SetBasePaths( m_pFileSystem ) != FS_OK )
return 0;
// Now that Steam is loaded, we can load up main libraries through steam
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
return m_pChildAppSystemGroup->Startup();
}
void CSteamApplication::Shutdown()
{
m_pChildAppSystemGroup->Shutdown();
BaseClass::Shutdown();
}
#endif

View File

@ -0,0 +1,53 @@
//-----------------------------------------------------------------------------
// APPFRAMEWORK.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$macro SRCDIR ".."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$General
{
$AdditionalProjectDependencies "$BASE;togl" [!$IS_LIB_PROJECT && $GL]
}
$Linker [$OSXALL]
{
$SystemFrameworks "Carbon;OpenGL;Quartz;Cocoa;IOKit"
}
}
$Project "appframework"
{
$Folder "Source Files"
{
$File "AppSystemGroup.cpp"
$File "$SRCDIR\public\filesystem_init.cpp"
$File "vguimatsysapp.cpp" [$WIN32]
$File "winapp.cpp" [$WIN32]
$File "posixapp.cpp" [$POSIX]
$File "sdlmgr.cpp" [$SDL]
$File "glmrendererinfo_osx.mm" [$OSXALL]
}
$Folder "Interface"
{
$File "$SRCDIR\public\appframework\AppFramework.h"
$File "$SRCDIR\public\appframework\IAppSystem.h"
$File "$SRCDIR\public\appframework\IAppSystemGroup.h"
$File "$SRCDIR\public\appframework\tier2app.h"
$File "$SRCDIR\public\appframework\tier3app.h"
$File "$SRCDIR\public\appframework\VguiMatSysApp.h"
$File "$SRCDIR\public\appframework\ilaunchermgr.h"
}
$Folder "Link Libraries"
{
$ImpLib togl [!$IS_LIB_PROJECT && $GL]
$ImpLib SDL2 [!$IS_LIB_PROJECT && $SDL]
}
}

View File

@ -0,0 +1,630 @@
//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============//
//
// Purpose: Defines a group of app systems that all have the same lifetime
// that need to be connected/initialized, etc. in a well-defined order
//
// $Revision: $
// $NoKeywords: $
//=============================================================================//
//===============================================================================
GLMRendererInfo::GLMRendererInfo( void )
{
m_display = NULL;
Q_memset( &m_info, 0, sizeof( m_info ) );
}
GLMRendererInfo::~GLMRendererInfo( void )
{
SDLAPP_FUNC;
if (m_display)
{
delete m_display;
m_display = NULL;
}
}
// !!! FIXME: sync this function with the Mac version in case anything important has changed.
void GLMRendererInfo::Init( GLMRendererInfoFields *info )
{
SDLAPP_FUNC;
m_info = *info;
m_display = NULL;
m_info.m_fullscreen = 0;
m_info.m_accelerated = 1;
m_info.m_windowed = 1;
m_info.m_ati = true;
m_info.m_atiNewer = true;
m_info.m_hasGammaWrites = true;
// If you haven't created a GL context by now (and initialized gGL), you're about to crash.
m_info.m_hasMixedAttachmentSizes = gGL->m_bHave_GL_ARB_framebuffer_object;
m_info.m_hasBGRA = gGL->m_bHave_GL_EXT_vertex_array_bgra;
// !!! FIXME: what do these do on the Mac?
m_info.m_hasNewFullscreenMode = false;
m_info.m_hasNativeClipVertexMode = true;
// if user disabled them
if (CommandLine()->FindParm("-glmdisableclipplanes"))
{
m_info.m_hasNativeClipVertexMode = false;
}
// or maybe enabled them..
if (CommandLine()->FindParm("-glmenableclipplanes"))
{
m_info.m_hasNativeClipVertexMode = true;
}
m_info.m_hasOcclusionQuery = gGL->m_bHave_GL_ARB_occlusion_query;
m_info.m_hasFramebufferBlit = gGL->m_bHave_GL_EXT_framebuffer_blit || gGL->m_bHave_GL_ARB_framebuffer_object;
GLint nMaxAniso = 0;
gGL->glGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &nMaxAniso );
m_info.m_maxAniso = clamp<int>( nMaxAniso, 0, 16 );
// We don't currently used bindable uniforms, but I've been experimenting with them so I might as well check this in just in case they turn out to be useful.
m_info.m_hasBindableUniforms = gGL->m_bHave_GL_EXT_bindable_uniform;
m_info.m_hasBindableUniforms = false; // !!! FIXME hardwiring this path to false until we see how to accelerate it properly
m_info.m_maxVertexBindableUniforms = 0;
m_info.m_maxFragmentBindableUniforms = 0;
m_info.m_maxBindableUniformSize = 0;
if (m_info.m_hasBindableUniforms)
{
gGL->glGetIntegerv(GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT, &m_info.m_maxVertexBindableUniforms);
gGL->glGetIntegerv(GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT, &m_info.m_maxFragmentBindableUniforms);
gGL->glGetIntegerv(GL_MAX_BINDABLE_UNIFORM_SIZE_EXT, &m_info.m_maxBindableUniformSize);
if ( ( m_info.m_maxVertexBindableUniforms < 1 ) || ( m_info.m_maxFragmentBindableUniforms < 1 ) || ( m_info.m_maxBindableUniformSize < ( sizeof( float ) * 4 * 256 ) ) )
{
m_info.m_hasBindableUniforms = false;
}
}
m_info.m_hasUniformBuffers = gGL->m_bHave_GL_ARB_uniform_buffer;
m_info.m_hasPerfPackage1 = true; // this flag is Mac-specific. We do slower things if you don't have Mac OS X 10.x.y or later. Linux always does the fast path!
//-------------------------------------------------------------------
// runtime options that aren't negotiable once set
m_info.m_hasDualShaders = CommandLine()->FindParm("-glmdualshaders") != 0;
//-------------------------------------------------------------------
// "can'ts "
#if defined( OSX )
m_info.m_cantBlitReliably = m_info.m_intel; //FIXME X3100&10.6.3 has problems blitting.. adjust this if bug fixed in 10.6.4
#else
// m_cantBlitReliably path doesn't work right now, and the Intel path is different for us on Linux/Win7 anyway
m_info.m_cantBlitReliably = false;
#endif
if (CommandLine()->FindParm("-glmenabletrustblit"))
{
m_info.m_cantBlitReliably = false; // we trust the blit, so set the cant-blit cap to false
}
if (CommandLine()->FindParm("-glmdisabletrustblit"))
{
m_info.m_cantBlitReliably = true; // we do not trust the blit, so set the cant-blit cap to true
}
// MSAA resolve issues
m_info.m_cantResolveFlipped = false;
#if defined( OSX )
m_info.m_cantResolveScaled = true; // generally true until new extension ships
#else
// DON'T just slam this to false and run without first testing with -gl_debug enabled on NVidia/AMD/etc.
// This path needs the m_bHave_GL_EXT_framebuffer_multisample_blit_scaled extension.
m_info.m_cantResolveScaled = true;
if ( gGL->m_bHave_GL_EXT_framebuffer_multisample_blit_scaled )
{
m_info.m_cantResolveScaled = false;
}
#endif
// gamma decode impacting shader codegen
m_info.m_costlyGammaFlips = false;
}
void GLMRendererInfo::PopulateDisplays()
{
SDLAPP_FUNC;
Assert( !m_display );
m_display = new GLMDisplayInfo;
// Populate display mode table.
m_display->PopulateModes();
}
void GLMRendererInfo::Dump( int which )
{
SDLAPP_FUNC;
GLMPRINTF(("\n #%d: GLMRendererInfo @ %p, renderer-id=(%08x) display-mask=%08x vram=%dMB",
which, this,
m_info.m_rendererID,
m_info.m_displayMask,
m_info.m_vidMemory >> 20
));
GLMPRINTF(("\n VendorID=%04x DeviceID=%04x Model=%s",
m_info.m_pciVendorID,
m_info.m_pciDeviceID,
m_info.m_pciModelString
));
m_display->Dump( which );
}
GLMDisplayDB::GLMDisplayDB ()
{
SDLAPP_FUNC;
m_renderer.m_display = NULL;
}
GLMDisplayDB::~GLMDisplayDB ( void )
{
SDLAPP_FUNC;
if ( m_renderer.m_display )
{
delete m_renderer.m_display;
m_renderer.m_display = NULL;
}
}
#ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
#endif
#ifndef GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX
#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
#endif
#ifndef GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX
#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
#endif
#ifndef GL_VBO_FREE_MEMORY_ATI
#define GL_VBO_FREE_MEMORY_ATI 0x87FB
#endif
#ifndef GL_TEXTURE_FREE_MEMORY_ATI
#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
#endif
#ifndef GL_RENDERBUFFER_FREE_MEMORY_ATI
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
#endif
void GLMDisplayDB::PopulateRenderers( void )
{
SDLAPP_FUNC;
Assert( !m_renderer.m_display );
GLMRendererInfoFields fields;
memset( &fields, 0, sizeof(fields) );
// Assume 512MB of available video memory
fields.m_vidMemory = 512 * 1024 * 1024;
DebugPrintf( "GL_NVX_gpu_memory_info: %s\n", gGL->m_bHave_GL_NVX_gpu_memory_info ? "AVAILABLE" : "UNAVAILABLE" );
DebugPrintf( "GL_ATI_meminfo: %s\n", gGL->m_bHave_GL_ATI_meminfo ? "AVAILABLE" : "UNAVAILABLE" );
if ( gGL->m_bHave_GL_NVX_gpu_memory_info )
{
gGL->glGetError();
GLint nTotalDedicated = 0, nTotalAvail = 0, nCurrentAvail = 0;
gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &nTotalDedicated );
gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &nTotalAvail );
gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &nCurrentAvail );
if ( gGL->glGetError() )
{
DebugPrintf( "GL_NVX_gpu_memory_info: Failed retrieving available GPU memory\n" );
}
else
{
DebugPrintf( "GL_NVX_gpu_memory_info: Total Dedicated: %u, Total Avail: %u, Current Avail: %u\n", nTotalDedicated, nTotalAvail, nCurrentAvail );
// Try to do something reasonable. Should we report dedicated or total available to the engine here?
// For now, just take the MAX of both.
uint64 nActualAvail = static_cast<uint64>( MAX( nTotalAvail, nTotalDedicated ) ) * 1024;
fields.m_vidMemory = static_cast< GLint >( MIN( nActualAvail, 0x7FFFFFFF ) );
}
}
else if ( gGL->m_bHave_GL_ATI_meminfo )
{
// As of 10/8/12 this extension is only available under Linux and Windows FireGL parts.
gGL->glGetError();
GLint nAvail[4] = { 0, 0, 0, 0 };
gGL->glGetIntegerv( GL_TEXTURE_FREE_MEMORY_ATI, nAvail );
if ( gGL->glGetError() )
{
DebugPrintf( "GL_ATI_meminfo: Failed retrieving available GPU memory\n" );
}
else
{
// param[0] - total memory free in the pool
// param[1] - largest available free block in the pool
// param[2] - total auxiliary memory free
// param[3] - largest auxiliary free block
DebugPrintf( "GL_ATI_meminfo: GL_TEXTURE_FREE_MEMORY_ATI: Total Free: %i, Largest Avail: %i, Total Aux: %i, Largest Aux Avail: %i\n",
nAvail[0], nAvail[1], nAvail[2], nAvail[3] );
uint64 nActualAvail = static_cast<uint64>( nAvail[0] ) * 1024;
fields.m_vidMemory = static_cast< GLint >( MIN( nActualAvail, 0x7FFFFFFF ) );
}
}
// Clamp the min amount of video memory to 256MB in case a query returned something bogus, or we interpreted it badly.
fields.m_vidMemory = MAX( fields.m_vidMemory, 128 * 1024 * 1024 );
fields.m_texMemory = fields.m_vidMemory;
fields.m_pciVendorID = GLM_OPENGL_VENDOR_ID;
fields.m_pciDeviceID = GLM_OPENGL_DEFAULT_DEVICE_ID;
if ( ( gGL->m_nDriverProvider == cGLDriverProviderIntel ) || ( gGL->m_nDriverProvider == cGLDriverProviderIntelOpenSource ) )
{
fields.m_pciDeviceID = GLM_OPENGL_LOW_PERF_DEVICE_ID;
}
/* fields.m_colorModes = (uint)-1;
fields.m_bufferModes = (uint)-1;
fields.m_depthModes = (uint)-1;
fields.m_stencilModes = (uint)-1;
fields.m_maxAuxBuffers = (uint)128;
fields.m_maxSampleBuffers = (uint)128;
fields.m_maxSamples = (uint)2048;
fields.m_sampleModes = (uint)128;
fields.m_sampleAlpha = (uint)32;
*/
GLint nMaxMultiSamples = 0;
gGL->glGetIntegerv( GL_MAX_SAMPLES_EXT, &nMaxMultiSamples );
fields.m_maxSamples = clamp<int>( nMaxMultiSamples, 0, 8 );
DebugPrintf( "GL_MAX_SAMPLES_EXT: %i\n", nMaxMultiSamples );
// We only have one GLMRendererInfo on Linux, unlike Mac OS X. Whatever libGL.so wants to do, we go with it.
m_renderer.Init( &fields );
// then go back and ask each renderer to populate its display info table.
m_renderer.PopulateDisplays();
}
void GLMDisplayDB::PopulateFakeAdapters( uint realRendererIndex ) // fake adapters = one real adapter times however many displays are on it
{
SDLAPP_FUNC;
Assert( realRendererIndex == 0 );
}
void GLMDisplayDB::Populate(void)
{
SDLAPP_FUNC;
this->PopulateRenderers();
this->PopulateFakeAdapters( 0 );
#if GLMDEBUG
this->Dump();
#endif
}
int GLMDisplayDB::GetFakeAdapterCount( void )
{
SDLAPP_FUNC;
return 1;
}
bool GLMDisplayDB::GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut )
{
SDLAPP_FUNC;
if (fakeAdapterIndex >= GetFakeAdapterCount() )
{
*rendererOut = 0;
*displayOut = 0;
return true; // fail
}
*rendererOut = 0;
*displayOut = 0;
bool rendResult = GetRendererInfo( *rendererOut, rendererInfoOut );
bool dispResult = GetDisplayInfo( *rendererOut, *displayOut, displayInfoOut );
return rendResult || dispResult;
}
int GLMDisplayDB::GetRendererCount( void )
{
SDLAPP_FUNC;
return 1;
}
bool GLMDisplayDB::GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut )
{
SDLAPP_FUNC;
memset( infoOut, 0, sizeof( GLMRendererInfoFields ) );
if (rendererIndex >= GetRendererCount())
return true; // fail
*infoOut = m_renderer.m_info;
return false;
}
int GLMDisplayDB::GetDisplayCount( int rendererIndex )
{
SDLAPP_FUNC;
if (rendererIndex >= GetRendererCount())
{
Assert( 0 );
return 0; // fail
}
return 1;
}
bool GLMDisplayDB::GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut )
{
SDLAPP_FUNC;
memset( infoOut, 0, sizeof( GLMDisplayInfoFields ) );
if (rendererIndex >= GetRendererCount())
return true; // fail
if (displayIndex >= GetDisplayCount(rendererIndex))
return true; // fail
*infoOut = m_renderer.m_display->m_info;
return false;
}
int GLMDisplayDB::GetModeCount( int rendererIndex, int displayIndex )
{
SDLAPP_FUNC;
if (rendererIndex >= GetRendererCount())
return 0; // fail
if (displayIndex >= GetDisplayCount(rendererIndex))
return 0; // fail
return m_renderer.m_display->m_modes->Count();
}
bool GLMDisplayDB::GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut )
{
SDLAPP_FUNC;
memset( infoOut, 0, sizeof( GLMDisplayModeInfoFields ) );
if ( rendererIndex >= GetRendererCount())
return true; // fail
if (displayIndex >= GetDisplayCount( rendererIndex ) )
return true; // fail
if ( modeIndex >= GetModeCount( rendererIndex, displayIndex ) )
return true; // fail
if ( modeIndex >= 0 )
{
GLMDisplayMode *displayModeInfo = m_renderer.m_display->m_modes->Element( modeIndex );
*infoOut = displayModeInfo->m_info;
}
else
{
const GLMDisplayInfoFields &info = m_renderer.m_display->m_info;
infoOut->m_modePixelWidth = info.m_displayPixelWidth;
infoOut->m_modePixelHeight = info.m_displayPixelHeight;
infoOut->m_modeRefreshHz = 0;
//return true; // fail
}
return false;
}
void GLMDisplayDB::Dump( void )
{
SDLAPP_FUNC;
GLMPRINTF(("\n GLMDisplayDB @ %p ",this ));
m_renderer.Dump( 0 );
}
//===============================================================================
GLMDisplayInfo::GLMDisplayInfo()
{
SDLAPP_FUNC;
m_modes = NULL;
int Width, Height;
GetLargestDisplaySize( Width, Height );
m_info.m_displayPixelWidth = ( uint )Width;
m_info.m_displayPixelHeight = ( uint )Height;
}
GLMDisplayInfo::~GLMDisplayInfo( void )
{
SDLAPP_FUNC;
}
extern "C" int DisplayModeSortFunction( GLMDisplayMode * const *A, GLMDisplayMode * const *B )
{
SDLAPP_FUNC;
int bigger = -1;
int smaller = 1; // adjust these for desired ordering
// check refreshrate - higher should win
if ( (*A)->m_info.m_modeRefreshHz > (*B)->m_info.m_modeRefreshHz )
{
return bigger;
}
else if ( (*A)->m_info.m_modeRefreshHz < (*B)->m_info.m_modeRefreshHz )
{
return smaller;
}
// check area - larger mode should win
int areaa = (*A)->m_info.m_modePixelWidth * (*A)->m_info.m_modePixelHeight;
int areab = (*B)->m_info.m_modePixelWidth * (*B)->m_info.m_modePixelHeight;
if ( areaa > areab )
{
return bigger;
}
else if ( areaa < areab )
{
return smaller;
}
return 0; // equal rank
}
void GLMDisplayInfo::PopulateModes( void )
{
SDLAPP_FUNC;
Assert( !m_modes );
m_modes = new CUtlVector< GLMDisplayMode* >;
int nummodes = SDL_GetNumVideoDisplays();
for ( int i = 0; i < nummodes; i++ )
{
SDL_Rect rect = { 0, 0, 0, 0 };
if ( !SDL_GetDisplayBounds( i, &rect ) && rect.w && rect.h )
{
m_modes->AddToTail( new GLMDisplayMode( rect.w, rect.h, 0 ) );
}
}
// Add a big pile of window resolutions.
static const struct
{
uint w;
uint h;
} s_Resolutions[] =
{
{ 640, 480 }, // 4x3
{ 800, 600 },
{ 1024, 768 },
{ 1152, 864 },
{ 1280, 960 },
{ 1600, 1200 },
{ 1920, 1440 },
{ 2048, 1536 },
{ 1280, 720 }, // 16x9
{ 1366, 768 },
{ 1600, 900 },
{ 1920, 1080 },
{ 720, 480 }, // 16x10
{ 1280, 800 },
{ 1680, 1050 },
{ 1920, 1200 },
{ 2560, 1600 },
};
for ( int i = 0; i < ARRAYSIZE( s_Resolutions ); i++ )
{
uint w = s_Resolutions[ i ].w;
uint h = s_Resolutions[ i ].h;
if ( ( w <= m_info.m_displayPixelWidth ) && ( h <= m_info.m_displayPixelHeight ) )
{
m_modes->AddToTail( new GLMDisplayMode( w, h, 0 ) );
if ( ( w * 2 <= m_info.m_displayPixelWidth ) && ( h * 2 < m_info.m_displayPixelHeight ) )
{
// Add double of everything also - Retina proofing hopefully.
m_modes->AddToTail( new GLMDisplayMode( w * 2, h * 2, 0 ) );
}
}
}
m_modes->Sort( DisplayModeSortFunction );
// remove dupes.
nummodes = m_modes->Count();
int i = 1; // not zero!
while (i < nummodes)
{
GLMDisplayModeInfoFields& info0 = m_modes->Element( i - 1 )->m_info;
GLMDisplayModeInfoFields& info1 = m_modes->Element( i )->m_info;
if ( ( info0.m_modePixelWidth == info1.m_modePixelWidth ) &&
( info0.m_modePixelHeight == info1.m_modePixelHeight ) &&
( info0.m_modeRefreshHz == info1.m_modeRefreshHz ) )
{
m_modes->Remove(i);
nummodes--;
}
else
{
i++;
}
}
}
void GLMDisplayInfo::Dump( int which )
{
SDLAPP_FUNC;
GLMPRINTF(("\n #%d: GLMDisplayInfo @ %08x, pixwidth=%d pixheight=%d",
which, (int)this, m_info.m_displayPixelWidth, m_info.m_displayPixelHeight ));
FOR_EACH_VEC( *m_modes, i )
{
( *m_modes )[i]->Dump(i);
}
}

File diff suppressed because it is too large Load Diff

182
appframework/posixapp.cpp Normal file
View File

@ -0,0 +1,182 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Pieces of the application framework, shared between POSIX systems (Mac OS X, Linux, etc)
//
// $Revision: $
// $NoKeywords: $
//=============================================================================//
#include "appframework/AppFramework.h"
#include "tier0/dbg.h"
#include "tier0/icommandline.h"
#include "interface.h"
#include "filesystem.h"
#include "appframework/IAppSystemGroup.h"
#include "filesystem_init.h"
#include "tier1/convar.h"
#include "vstdlib/cvar.h"
#include "togl/rendermechanism.h"
// NOTE: This has to be the last file included! (turned off below, since this is included like a header)
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Globals...
//-----------------------------------------------------------------------------
HINSTANCE s_HInstance;
//#if !defined(LINUX)
//static CSimpleLoggingListener s_SimpleLoggingListener;
//ILoggingListener *g_pDefaultLoggingListener = &s_SimpleLoggingListener;
//#endif
//-----------------------------------------------------------------------------
// HACK: Since I don't want to refit vgui yet...
//-----------------------------------------------------------------------------
void *GetAppInstance()
{
return s_HInstance;
}
//-----------------------------------------------------------------------------
// Sets the application instance, should only be used if you're not calling AppMain.
//-----------------------------------------------------------------------------
void SetAppInstance( void* hInstance )
{
s_HInstance = (HINSTANCE)hInstance;
}
//-----------------------------------------------------------------------------
// Version of AppMain used by windows applications
//-----------------------------------------------------------------------------
int AppMain( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup )
{
Assert( 0 );
return -1;
}
//#if !defined(LINUX)
//static CNonFatalLoggingResponsePolicy s_NonFatalLoggingResponsePolicy;
//#endif
//-----------------------------------------------------------------------------
// Version of AppMain used by console applications
//-----------------------------------------------------------------------------
int AppMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
{
Assert( pAppSystemGroup );
//#if !defined(LINUX)
// LoggingSystem_SetLoggingResponsePolicy( &s_NonFatalLoggingResponsePolicy );
//#endif
s_HInstance = NULL;
CommandLine()->CreateCmdLine( argc, argv );
return pAppSystemGroup->Run( );
}
//-----------------------------------------------------------------------------
//
// Default implementation of an application meant to be run using Steam
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CSteamApplication::CSteamApplication( CSteamAppSystemGroup *pAppSystemGroup )
{
m_pChildAppSystemGroup = pAppSystemGroup;
m_pFileSystem = NULL;
}
//-----------------------------------------------------------------------------
// Create necessary interfaces
//-----------------------------------------------------------------------------
bool CSteamApplication::Create( )
{
FileSystem_SetErrorMode( FS_ERRORMODE_NONE );
char pFileSystemDLL[MAX_PATH];
if ( FileSystem_GetFileSystemDLLName( pFileSystemDLL, MAX_PATH, m_bSteam ) != FS_OK )
return false;
// Add in the cvar factory
AppModule_t cvarModule = LoadModule( VStdLib_GetICVarFactory() );
AddSystem( cvarModule, CVAR_INTERFACE_VERSION );
AppModule_t fileSystemModule = LoadModule( pFileSystemDLL );
m_pFileSystem = (IFileSystem*)AddSystem( fileSystemModule, FILESYSTEM_INTERFACE_VERSION );
if ( !m_pFileSystem )
{
Error( "Unable to load %s", pFileSystemDLL );
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// The file system pointer is invalid at this point
//-----------------------------------------------------------------------------
void CSteamApplication::Destroy()
{
m_pFileSystem = NULL;
}
//-----------------------------------------------------------------------------
// Pre-init, shutdown
//-----------------------------------------------------------------------------
bool CSteamApplication::PreInit( )
{
return true;
}
void CSteamApplication::PostShutdown( )
{
}
//-----------------------------------------------------------------------------
// Run steam main loop
//-----------------------------------------------------------------------------
int CSteamApplication::Main( )
{
// Now that Steam is loaded, we can load up main libraries through steam
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
return m_pChildAppSystemGroup->Run( );
}
int CSteamApplication::Startup()
{
int nRetVal = BaseClass::Startup();
if ( GetErrorStage() != NONE )
return nRetVal;
if ( FileSystem_SetBasePaths( m_pFileSystem ) != FS_OK )
return 0;
// Now that Steam is loaded, we can load up main libraries through steam
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
return m_pChildAppSystemGroup->Startup();
}
void CSteamApplication::Shutdown()
{
m_pChildAppSystemGroup->Shutdown();
BaseClass::Shutdown();
}
// Turn off memdbg macros (turned on up top) since this is included like a header
#include "tier0/memdbgoff.h"

2078
appframework/sdlmgr.cpp Normal file

File diff suppressed because it is too large Load Diff

260
bitmap/ImageByteSwap.cpp Normal file
View File

@ -0,0 +1,260 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Image Byte Swapping. Isolate routines to own module to allow librarian
// to ignore xbox 360 dependenices in non-applicable win32 projects.
//
//=============================================================================//
#if defined( _WIN32 ) && !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION )
#include <windows.h>
#endif
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "bitmap/imageformat.h"
// Should be last include
#include "tier0/memdbgon.h"
#if defined( _WIN32 ) && !defined( _X360 ) && !defined( NO_X360_XDK ) && !defined( DX_TO_GL_ABSTRACTION )
// the x86 version of the 360 (used by win32 tools)
// It would have been nice to use the 360 D3DFORMAT bit encodings, but the codes
// are different for WIN32, and this routine is used by a WIN32 library to
// manipulate 360 data, so there can be no reliance on WIN32 D3DFORMAT bits
#pragma warning(push)
#pragma warning(disable : 4458) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc (disabled due to std headers having exception syntax)
#include "..\x360xdk\include\win32\vs2005\d3d9.h"
#include "..\x360xdk\include\win32\vs2005\XGraphics.h"
#pragma warning(pop)
#endif
namespace ImageLoader
{
//-----------------------------------------------------------------------------
// Known formats that can be converted. Used as a trap for 360 formats
// that may occur but have not been validated yet.
//-----------------------------------------------------------------------------
bool IsFormatValidForConversion( ImageFormat fmt )
{
switch ( fmt )
{
case IMAGE_FORMAT_RGBA8888:
case IMAGE_FORMAT_ABGR8888:
case IMAGE_FORMAT_RGB888:
case IMAGE_FORMAT_BGR888:
case IMAGE_FORMAT_ARGB8888:
case IMAGE_FORMAT_BGRA8888:
case IMAGE_FORMAT_BGRX8888:
case IMAGE_FORMAT_UVWQ8888:
case IMAGE_FORMAT_RGBA16161616F:
case IMAGE_FORMAT_RGBA16161616:
case IMAGE_FORMAT_UVLX8888:
case IMAGE_FORMAT_DXT1:
case IMAGE_FORMAT_DXT1_ONEBITALPHA:
case IMAGE_FORMAT_DXT3:
case IMAGE_FORMAT_DXT5:
case IMAGE_FORMAT_UV88:
return true;
// untested formats
default:
case IMAGE_FORMAT_RGB565:
case IMAGE_FORMAT_I8:
case IMAGE_FORMAT_IA88:
case IMAGE_FORMAT_A8:
case IMAGE_FORMAT_RGB888_BLUESCREEN:
case IMAGE_FORMAT_BGR888_BLUESCREEN:
case IMAGE_FORMAT_BGR565:
case IMAGE_FORMAT_BGRX5551:
case IMAGE_FORMAT_BGRA4444:
case IMAGE_FORMAT_BGRA5551:
case IMAGE_FORMAT_ATI1N:
case IMAGE_FORMAT_ATI2N:
break;
}
return false;
}
//-----------------------------------------------------------------------------
// Swaps the image element type within the format.
// This is to ensure that >8 bit channels are in the correct endian format
// as expected by the conversion process, which varies according to format,
// input, and output.
//-----------------------------------------------------------------------------
void PreConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width, int stride )
{
Assert( IsFormatValidForConversion( imageFormat ) );
#if !defined( DX_TO_GL_ABSTRACTION ) && !defined( NO_X360_XDK )
if ( IsPC() )
{
// running as a win32 tool, data is in expected order
// for conversion code
return;
}
// running on 360 and converting, input data must be x86 order
// swap to ensure conversion code gets valid data
XGENDIANTYPE xEndian;
switch ( imageFormat )
{
default:
return;
case IMAGE_FORMAT_RGBA16161616F:
case IMAGE_FORMAT_RGBA16161616:
xEndian = XGENDIAN_8IN16;
break;
}
int count;
if ( !stride )
{
stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
count = nImageSize / stride;
XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
}
else
{
int nRows = nImageSize/stride;
for ( int i=0; i<nRows; i++ )
{
XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
pImageData += stride;
}
}
#endif
}
//-----------------------------------------------------------------------------
// Swaps image bytes for use on a big endian platform. This is used after the conversion
// process to match the 360 d3dformats.
//-----------------------------------------------------------------------------
void PostConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width, int stride )
{
Assert( IsFormatValidForConversion( imageFormat ) );
#if !defined( DX_TO_GL_ABSTRACTION ) && !defined( NO_X360_XDK )
// It would have been nice to use the 360 D3DFORMAT bit encodings, but the codes
// are different for win32, and this routine is used by a win32 library to
// manipulate 360 data, so there can be no reliance on D3DFORMAT bits
XGENDIANTYPE xEndian;
switch ( imageFormat )
{
default:
return;
case IMAGE_FORMAT_RGBA16161616:
if ( IsX360() )
{
// running on 360 the conversion output is correct
return;
}
// running on the pc, the output needs to be in 360 order
xEndian = XGENDIAN_8IN16;
break;
case IMAGE_FORMAT_DXT1:
case IMAGE_FORMAT_DXT1_ONEBITALPHA:
case IMAGE_FORMAT_DXT3:
case IMAGE_FORMAT_DXT5:
case IMAGE_FORMAT_UV88:
case IMAGE_FORMAT_ATI1N:
case IMAGE_FORMAT_ATI2N:
xEndian = XGENDIAN_8IN16;
break;
case IMAGE_FORMAT_BGRA8888:
case IMAGE_FORMAT_BGRX8888:
case IMAGE_FORMAT_UVWQ8888:
case IMAGE_FORMAT_UVLX8888:
xEndian = XGENDIAN_8IN32;
break;
}
int count;
if ( !stride )
{
stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
count = nImageSize / stride;
XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
}
else
{
int nRows = nImageSize/stride;
for ( int i=0; i<nRows; i++ )
{
XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
pImageData += stride;
}
}
#endif
}
//-----------------------------------------------------------------------------
// Swaps image bytes.
//-----------------------------------------------------------------------------
void ByteSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width, int stride )
{
Assert( IsFormatValidForConversion( imageFormat ) );
#if !defined( DX_TO_GL_ABSTRACTION ) && !defined( NO_X360_XDK )
XGENDIANTYPE xEndian;
switch ( imageFormat )
{
case IMAGE_FORMAT_BGR888:
case IMAGE_FORMAT_I8:
case IMAGE_FORMAT_A8:
default:
return;
case IMAGE_FORMAT_BGRA8888:
case IMAGE_FORMAT_BGRX8888:
case IMAGE_FORMAT_UVWQ8888:
case IMAGE_FORMAT_UVLX8888:
case IMAGE_FORMAT_R32F:
case IMAGE_FORMAT_RGBA32323232F:
xEndian = XGENDIAN_8IN32;
break;
case IMAGE_FORMAT_BGR565:
case IMAGE_FORMAT_BGRX5551:
case IMAGE_FORMAT_BGRA5551:
case IMAGE_FORMAT_BGRA4444:
case IMAGE_FORMAT_IA88:
case IMAGE_FORMAT_DXT1:
case IMAGE_FORMAT_DXT1_ONEBITALPHA:
case IMAGE_FORMAT_DXT3:
case IMAGE_FORMAT_DXT5:
case IMAGE_FORMAT_ATI1N:
case IMAGE_FORMAT_ATI2N:
case IMAGE_FORMAT_UV88:
case IMAGE_FORMAT_RGBA16161616F:
case IMAGE_FORMAT_RGBA16161616:
xEndian = XGENDIAN_8IN16;
break;
}
int count;
if ( !stride )
{
stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
count = nImageSize / stride;
XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
}
else
{
int nRows = nImageSize/stride;
for ( int i=0; i<nRows; i++ )
{
XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
pImageData += stride;
}
}
#endif
}
}

461
bitmap/bitmap.cpp Normal file
View File

@ -0,0 +1,461 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "bitmap/bitmap.h"
#include "dbg.h"
// Should be last include
#include "tier0/memdbgon.h"
bool Bitmap_t::IsValid() const
{
if ( m_nWidth <= 0 || m_nHeight <= 0 || m_pBits == NULL )
{
Assert( m_nWidth == 0 );
Assert( m_nHeight == 0 );
Assert( m_pBits == NULL );
return false;
}
return true;
}
void Bitmap_t::Clear()
{
if ( m_pBits && m_bOwnsBuffer )
{
free( m_pBits );
}
Reset();
}
void Bitmap_t::Init( int xs, int ys, ImageFormat imageFormat, int nStride )
{
// Check for bogus allocation sizes
if (xs <= 0 || ys <= 0 )
{
Assert( xs == 0 );
Assert( ys == 0 );
Clear();
return;
}
int nPixSize = ImageLoader::SizeInBytes( imageFormat );
// Auto detect stride
if ( nStride == 0 )
{
nStride = nPixSize * xs;
}
// Check for NOP
if (
m_pBits
&& m_bOwnsBuffer
&& m_nWidth == xs
&& m_nHeight == ys
&& nStride == m_nStride
&& nPixSize == m_nPixelSize )
{
// We're already got a buffer of the right size.
// The only thing that might be wrong is the pixel format.
m_ImageFormat = imageFormat;
return;
}
// Free up anything already allocated
Clear();
// Remember dimensions and pixel format
m_nWidth = xs;
m_nHeight = ys;
m_ImageFormat = imageFormat;
m_nPixelSize = nPixSize;
m_nStride = nStride;
// Allocate buffer. Because this is a PC game,
// failure is impossible....right?
m_pBits = (byte *)malloc( ys * m_nStride );
// Assume ownership
m_bOwnsBuffer = true;
}
void Bitmap_t::SetBuffer( int nWidth, int nHeight, ImageFormat imageFormat, unsigned char *pBits, bool bAssumeOwnership, int nStride )
{
Assert( pBits );
Assert( nWidth > 0 );
Assert( nHeight > 0 );
// Free up anything already allocated
Clear();
// Remember dimensions and pixel format
m_nWidth = nWidth;
m_nHeight = nHeight;
m_ImageFormat = imageFormat;
m_nPixelSize = ImageLoader::SizeInBytes( imageFormat );
if ( nStride == 0 )
{
m_nStride = m_nPixelSize * nWidth;
}
else
{
m_nStride = nStride;
}
// Set our buffer pointer
m_pBits = pBits;
// Assume ownership of the buffer, if requested
m_bOwnsBuffer = bAssumeOwnership;
// We should be good to go
Assert( IsValid() );
}
Color Bitmap_t::GetColor( int x, int y ) const
{
Assert( x >= 0 && x < m_nWidth );
Assert( y >= 0 && y < m_nHeight );
Assert( m_pBits );
// Get pointer to pixel data
byte *ptr = m_pBits + (y*m_nStride) + x* m_nPixelSize;
// Check supported image formats
switch ( m_ImageFormat )
{
case IMAGE_FORMAT_RGBA8888:
return Color( ptr[0], ptr[1], ptr[2], ptr[3] );
case IMAGE_FORMAT_ABGR8888:
return Color( ptr[3], ptr[2], ptr[1], ptr[0] );
default:
Assert( !"Unsupport image format!");
return Color( 255,0,255,255 );
}
}
void Bitmap_t::SetColor( int x, int y, Color c )
{
Assert( x >= 0 && x < m_nWidth );
Assert( y >= 0 && y < m_nHeight );
Assert( m_pBits );
// Get pointer to pixel data
byte *ptr = m_pBits + (y*m_nStride) + x* m_nPixelSize;
// Check supported image formats
switch ( m_ImageFormat )
{
case IMAGE_FORMAT_RGBA8888:
ptr[0] = c.r();
ptr[1] = c.g();
ptr[2] = c.b();
ptr[3] = c.a();
break;
case IMAGE_FORMAT_ABGR8888:
ptr[0] = c.a();
ptr[1] = c.b();
ptr[2] = c.g();
ptr[3] = c.r();
break;
default:
Assert( !"Unsupport image format!");
break;
}
}
//bool LoadVTF( const char *pszFilename )
//{
//
// // Load the raw file data
// CUtlBuffer fileData;
// if ( !filesystem->ReadFile( pszFilename, "game", fileData ) )
// {
// Warning( "Failed to load %s\n", pszFilename);
// return false;
// }
//
// return LoadVTFFromBuffer( fileData, pszFilename );
//}
//
//bool LoadVTFFromBuffer( CUtlBuffer fileData, const char *pszDebugName = "buffer" )
//{
//
// // Parse it into VTF object
// IVTFTexture *pVTFTexture( CreateVTFTexture() );
// if ( !pVTFTexture->Unserialize( fileData ) )
// {
// DestroyVTFTexture( pVTFTexture );
// Warning( "Failed to deserialize VTF %s\n", pszDebugName);
// return false;
// }
//
// // We are re-reading our own files, so they should be 8888's
// if ( pVTFTexture->Format() != IMAGE_FORMAT_RGBA8888 )
// {
// DestroyVTFTexture( pVTFTexture );
// Warning( "%s isn't RGBA8888\n", pszDebugName);
// return false;
// }
//
// // Copy the image data
// Allocate( pVTFTexture->Width(), pVTFTexture->Height() );
// for ( int y = 0 ; y < m_nHeight ; ++y )
// {
// memcpy( PixPtr(0, y), pVTFTexture->ImageData(0, 0, 0, 0, y), m_nWidth*4 );
// }
//
// // Clean up
// DestroyVTFTexture( pVTFTexture );
// return true;
//}
//
//bool SaveVTF( CUtlBuffer &outBuffer )
//{
// // Create the VTF to write into
// IVTFTexture *pVTFTexture( CreateVTFTexture() );
// const int nFlags = TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_SRGB;
// if ( !pVTFTexture->Init( m_nWidth, m_nHeight, 1, IMAGE_FORMAT_RGBA8888, nFlags, 1, 1 ) )
// {
// DestroyVTFTexture( pVTFTexture );
// return false;
// }
//
// // write the rgba image to the vtf texture using the pixel writer
// CPixelWriter pixelWriter;
// pixelWriter.SetPixelMemory( pVTFTexture->Format(), pVTFTexture->ImageData(), pVTFTexture->RowSizeInBytes( 0 ) );
//
// for (int y = 0; y < m_nHeight; ++y)
// {
// pixelWriter.Seek( 0, y );
// for (int x = 0; x < m_nWidth; ++x)
// {
// Color c = GetPix( x, y );
// pixelWriter.WritePixel( c.r(), c.g(), c.b(), c.a() );
// }
// }
//
// // Serialize to the buffer
// if ( !pVTFTexture->Serialize( outBuffer ) )
// {
// DestroyVTFTexture( pVTFTexture );
// return false;
// }
// DestroyVTFTexture( pVTFTexture );
// return true;
//}
//void Resize( int nNewSizeX, int nNewSizeY, const Image *pImgSrc = NULL )
//{
// if ( pImgSrc == NULL )
// {
// pImgSrc = this;
// }
//
// if ( nNewSizeX == m_nWidth && nNewSizeY == m_nHeight && pImgSrc == this )
// {
// return;
// }
//
// byte *pNewData = (byte *)malloc( nNewSizeX * nNewSizeY * 4 );
// ImgUtl_StretchRGBAImage( pImgSrc->m_pBits, pImgSrc->m_nWidth, pImgSrc->m_nHeight, pNewData, nNewSizeX, nNewSizeY );
// Clear();
// m_pBits = pNewData;
// m_nWidth = nNewSizeX;
// m_nHeight = nNewSizeY;
//}
//
//void Crop( int x0, int y0, int nNewSizeX, int nNewSizeY, const Image *pImgSrc )
//{
// if ( pImgSrc == NULL )
// {
// pImgSrc = this;
// }
//
// if ( nNewSizeX == m_nWidth && nNewSizeY == m_nHeight && pImgSrc == this )
// {
// return;
// }
//
//
// Assert( x0 >= 0 );
// Assert( y0 >= 0 );
// Assert( x0 + nNewSizeX <= pImgSrc->m_nWidth );
// Assert( y0 + nNewSizeY <= pImgSrc->m_nHeight );
//
// // Allocate new buffer
// int nRowSize = nNewSizeX * 4;
// byte *pNewData = (byte *)malloc( nNewSizeY * nRowSize );
//
// // Copy data, one row at a time
// for ( int y = 0 ; y < nNewSizeY ; ++y )
// {
// memcpy( pNewData + y*nRowSize, pImgSrc->PixPtr(x0, y0+y), nRowSize );
// }
//
// // Replace current buffer with the new one
// Clear();
// m_pBits = pNewData;
// m_nWidth = nNewSizeX;
// m_nHeight = nNewSizeY;
//}
void Bitmap_t::MakeLogicalCopyOf( Bitmap_t &src, bool bTransferBufferOwnership )
{
// What does it mean to make a logical copy of an
// invalid bitmap? I'll tell you what it means: you have a bug.
Assert( src.IsValid() );
// Free up anything we already own
Clear();
// Copy all of the member variables so we are
// a logical copy of the source bitmap
m_nWidth = src.m_nWidth;
m_nHeight = src.m_nHeight;
m_nPixelSize = src.m_nPixelSize;
m_nStride = src.m_nStride;
m_ImageFormat = src.m_ImageFormat;
m_pBits = src.m_pBits;
Assert( !m_bOwnsBuffer );
// Check for assuming ownership of the buffer
if ( bTransferBufferOwnership )
{
if ( src.m_bOwnsBuffer )
{
m_bOwnsBuffer = true;
src.m_bOwnsBuffer = false;
}
else
{
// They don't own the buffer? Then who does?
// Maybe nobody, and it would safe to assume
// ownership. But more than likely, this is a
// bug.
Assert( src.m_bOwnsBuffer );
// And a leak is better than a double-free.
// Don't assume ownership of the buffer.
}
}
}
void Bitmap_t::Crop( int x0, int y0, int nWidth, int nHeight, const Bitmap_t *pImgSource )
{
// Check for cropping in place, then save off our data to a temp
Bitmap_t temp;
if ( pImgSource == this || !pImgSource )
{
temp.MakeLogicalCopyOf( *this, m_bOwnsBuffer );
pImgSource = &temp;
}
// No source image?
if ( !pImgSource->IsValid() )
{
Assert( pImgSource->IsValid() );
return;
}
// Sanity check crop rectangle
Assert( x0 >= 0 );
Assert( y0 >= 0 );
Assert( x0 + nWidth <= pImgSource->Width() );
Assert( y0 + nHeight <= pImgSource->Height() );
// Allocate buffer
Init( nWidth, nHeight, pImgSource->Format() );
// Something wrong?
if ( !IsValid() )
{
Assert( IsValid() );
return;
}
// Copy the data a row at a time
int nRowSize = m_nWidth * m_nPixelSize;
for ( int y = 0 ; y < m_nHeight ; ++y )
{
memcpy( GetPixel(0,y), pImgSource->GetPixel( x0, y + y0 ), nRowSize );
}
}
void Bitmap_t::SetPixelData( const Bitmap_t &src, int nSrcX1, int nSrcY1, int nCopySizeX, int nCopySizeY, int nDestX1, int nDestY1 )
{
// Safety
if ( !src.IsValid() )
{
Assert( src.IsValid() );
return;
}
if ( !IsValid() )
{
Assert( IsValid() );
return;
}
// You need to specify a valid source rectangle, we cannot clip that for you
if ( nSrcX1 < 0 || nSrcY1 < 0 || nSrcX1 + nCopySizeX > src.Width() || nSrcY1 + nCopySizeY > src.Height() )
{
Assert( nSrcX1 >= 0 );
Assert( nSrcY1 >= 0 );
Assert( nSrcX1 + nCopySizeX <= src.Width() );
Assert( nSrcY1 + nCopySizeY <= src.Height() );
return;
}
// But we can clip the rectangle if it extends outside the destination image in a perfectly
// reasonable way
if ( nDestX1 < 0 )
{
nCopySizeX += nDestX1;
nDestX1 = 0;
}
if ( nDestX1 + nCopySizeX > Width() )
{
nCopySizeX = Width() - nDestX1;
}
if ( nDestY1 < 0 )
{
nCopySizeY += nDestY1;
nDestY1 = 0;
}
if ( nDestY1 + nCopySizeY > Height() )
{
nCopySizeY = Height() - nDestY1;
}
if ( nCopySizeX <= 0 || nCopySizeY <= 0 )
{
return;
}
// Copy the pixel data
for ( int y = 0 ; y < nCopySizeY ; ++y )
{
// Wow, this could be a lot faster in the common case
// that the pixe formats are the same. But...this code
// is simple and works, and is NOT the root of all evil.
for ( int x = 0 ; x < nCopySizeX ; ++x )
{
Color c = src.GetColor( nSrcX1 + x, nSrcY1 + y );
SetColor( nDestX1 + x, nDestY1 + y, c );
}
}
}
void Bitmap_t::SetPixelData( const Bitmap_t &src, int nDestX1, int nDestY1 )
{
SetPixelData( src, 0, 0, src.Width(), src.Height(), nDestX1, nDestY1 );
}

57
bitmap/bitmap.vpc Normal file
View File

@ -0,0 +1,57 @@
//-----------------------------------------------------------------------------
// BITMAP.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR ".."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE;$SRCDIR\dx9sdk\include" [$WINDOWS]
$AdditionalIncludeDirectories "$BASE;$SRCDIR\x360xdk\include\win32\vs2005" [$WINDOWS]
$AdditionalIncludeDirectories "$BASE;$SRCDIR\thirdparty\stb"
}
}
$Project "bitmap"
{
$Folder "Source Files"
{
$File "ImageByteSwap.cpp"
$File "colorconversion.cpp"
$File "float_bm.cpp"
$File "float_bm2.cpp"
$File "float_bm3.cpp"
$File "float_bm4.cpp" [$WINDOWS]
$File "float_bm_bilateral_filter.cpp"
$File "float_cube.cpp"
$File "imageformat.cpp"
$File "psd.cpp"
$File "resample.cpp"
$File "tgaloader.cpp"
$File "tgawriter.cpp"
$File "bitmap.cpp"
}
$Folder "Header Files"
{
$File "$SRCDIR\public\bitmap\bitmap.h"
$File "$SRCDIR\public\bitmap\float_bm.h"
$File "$SRCDIR\public\bitmap\imageformat.h"
$File "$SRCDIR\public\bitmap\psd.h"
$File "$SRCDIR\public\bitmap\tgaloader.h"
$File "$SRCDIR\public\bitmap\tgawriter.h"
$File "$SRCDIR\thirdparty\stb\stb_dxt.h"
}
$Folder "Link Libraries" [$WIN32]
{
$Lib nvtc
$Lib ATI_Compress_MT_VC10
}
}

2373
bitmap/colorconversion.cpp Normal file

File diff suppressed because it is too large Load Diff

729
bitmap/float_bm.cpp Normal file
View File

@ -0,0 +1,729 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <tier0/platform.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "bitmap/float_bm.h"
#include <tier2/tier2.h>
#include "bitmap/imageformat.h"
#include "bitmap/tgaloader.h"
#include "tier1/strtools.h"
#include "filesystem.h"
#define SQ(x) ((x)*(x))
// linear interpolate between 2 control points (L,R)
inline float LinInterp(float frac, float L, float R)
{
return (((R-L) * frac) + L);
}
// bilinear interpolate between 4 control points (UL,UR,LL,LR)
inline float BiLinInterp(float Xfrac, float Yfrac, float UL, float UR, float LL, float LR)
{
float iu = LinInterp(Xfrac, UL, UR);
float il = LinInterp(Xfrac, LL, LR);
return( LinInterp(Yfrac, iu, il) );
}
FloatBitMap_t::FloatBitMap_t(int width, int height)
{
RGBAData=0;
AllocateRGB(width,height);
}
FloatBitMap_t::FloatBitMap_t(FloatBitMap_t const *orig)
{
RGBAData=0;
AllocateRGB(orig->Width,orig->Height);
memcpy(RGBAData,orig->RGBAData,Width*Height*sizeof(float)*4);
}
static char GetChar(FileHandle_t &f)
{
char a;
g_pFullFileSystem->Read(&a,1,f);
return a;
}
static int GetInt(FileHandle_t &f)
{
char buf[100];
char *bout=buf;
for(;;)
{
char c=GetChar(f);
if ((c<'0') || (c>'9'))
break;
*(bout++)=c;
}
*(bout++)=0;
return atoi(buf);
}
#define PFM_MAX_XSIZE 2048
bool FloatBitMap_t::LoadFromPFM(char const *fname)
{
FileHandle_t f = g_pFullFileSystem->Open(fname, "rb");
if (f)
{
if( ( GetChar(f) == 'P' ) && (GetChar(f) == 'F' ) && ( GetChar(f) == '\n' ))
{
Width=GetInt(f);
Height=GetInt(f);
// eat crap until the next newline
while( GetChar(f) != '\n')
{
}
// printf("file %s w=%d h=%d\n",fname,Width,Height);
AllocateRGB(Width,Height);
for( int y = Height-1; y >= 0; y-- )
{
float linebuffer[PFM_MAX_XSIZE*3];
g_pFullFileSystem->Read(linebuffer,3*Width*sizeof(float),f);
for(int x=0;x<Width;x++)
{
for(int c=0;c<3;c++)
{
Pixel(x,y,c)=linebuffer[x*3+c];
}
}
}
}
g_pFullFileSystem->Close( f ); // close file after reading
}
return (RGBAData!=0);
}
bool FloatBitMap_t::WritePFM(char const *fname)
{
FileHandle_t f = g_pFullFileSystem->Open(fname, "wb");
if ( f )
{
g_pFullFileSystem->FPrintf(f,"PF\n%d %d\n-1.000000\n",Width,Height);
for( int y = Height-1; y >= 0; y-- )
{
float linebuffer[PFM_MAX_XSIZE*3];
for(int x=0;x<Width;x++)
{
for(int c=0;c<3;c++)
{
linebuffer[x*3+c]=Pixel(x,y,c);
}
}
g_pFullFileSystem->Write(linebuffer,3*Width*sizeof(float),f);
}
g_pFullFileSystem->Close(f);
return true;
}
return false;
}
float FloatBitMap_t::InterpolatedPixel(float x, float y, int comp) const
{
int Top= floor(y);
float Yfrac= y - Top;
int Bot= min(Height-1,Top+1);
int Left= floor(x);
float Xfrac= x - Left;
int Right= min(Width-1,Left+1);
return
BiLinInterp(Xfrac, Yfrac,
Pixel(Left, Top, comp),
Pixel(Right, Top, comp),
Pixel(Left, Bot, comp),
Pixel(Right, Bot, comp));
}
//-----------------------------------------------------------------
// resize (with bilinear filter) truecolor bitmap in place
void FloatBitMap_t::ReSize(int NewWidth, int NewHeight)
{
float XRatio= (float)Width / (float)NewWidth;
float YRatio= (float)Height / (float)NewHeight;
float SourceX, SourceY, Xfrac, Yfrac;
int Top, Bot, Left, Right;
float *newrgba=new float[NewWidth * NewHeight * 4];
SourceY= 0;
for(int y=0;y<NewHeight;y++)
{
Yfrac= SourceY - floor(SourceY);
Top= SourceY;
Bot= SourceY+1;
if (Bot>=Height) Bot= Height-1;
SourceX= 0;
for(int x=0;x<NewWidth;x++)
{
Xfrac= SourceX - floor(SourceX);
Left= SourceX;
Right= SourceX+1;
if (Right>=Width) Right= Width-1;
for(int c=0;c<4;c++)
{
newrgba[4*(y*NewWidth+x)+c] = BiLinInterp(Xfrac, Yfrac,
Pixel(Left, Top, c),
Pixel(Right, Top, c),
Pixel(Left, Bot, c),
Pixel(Right, Bot, c));
}
SourceX+= XRatio;
}
SourceY+= YRatio;
}
delete[] RGBAData;
RGBAData=newrgba;
Width=NewWidth;
Height=NewHeight;
}
struct TGAHeader_t
{
unsigned char id_length, colormap_type, image_type;
unsigned char colormap_index0,colormap_index1, colormap_length0,colormap_length1;
unsigned char colormap_size;
unsigned char x_origin0,x_origin1, y_origin0,y_origin1, width0, width1,height0,height1;
unsigned char pixel_size, attributes;
};
bool FloatBitMap_t::WriteTGAFile(char const *filename) const
{
FileHandle_t f = g_pFullFileSystem->Open(filename, "wb");
if (f)
{
TGAHeader_t myheader;
memset(&myheader,0,sizeof(myheader));
myheader.image_type=2;
myheader.pixel_size=32;
myheader.width0= Width & 0xff;
myheader.width1= (Width>>8);
myheader.height0= Height & 0xff;
myheader.height1= (Height>>8);
myheader.attributes=0x20;
g_pFullFileSystem->Write(&myheader,sizeof(myheader),f);
// now, write the pixels
for(int y=0;y<Height;y++)
{
for(int x=0;x<Width;x++)
{
PixRGBAF fpix = PixelRGBAF( x, y );
PixRGBA8 pix8 = PixRGBAF_to_8( fpix );
g_pFullFileSystem->Write(&pix8.Blue,1,f);
g_pFullFileSystem->Write(&pix8.Green,1,f);
g_pFullFileSystem->Write(&pix8.Red,1,f);
g_pFullFileSystem->Write(&pix8.Alpha,1,f);
}
}
g_pFullFileSystem->Close( f ); // close file after reading
return true;
}
return false;
}
FloatBitMap_t::FloatBitMap_t(char const *tgafilename)
{
RGBAData=0;
// load from a tga or pfm
if (Q_stristr(tgafilename, ".pfm"))
{
LoadFromPFM(tgafilename);
return;
}
int width1, height1;
ImageFormat imageFormat1;
float gamma1;
if( !TGALoader::GetInfo( tgafilename, &width1, &height1, &imageFormat1, &gamma1 ) )
{
printf( "error loading %s\n", tgafilename);
exit( -1 );
}
AllocateRGB(width1,height1);
uint8 *pImage1Tmp =
new uint8 [ImageLoader::GetMemRequired( width1, height1, 1, imageFormat1, false )];
if( !TGALoader::Load( pImage1Tmp, tgafilename, width1, height1, imageFormat1, 2.2f, false ) )
{
printf( "error loading %s\n", tgafilename);
exit( -1 );
}
uint8 *pImage1 =
new uint8 [ImageLoader::GetMemRequired( width1, height1, 1, IMAGE_FORMAT_ABGR8888, false )];
ImageLoader::ConvertImageFormat( pImage1Tmp, imageFormat1, pImage1, IMAGE_FORMAT_ABGR8888, width1, height1, 0, 0 );
for(int y=0;y<height1;y++)
{
for(int x=0;x<width1;x++)
{
for(int c=0;c<4;c++)
{
Pixel(x,y,3-c)=pImage1[c+4*(x+(y*width1))]/255.0;
}
}
}
delete[] pImage1;
delete[] pImage1Tmp;
}
FloatBitMap_t::~FloatBitMap_t(void)
{
if (RGBAData)
delete[] RGBAData;
}
FloatBitMap_t *FloatBitMap_t::QuarterSize(void) const
{
// generate a new bitmap half on each axis
FloatBitMap_t *newbm=new FloatBitMap_t(Width/2,Height/2);
for(int y=0;y<Height/2;y++)
for(int x=0;x<Width/2;x++)
{
for(int c=0;c<4;c++)
newbm->Pixel(x,y,c)=((Pixel(x*2,y*2,c)+Pixel(x*2+1,y*2,c)+
Pixel(x*2,y*2+1,c)+Pixel(x*2+1,y*2+1,c))/4);
}
return newbm;
}
FloatBitMap_t *FloatBitMap_t::QuarterSizeBlocky(void) const
{
// generate a new bitmap half on each axis
FloatBitMap_t *newbm=new FloatBitMap_t(Width/2,Height/2);
for(int y=0;y<Height/2;y++)
for(int x=0;x<Width/2;x++)
{
for(int c=0;c<4;c++)
newbm->Pixel(x,y,c)=Pixel(x*2,y*2,c);
}
return newbm;
}
Vector FloatBitMap_t::AverageColor(void)
{
Vector ret(0,0,0);
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
for(int c=0;c<3;c++)
ret[c]+=Pixel(x,y,c);
ret*=1.0/(Width*Height);
return ret;
}
float FloatBitMap_t::BrightestColor(void)
{
float ret=0.0;
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
{
Vector v(Pixel(x,y,0),Pixel(x,y,1),Pixel(x,y,2));
ret=max(ret,v.Length());
}
return ret;
}
template <class T> static inline void SWAP(T & a, T & b)
{
T temp=a;
a=b;
b=temp;
}
void FloatBitMap_t::RaiseToPower(float power)
{
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
for(int c=0;c<3;c++)
Pixel(x,y,c)=pow((float)MAX(0.0,Pixel(x,y,c)),(float)power);
}
void FloatBitMap_t::Logize(void)
{
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
for(int c=0;c<3;c++)
Pixel(x,y,c)=log(1.0+Pixel(x,y,c));
}
void FloatBitMap_t::UnLogize(void)
{
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
for(int c=0;c<3;c++)
Pixel(x,y,c)=exp(Pixel(x,y,c))-1;
}
void FloatBitMap_t::Clear(float r, float g, float b, float alpha)
{
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
{
Pixel(x,y,0)=r;
Pixel(x,y,1)=g;
Pixel(x,y,2)=b;
Pixel(x,y,3)=alpha;
}
}
void FloatBitMap_t::ScaleRGB(float scale_factor)
{
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
for(int c=0;c<3;c++)
Pixel(x,y,c)*=scale_factor;
}
static int dx[4]={0,-1,1,0};
static int dy[4]={-1,0,0,1};
#define NDELTAS 4
void FloatBitMap_t::SmartPaste(FloatBitMap_t const &b, int xofs, int yofs, uint32 Flags)
{
// now, need to make Difference map
FloatBitMap_t DiffMap0(this);
FloatBitMap_t DiffMap1(this);
FloatBitMap_t DiffMap2(this);
FloatBitMap_t DiffMap3(this);
FloatBitMap_t *deltas[4]={&DiffMap0,&DiffMap1,&DiffMap2,&DiffMap3};
for(int x=0;x<Width;x++)
for(int y=0;y<Height;y++)
for(int c=0;c<3;c++)
{
for(int i=0;i<NDELTAS;i++)
{
int x1=x+dx[i];
int y1=y+dy[i];
x1=MAX(0,x1);
x1=MIN(Width-1,x1);
y1=MAX(0,y1);
y1=MIN(Height-1,y1);
float dx1=Pixel(x,y,c)-Pixel(x1,y1,c);
deltas[i]->Pixel(x,y,c)=dx1;
}
}
for(int x=1;x<b.Width-1;x++)
for(int y=1;y<b.Height-1;y++)
for(int c=0;c<3;c++)
{
for(int i=0;i<NDELTAS;i++)
{
float diff=b.Pixel(x,y,c)-b.Pixel(x+dx[i],y+dy[i],c);
deltas[i]->Pixel(x+xofs,y+yofs,c)=diff;
if (Flags & SPFLAGS_MAXGRADIENT)
{
float dx1=Pixel(x+xofs,y+yofs,c)-Pixel(x+dx[i]+xofs,y+dy[i]+yofs,c);
if (fabs(dx1)>fabs(diff))
deltas[i]->Pixel(x+xofs,y+yofs,c)=dx1;
}
}
}
// now, calculate modifiability
for(int x=0;x<Width;x++)
for(int y=0;y<Height;y++)
{
float modify=0;
if (
(x>xofs+1) && (x<=xofs+b.Width-2) &&
(y>yofs+1) && (y<=yofs+b.Height-2))
modify=1;
Alpha(x,y)=modify;
}
// // now, force a fex pixels in center to be constant
// int midx=xofs+b.Width/2;
// int midy=yofs+b.Height/2;
// for(x=midx-10;x<midx+10;x++)
// for(int y=midy-10;y<midy+10;y++)
// {
// Alpha(x,y)=0;
// for(int c=0;c<3;c++)
// Pixel(x,y,c)=b.Pixel(x-xofs,y-yofs,c);
// }
Poisson(deltas,6000,Flags);
}
void FloatBitMap_t::ScaleGradients(void)
{
// now, need to make Difference map
FloatBitMap_t DiffMap0(this);
FloatBitMap_t DiffMap1(this);
FloatBitMap_t DiffMap2(this);
FloatBitMap_t DiffMap3(this);
FloatBitMap_t *deltas[4]={&DiffMap0,&DiffMap1,&DiffMap2,&DiffMap3};
double gsum=0.0;
for(int x=0;x<Width;x++)
for(int y=0;y<Height;y++)
for(int c=0;c<3;c++)
{
for(int i=0;i<NDELTAS;i++)
{
int x1=x+dx[i];
int y1=y+dy[i];
x1=MAX(0,x1);
x1=MIN(Width-1,x1);
y1=MAX(0,y1);
y1=MIN(Height-1,y1);
float dx1=Pixel(x,y,c)-Pixel(x1,y1,c);
deltas[i]->Pixel(x,y,c)=dx1;
gsum+=fabs(dx1);
}
}
// now, reduce gradient changes
// float gavg=gsum/(Width*Height);
for(int x=0;x<Width;x++)
for(int y=0;y<Height;y++)
for(int c=0;c<3;c++)
{
for(int i=0;i<NDELTAS;i++)
{
float norml=1.1*deltas[i]->Pixel(x,y,c);
// if (norml<0.0)
// norml=-pow(-norml,1.2);
// else
// norml=pow(norml,1.2);
deltas[i]->Pixel(x,y,c)=norml;
}
}
// now, calculate modifiability
for(int x=0;x<Width;x++)
for(int y=0;y<Height;y++)
{
float modify=0;
if (
(x>0) && (x<Width-1) &&
(y) && (y<Height-1))
{
modify=1;
Alpha(x,y)=modify;
}
}
Poisson(deltas,2200,0);
}
void FloatBitMap_t::MakeTileable(void)
{
FloatBitMap_t rslta(this);
// now, need to make Difference map
FloatBitMap_t DiffMapX(this);
FloatBitMap_t DiffMapY(this);
// set each pixel=avg-pixel
FloatBitMap_t *cursrc=&rslta;
for(int x=1;x<Width-1;x++)
for(int y=1;y<Height-1;y++)
for(int c=0;c<3;c++)
{
DiffMapX.Pixel(x,y,c)=Pixel(x,y,c)-Pixel(x+1,y,c);
DiffMapY.Pixel(x,y,c)=Pixel(x,y,c)-Pixel(x,y+1,c);
}
// initialize edge conditions
for(int x=0;x<Width;x++)
{
for(int c=0;c<3;c++)
{
float a=0.5*(Pixel(x,Height-1,c)+=Pixel(x,0,c));
rslta.Pixel(x,Height-1,c)=a;
rslta.Pixel(x,0,c)=a;
}
}
for(int y=0;y<Height;y++)
{
for(int c=0;c<3;c++)
{
float a=0.5*(Pixel(Width-1,y,c)+Pixel(0,y,c));
rslta.Pixel(Width-1,y,c)=a;
rslta.Pixel(0,y,c)=a;
}
}
FloatBitMap_t rsltb(&rslta);
FloatBitMap_t *curdst=&rsltb;
// now, ready to iterate
for(int pass=0;pass<10;pass++)
{
float error=0.0;
for(int x=1;x<Width-1;x++)
for(int y=1;y<Height-1;y++)
for(int c=0;c<3;c++)
{
float desiredx=DiffMapX.Pixel(x,y,c)+cursrc->Pixel(x+1,y,c);
float desiredy=DiffMapY.Pixel(x,y,c)+cursrc->Pixel(x,y+1,c);
float desired=0.5*(desiredy+desiredx);
curdst->Pixel(x,y,c)=FLerp(cursrc->Pixel(x,y,c),desired,0.5);
error+=SQ(desired-cursrc->Pixel(x,y,c));
}
SWAP(cursrc,curdst);
}
// paste result
for(int x=0;x<Width;x++)
for(int y=0;y<Height;y++)
for(int c=0;c<3;c++)
Pixel(x,y,c)=curdst->Pixel(x,y,c);
}
void FloatBitMap_t::GetAlphaBounds(int &minx, int &miny, int &maxx,int &maxy)
{
for(minx=0;minx<Width;minx++)
{
int y;
for(y=0;y<Height;y++)
if (Alpha(minx,y))
break;
if (y!=Height)
break;
}
for(maxx=Width-1;maxx>=0;maxx--)
{
int y;
for(y=0;y<Height;y++)
if (Alpha(maxx,y))
break;
if (y!=Height)
break;
}
for(miny=0;minx<Height;miny++)
{
int x;
for(x=minx;x<=maxx;x++)
if (Alpha(x,miny))
break;
if (x<maxx)
break;
}
for(maxy=Height-1;maxy>=0;maxy--)
{
int x;
for(x=minx;x<=maxx;x++)
if (Alpha(x,maxy))
break;
if (x<maxx)
break;
}
}
void FloatBitMap_t::Poisson(FloatBitMap_t *deltas[4],
int n_iters,
uint32 flags // SPF_xxx
)
{
int minx,miny,maxx,maxy;
GetAlphaBounds(minx,miny,maxx,maxy);
minx=MAX(1,minx);
miny=MAX(1,miny);
maxx=MIN(Width-2,maxx);
maxy=MIN(Height-2,maxy);
if (((maxx-minx)>25) && (maxy-miny)>25)
{
// perform at low resolution
FloatBitMap_t *lowdeltas[NDELTAS];
for(int i=0;i<NDELTAS;i++)
lowdeltas[i]=deltas[i]->QuarterSize();
FloatBitMap_t *tmp=QuarterSize();
tmp->Poisson(lowdeltas,n_iters*4,flags);
// now, propagate results from tmp to us
for(int x=0;x<tmp->Width;x++)
for(int y=0;y<tmp->Height;y++)
for(int xi=0;xi<2;xi++)
for(int yi=0;yi<2;yi++)
if (Alpha(x*2+xi,y*2+yi))
{
for(int c=0;c<3;c++)
Pixel(x*2+xi,y*2+yi,c)=
FLerp(Pixel(x*2+xi,y*2+yi,c),tmp->Pixel(x,y,c),Alpha(x*2+xi,y*2+yi));
}
char fname[80];
sprintf(fname,"sub%dx%d.tga",tmp->Width,tmp->Height);
tmp->WriteTGAFile(fname);
sprintf(fname,"submrg%dx%d.tga",tmp->Width,tmp->Height);
WriteTGAFile(fname);
delete tmp;
for(int i=0;i<NDELTAS;i++)
delete lowdeltas[i];
}
FloatBitMap_t work1(this);
FloatBitMap_t work2(this);
FloatBitMap_t *curdst=&work1;
FloatBitMap_t *cursrc=&work2;
// now, ready to iterate
while(n_iters--)
{
float error=0.0;
for(int x=minx;x<=maxx;x++)
{
for(int y=miny;y<=maxy;y++)
{
if (Alpha(x,y))
{
for(int c=0;c<3;c++)
{
float desired=0.0;
for(int i=0;i<NDELTAS;i++)
desired+=deltas[i]->Pixel(x,y,c)+cursrc->Pixel(x+dx[i],y+dy[i],c);
desired*=(1.0/NDELTAS);
// desired=FLerp(Pixel(x,y,c),desired,Alpha(x,y));
curdst->Pixel(x,y,c)=FLerp(cursrc->Pixel(x,y,c),desired,0.5);
error+=SQ(desired-cursrc->Pixel(x,y,c));
}
}
SWAP(cursrc,curdst);
}
}
}
// paste result
for(int x=0;x<Width;x++)
{
for(int y=0;y<Height;y++)
{
for(int c=0;c<3;c++)
{
Pixel(x,y,c)=curdst->Pixel(x,y,c);
}
}
}
}

144
bitmap/float_bm2.cpp Normal file
View File

@ -0,0 +1,144 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <tier0/platform.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "bitmap/float_bm.h"
static float ScaleValue(float f, float overbright)
{
// map a value between 0..255 to the scale factor
int ival=f;
return ival*(overbright/255.0);
}
static float IScaleValue(float f, float overbright)
{
f*=(1.0/overbright);
int ival=min(255,(int)ceil(f*255.0));
return ival;
}
void MaybeSetScaleVaue(FloatBitMap_t const &orig, FloatBitMap_t &newbm, int x, int y,
float newscale, float overbright)
{
// clamp the given scale value to the legal range for that pixel and regnerate the rgb
// components.
float maxc=max(max(orig.Pixel(x,y,0),orig.Pixel(x,y,1)),orig.Pixel(x,y,2));
if (maxc==0.0)
{
// pixel is black. any scale value is fine.
newbm.Pixel(x,y,3)=newscale;
for(int c=0;c<3;c++)
newbm.Pixel(x,y,c)=0;
}
else
{
// float desired_floatscale=maxc;
float scale_we_will_get=ScaleValue(newscale,overbright);
// if (scale_we_will_get >= desired_floatscale )
{
newbm.Pixel(x,y,3)=newscale;
for(int c=0;c<3;c++)
newbm.Pixel(x,y,c)=orig.Pixel(x,y,c)/(scale_we_will_get);
}
}
}
void FloatBitMap_t::Uncompress(float overbright)
{
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
{
int iactual_alpha_value=255.0*Pixel(x,y,3);
float actual_alpha_value=iactual_alpha_value*(1.0/255.0);
for(int c=0;c<3;c++)
{
int iactual_color_value=255.0*Pixel(x,y,c);
float actual_color_value=iactual_color_value*(1.0/255.0);
Pixel(x,y,c)=actual_alpha_value*actual_color_value*overbright;
}
}
}
#define GAUSSIAN_WIDTH 5
#define SQ(x) ((x)*(x))
void FloatBitMap_t::CompressTo8Bits(float overbright)
{
FloatBitMap_t TmpFBM(Width,Height);
// first, saturate to max overbright
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
for(int c=0;c<3;c++)
Pixel(x,y,c)=min(overbright,Pixel(x,y,c));
// first pass - choose nominal scale values to convert to rgb,scale
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
{
// determine maximum component
float maxc=max(max(Pixel(x,y,0),Pixel(x,y,1)),Pixel(x,y,2));
if (maxc==0)
{
for(int c=0;c<4;c++)
TmpFBM.Pixel(x,y,c)=0;
}
else
{
float desired_floatscale=maxc;
float closest_iscale=IScaleValue(desired_floatscale, overbright);
float scale_value_we_got=ScaleValue(closest_iscale, overbright );
TmpFBM.Pixel(x,y,3)=closest_iscale;
for(int c=0;c<3;c++)
TmpFBM.Pixel(x,y,c)=Pixel(x,y,c)/scale_value_we_got;
}
}
// now, refine scale values
#ifdef FILTER_TO_REDUCE_LERP_ARTIFACTS
// I haven't been able to come up with a filter which eleiminates objectionable artifacts on all
// source textures. So, I've gone to doing the lerping in the shader.
int pass=0;
while(pass<1)
{
FloatBitMap_t temp_filtered(&TmpFBM);
for(int y=0;y<Height;y++)
{
for(int x=0;x<Width;x++)
{
float sum_scales=0.0;
float sum_weights=0.0;
for(int yofs=-GAUSSIAN_WIDTH;yofs<=GAUSSIAN_WIDTH;yofs++)
for(int xofs=-GAUSSIAN_WIDTH;xofs<=GAUSSIAN_WIDTH;xofs++)
{
float r=0.456*GAUSSIAN_WIDTH;
r=0.26*GAUSSIAN_WIDTH;
float x1=xofs/r;
float y1=yofs/r;
float a=(SQ(x1)+SQ(y1))/(2.0*SQ(r));
float w=exp(-a);
sum_scales+=w*TmpFBM.PixelClamped(x+xofs,y+yofs,3);
sum_weights+=w;
}
int new_trial_scale=sum_scales*(1.0/sum_weights);
MaybeSetScaleVaue(*this,temp_filtered,x,y,new_trial_scale,overbright);
}
}
pass++;
memcpy(TmpFBM.RGBAData,temp_filtered.RGBAData,Width*Height*4*sizeof(float));
}
#endif
memcpy(RGBAData,TmpFBM.RGBAData,Width*Height*4*sizeof(float));
// now, map scale to real value
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
Pixel(x,y,3)*=(1.0/255.0);
}

108
bitmap/float_bm3.cpp Normal file
View File

@ -0,0 +1,108 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <tier0/platform.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "bitmap/float_bm.h"
#include "vstdlib/vstdlib.h"
#include "vstdlib/random.h"
#include "tier1/strtools.h"
void FloatBitMap_t::InitializeWithRandomPixelsFromAnotherFloatBM(FloatBitMap_t const &other)
{
for(int y=0;y<Height;y++)
for(int x=0;x<Width;x++)
{
float x1=RandomInt(0,other.Width-1);
float y1=RandomInt(0,other.Height-1);
for(int c=0;c<4;c++)
{
Pixel(x,y,c)=other.Pixel(x1,y1,c);
}
}
}
FloatBitMap_t *FloatBitMap_t::QuarterSizeWithGaussian(void) const
{
// generate a new bitmap half on each axis, using a separable gaussian.
static float kernel[]={.05,.25,.4,.25,.05};
FloatBitMap_t *newbm=new FloatBitMap_t(Width/2,Height/2);
for(int y=0;y<Height/2;y++)
for(int x=0;x<Width/2;x++)
{
for(int c=0;c<4;c++)
{
float sum=0;
float sumweights=0; // for versatility in handling the
// offscreen case
for(int xofs=-2;xofs<=2;xofs++)
{
int orig_x=max(0,min(Width-1,x*2+xofs));
for(int yofs=-2;yofs<=2;yofs++)
{
int orig_y=max(0,min(Height-1,y*2+yofs));
float coeff=kernel[xofs+2]*kernel[yofs+2];
sum+=Pixel(orig_x,orig_y,c)*coeff;
sumweights+=coeff;
}
}
newbm->Pixel(x,y,c)=sum/sumweights;
}
}
return newbm;
}
FloatImagePyramid_t::FloatImagePyramid_t(FloatBitMap_t const &src, ImagePyramidMode_t mode)
{
memset(m_pLevels,0,sizeof(m_pLevels));
m_nLevels=1;
m_pLevels[0]=new FloatBitMap_t(&src);
ReconstructLowerResolutionLevels(0);
}
void FloatImagePyramid_t::ReconstructLowerResolutionLevels(int start_level)
{
while( (m_pLevels[start_level]->Width>1) && (m_pLevels[start_level]->Height>1) )
{
if (m_pLevels[start_level+1])
delete m_pLevels[start_level+1];
m_pLevels[start_level+1]=m_pLevels[start_level]->QuarterSizeWithGaussian();
start_level++;
}
m_nLevels=start_level+1;
}
float & FloatImagePyramid_t::Pixel(int x, int y, int component, int level) const
{
assert(level<m_nLevels);
x<<=level;
y<<=level;
return m_pLevels[level]->Pixel(x,y,component);
}
void FloatImagePyramid_t::WriteTGAs(char const *basename) const
{
for(int l=0;l<m_nLevels;l++)
{
char bname_out[1024];
Q_snprintf(bname_out,sizeof(bname_out),"%s_%02d.tga",basename,l);
m_pLevels[l]->WriteTGAFile(bname_out);
}
}
FloatImagePyramid_t::~FloatImagePyramid_t(void)
{
for(int l=0;l<m_nLevels;l++)
if (m_pLevels[l])
delete m_pLevels[l];
}

350
bitmap/float_bm4.cpp Normal file
View File

@ -0,0 +1,350 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <tier0/platform.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "bitmap/float_bm.h"
#include "vstdlib/vstdlib.h"
#include "raytrace.h"
#include "mathlib/bumpvects.h"
#include "mathlib/halton.h"
#include "tier0/threadtools.h"
#include "tier0/progressbar.h"
// In order to handle intersections with wrapped copies, we repeat the bitmap triangles this many
// times
#define NREPS_TILE 1
extern int n_intersection_calculations;
struct SSBumpCalculationContext // what each thread needs to see
{
RayTracingEnvironment *m_pRtEnv;
FloatBitMap_t *ret_bm; // the bitmnap we are building
FloatBitMap_t const *src_bm;
int nrays_to_trace_per_pixel;
float bump_scale;
Vector *trace_directions; // light source directions to trace
Vector *normals;
int min_y; // range of scanlines to computer for
int max_y;
uint32 m_nOptionFlags;
int thread_number;
};
static unsigned SSBumpCalculationThreadFN( void * ctx1 )
{
SSBumpCalculationContext *ctx = ( SSBumpCalculationContext * ) ctx1;
RayStream ray_trace_stream_ctx;
RayTracingSingleResult * rslts = new
RayTracingSingleResult[ctx->ret_bm->Width * ctx->nrays_to_trace_per_pixel];
for( int y = ctx->min_y; y <= ctx->max_y; y++ )
{
if ( ctx->thread_number == 0 )
ReportProgress("Computing output",(1+ctx->max_y-ctx->min_y),y-ctx->min_y);
for( int r = 0; r < ctx->nrays_to_trace_per_pixel; r++ )
{
for( int x = 0; x < ctx->ret_bm->Width; x++ )
{
Vector surf_pnt( x, y, ctx->bump_scale * ctx->src_bm->Pixel( x, y, 3 ) );
// move the ray origin up a hair
surf_pnt.z += 0.55;
Vector trace_end = surf_pnt;
Vector trace_dir = ctx->trace_directions[ r ];
trace_dir *= ( 1 + NREPS_TILE * 2 ) * max( ctx->src_bm->Width, ctx->src_bm->Height );
trace_end += trace_dir;
ctx->m_pRtEnv->AddToRayStream( ray_trace_stream_ctx, surf_pnt, trace_end,
& ( rslts[ r + ctx->nrays_to_trace_per_pixel * ( x )] ));
}
}
if ( ctx->nrays_to_trace_per_pixel )
ctx->m_pRtEnv->FinishRayStream( ray_trace_stream_ctx );
// now, all ray tracing results are in the results buffer. Determine the visible self-shadowed
// bump map lighting at each vertex in each basis direction
for( int x = 0; x < ctx->src_bm->Width; x++ )
{
int nNumChannels = ( ctx->m_nOptionFlags & SSBUMP_OPTION_NONDIRECTIONAL ) ? 1 : 3;
for( int c = 0; c < nNumChannels; c++ )
{
float sum_dots = 0;
float sum_possible_dots = 0;
Vector ldir = g_localBumpBasis[c];
float ndotl = DotProduct( ldir, ctx->normals[x + y * ctx->src_bm->Width] );
if ( ndotl < 0 )
ctx->ret_bm->Pixel( x, y, c ) = 0;
else
{
if ( ctx->nrays_to_trace_per_pixel )
{
RayTracingSingleResult *this_rslt =
rslts + ctx->nrays_to_trace_per_pixel * ( x );
for( int r = 0; r < ctx->nrays_to_trace_per_pixel; r++ )
{
float dot;
if ( ctx->m_nOptionFlags & SSBUMP_OPTION_NONDIRECTIONAL )
dot = ctx->trace_directions[r].z;
else
dot = DotProduct( ldir, ctx->trace_directions[r] );
if ( dot > 0 )
{
sum_possible_dots += dot;
if ( this_rslt[r].HitID == - 1 )
sum_dots += dot;
}
}
}
else
{
sum_dots = sum_possible_dots = 1.0;
}
ctx->ret_bm->Pixel( x, y, c ) = ( ndotl * sum_dots ) / sum_possible_dots;
}
}
if ( ctx->m_nOptionFlags & SSBUMP_OPTION_NONDIRECTIONAL )
{
ctx->ret_bm->Pixel( x, y, 1 ) = ctx->ret_bm->Pixel( x, y, 0 ); // copy height
ctx->ret_bm->Pixel( x, y, 2 ) = ctx->ret_bm->Pixel( x, y, 0 ); // copy height
ctx->ret_bm->Pixel( x, y, 3 ) = ctx->ret_bm->Pixel( x, y, 0 ); // copy height
}
else
{
ctx->ret_bm->Pixel( x, y, 3 ) = ctx->src_bm->Pixel( x, y, 3 ); // copy height
}
}
}
delete[] rslts;
return 0;
}
void FloatBitMap_t::ComputeVertexPositionsAndNormals( float flHeightScale, Vector **ppPosOut, Vector **ppNormalOut ) const
{
Vector *verts = new Vector[Width * Height];
// first, calculate vertex positions
for( int y = 0; y < Height; y++ )
for( int x = 0; x < Width; x++ )
{
Vector * out = verts + x + y * Width;
out->x = x;
out->y = y;
out->z = flHeightScale * Pixel( x, y, 3 );
}
Vector *normals = new Vector[Width * Height];
// now, calculate normals, smoothed
for( int y = 0; y < Height; y++ )
for( int x = 0; x < Width; x++ )
{
// now, calculcate average normal
Vector avg_normal( 0, 0, 0 );
for( int xofs =- 1;xofs <= 1;xofs++ )
for( int yofs =- 1;yofs <= 1;yofs++ )
{
int x0 = ( x + xofs );
if ( x0 < 0 )
x0 += Width;
int y0 = ( y + yofs );
if ( y0 < 0 )
y0 += Height;
x0 = x0 % Width;
y0 = y0 % Height;
int x1 = ( x0 + 1 ) % Width;
int y1 = ( y0 + 1 ) % Height;
// now, form the two triangles from this vertex
Vector p0 = verts[x0 + y0 * Width];
Vector e1 = verts[x1 + y0 * Width];
e1 -= p0;
Vector e2 = verts[x0 + y1 * Width];
e2 -= p0;
Vector n1;
CrossProduct( e1, e2, n1 );
if ( n1.z < 0 )
n1.Negate();
e1 = verts[x + y1 * Width];
e1 -= p0;
e2 = verts[x1 + y1 * Width];
e2 -= p0;
Vector n2;
CrossProduct( e1, e2, n2 );
if ( n2.z < 0 )
n2.Negate();
n1.NormalizeInPlace();
n2.NormalizeInPlace();
avg_normal += n1;
avg_normal += n2;
}
avg_normal.NormalizeInPlace();
normals[x + y * Width]= avg_normal;
}
*ppPosOut = verts;
*ppNormalOut = normals;
}
FloatBitMap_t *FloatBitMap_t::ComputeSelfShadowedBumpmapFromHeightInAlphaChannel(
float bump_scale, int nrays_to_trace_per_pixel,
uint32 nOptionFlags ) const
{
// first, add all the triangles from the height map to the "world".
// we will make multiple copies to handle wrapping
int tcnt = 1;
Vector * verts;
Vector * normals;
ComputeVertexPositionsAndNormals( bump_scale, & verts, & normals );
RayTracingEnvironment rtEnv;
rtEnv.Flags |= RTE_FLAGS_DONT_STORE_TRIANGLE_COLORS; // save some ram
if ( nrays_to_trace_per_pixel )
{
rtEnv.MakeRoomForTriangles( ( 1 + 2 * NREPS_TILE ) * ( 1 + 2 * NREPS_TILE ) * 2 * Height * Width );
// now, add a whole mess of triangles to trace against
for( int tilex =- NREPS_TILE; tilex <= NREPS_TILE; tilex++ )
for( int tiley =- NREPS_TILE; tiley <= NREPS_TILE; tiley++ )
{
int min_x = 0;
int max_x = Width - 1;
int min_y = 0;
int max_y = Height - 1;
if ( tilex < 0 )
min_x = Width / 2;
if ( tilex > 0 )
max_x = Width / 2;
if ( tiley < 0 )
min_y = Height / 2;
if ( tiley > 0 )
max_y = Height / 2;
for( int y = min_y; y <= max_y; y++ )
for( int x = min_x; x <= max_x; x++ )
{
Vector ofs( tilex * Width, tiley * Height, 0 );
int x1 = ( x + 1 ) % Width;
int y1 = ( y + 1 ) % Height;
Vector v0 = verts[x + y * Width];
Vector v1 = verts[x1 + y * Width];
Vector v2 = verts[x1 + y1 * Width];
Vector v3 = verts[x + y1 * Width];
v0.x = x; v0.y = y;
v1.x = x + 1; v1.y = y;
v2.x = x + 1; v2.y = y + 1;
v3.x = x; v3.y = y + 1;
v0 += ofs; v1 += ofs; v2 += ofs; v3 += ofs;
rtEnv.AddTriangle( tcnt++, v0, v1, v2, Vector( 1, 1, 1 ) );
rtEnv.AddTriangle( tcnt++, v0, v3, v2, Vector( 1, 1, 1 ) );
}
}
//printf("added %d triangles\n",tcnt-1);
ReportProgress("Creating kd-tree",0,0);
rtEnv.SetupAccelerationStructure();
// ok, now we have built a structure for ray intersection. we will take advantage
// of the SSE ray tracing code by intersecting rays as a batch.
}
// We need to calculate for each vertex (i.e. pixel) of the heightmap, how "much" of the world
// it can see in each basis direction. we will do this by sampling a sphere of rays around the
// vertex, and using dot-product weighting to measure the lighting contribution in each basis
// direction. note that the surface normal is not used here. The surface normal will end up
// being reflected in the result because of rays being blocked when they try to pass through
// the planes of the triangles touching the vertex.
// note that there is no reason inter-bounced lighting could not be folded into this
// calculation.
FloatBitMap_t * ret = new FloatBitMap_t( Width, Height );
Vector *trace_directions=new Vector[nrays_to_trace_per_pixel];
DirectionalSampler_t my_sphere_sampler;
for( int r=0; r < nrays_to_trace_per_pixel; r++)
{
Vector trace_dir=my_sphere_sampler.NextValue();
// trace_dir=Vector(1,0,0);
trace_dir.z=fabs(trace_dir.z); // upwards facing only
trace_directions[ r ]= trace_dir;
}
volatile SSBumpCalculationContext ctxs[32];
ctxs[0].m_pRtEnv =& rtEnv;
ctxs[0].ret_bm = ret;
ctxs[0].src_bm = this;
ctxs[0].nrays_to_trace_per_pixel = nrays_to_trace_per_pixel;
ctxs[0].bump_scale = bump_scale;
ctxs[0].trace_directions = trace_directions;
ctxs[0].normals = normals;
ctxs[0].min_y = 0;
ctxs[0].max_y = Height - 1;
ctxs[0].m_nOptionFlags = nOptionFlags;
int nthreads = min( 32, (int)GetCPUInformation()->m_nPhysicalProcessors );
ThreadHandle_t waithandles[32];
int starty = 0;
int ystep = Height / nthreads;
for( int t = 0;t < nthreads; t++ )
{
if ( t )
memcpy( (void * ) ( & ctxs[t] ), ( void * ) & ctxs[0], sizeof( ctxs[0] ));
ctxs[t].thread_number = t;
ctxs[t].min_y = starty;
if ( t != nthreads - 1 )
ctxs[t].max_y = min( Height - 1, starty + ystep - 1 );
else
ctxs[t].max_y = Height - 1;
waithandles[t]= CreateSimpleThread( SSBumpCalculationThreadFN, ( SSBumpCalculationContext * ) & ctxs[t] );
starty += ystep;
}
for(int t=0;t<nthreads;t++)
{
ThreadJoin( waithandles[t] );
}
if ( nOptionFlags & SSBUMP_MOD2X_DETAIL_TEXTURE )
{
const float flOutputScale = 0.5 * ( 1.0 / .57735026 ); // normalize so that a flat normal yields 0.5
// scale output weights by color channel
for( int nY = 0; nY < Height; nY++ )
for( int nX = 0; nX < Width; nX++ )
{
float flScale = flOutputScale * (2.0/3.0) * ( Pixel( nX, nY, 0 ) + Pixel( nX, nY, 1 ) + Pixel( nX, nY, 2 ) );
ret->Pixel( nX, nY, 0 ) *= flScale;
ret->Pixel( nX, nY, 1 ) *= flScale;
ret->Pixel( nX, nY, 2 ) *= flScale;
}
}
delete[] verts;
delete[] trace_directions;
delete[] normals;
return ret; // destructor will clean up rtenv
}
// generate a conventional normal map from a source with height stored in alpha.
FloatBitMap_t *FloatBitMap_t::ComputeBumpmapFromHeightInAlphaChannel( float bump_scale ) const
{
Vector *verts;
Vector *normals;
ComputeVertexPositionsAndNormals( bump_scale, &verts, &normals );
FloatBitMap_t *ret=new FloatBitMap_t( Width, Height );
for( int y = 0; y < Height; y++ )
for( int x = 0; x < Width; x++ )
{
Vector const & N = normals[ x + y * Width ];
ret->Pixel( x, y, 0 ) = 0.5+ 0.5 * N.x;
ret->Pixel( x, y, 1 ) = 0.5+ 0.5 * N.y;
ret->Pixel( x, y, 2 ) = 0.5+ 0.5 * N.z;
ret->Pixel( x, y, 3 ) = Pixel( x, y, 3 );
}
return ret;
}

View File

@ -0,0 +1,95 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <tier0/platform.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "bitmap/float_bm.h"
#include <tier2/tier2.h>
#include "tier0/threadtools.h"
#include "tier0/progressbar.h"
struct TBFCalculationContext
{
int min_y,max_y; // range to calculate in this thread
int thread_number;
int radius_in_pixels;
float edge_threshold_value;
FloatBitMap_t const *orig_bm;
FloatBitMap_t *dest_bm;
};
static unsigned TBFCalculationThreadFN( void *ctx1 )
{
TBFCalculationContext *ctx = (TBFCalculationContext *) ctx1;
for(int y=ctx->min_y; y <= ctx->max_y; y++)
{
if ( ctx->thread_number == 0 )
ReportProgress("Performing bilateral filter",(1+ctx->max_y-ctx->min_y),
y-ctx->min_y);
for(int x=0; x < ctx->dest_bm->Width; x++)
for(int c=0;c<4;c++)
{
float sum_weights=0;
float filter_sum=0;
float centerp=ctx->orig_bm->Pixel(x,y,c);
for(int iy=-ctx->radius_in_pixels; iy <= ctx->radius_in_pixels; iy++)
for(int ix=-ctx->radius_in_pixels; ix <= ctx->radius_in_pixels; ix++)
{
float this_p=ctx->orig_bm->PixelWrapped(x+ix,y+iy,c);
// caluclate the g() term. We use a gaussian
float exp1=(ix*ix+iy*iy)*(1.0/(2.0*ctx->radius_in_pixels*.033));
float g=exp(-exp1);
// calculate the "similarity" term. We use a triangle filter
float s=1.0;
float cdiff=fabs(centerp-this_p);
s= (cdiff>ctx->edge_threshold_value)?0:
FLerp(1,0,0,ctx->edge_threshold_value,cdiff);
sum_weights += s*g;
filter_sum += s*g*this_p;
}
ctx->dest_bm->Pixel(x,y,c)=filter_sum/sum_weights;
}
}
return 0;
}
void FloatBitMap_t::TileableBilateralFilter( int radius_in_pixels,
float edge_threshold_value )
{
FloatBitMap_t orig( this ); // need a copy for the source
TBFCalculationContext ctxs[32];
ctxs[0].radius_in_pixels = radius_in_pixels;
ctxs[0].edge_threshold_value = edge_threshold_value;
ctxs[0].orig_bm = &orig;
ctxs[0].dest_bm = this;
int nthreads = min( 32, (int)GetCPUInformation()->m_nPhysicalProcessors );
ThreadHandle_t waithandles[32];
int starty=0;
int ystep=Height/nthreads;
for(int t=0;t<nthreads;t++)
{
if (t)
ctxs[t]=ctxs[0];
ctxs[t].thread_number=t;
ctxs[t].min_y=starty;
if (t != nthreads-1)
ctxs[t].max_y=min(Height-1,starty+ystep-1);
else
ctxs[t].max_y=Height-1;
waithandles[t]=CreateSimpleThread(TBFCalculationThreadFN, &ctxs[t]);
starty+=ystep;
}
for(int t=0;t<nthreads;t++)
{
ThreadJoin( waithandles[t] );
}
}

119
bitmap/float_cube.cpp Normal file
View File

@ -0,0 +1,119 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#include <tier0/platform.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "bitmap/float_bm.h"
#include <filesystem.h>
#include <mathlib/vector.h>
static Vector face_xvector[6]={ // direction of x pixels on face
Vector(-1,0,0), // back
Vector(1,0,0), // down
Vector(1,0,0), // front
Vector(0,1,0), // left
Vector(0,-1,0), // right
Vector(1,0,0) // up
};
static Vector face_yvector[6]={ // direction of y pixels on face
Vector(0,0,-1), // back
Vector(0,1,0), // down
Vector(0,0,-1), // front
Vector(0,0,-1), // left
Vector(0,0,-1), // right
Vector(0,-1,0) // up
};
static Vector face_zvector[6]={
Vector(1,1,1), // back
Vector(-1,-1,-1), // down
Vector(-1,-1,1), // front
Vector(1,-1,1), // left
Vector(-1,1,1), // right
Vector(-1,1,1) // up
};
static char const *namepts[6]={"%sbk.pfm","%sdn.pfm","%sft.pfm","%slf.pfm","%srt.pfm","%sup.pfm"};
FloatCubeMap_t::FloatCubeMap_t(char const *basename)
{
for(int f=0;f<6;f++)
{
char fnamebuf[512];
sprintf(fnamebuf,namepts[f],basename);
face_maps[f].LoadFromPFM(fnamebuf);
}
}
void FloatCubeMap_t::WritePFMs(char const *basename)
{
for(int f=0;f<6;f++)
{
char fnamebuf[512];
sprintf(fnamebuf,namepts[f],basename);
face_maps[f].WritePFM(fnamebuf);
}
}
Vector FloatCubeMap_t::PixelDirection(int face, int x, int y)
{
FloatBitMap_t const &bm=face_maps[face];
float xc=x*1.0/(bm.Width-1);
float yc=y*1.0/(bm.Height-1);
Vector dir=2*xc*face_xvector[face]+
2*yc*face_yvector[face]+face_zvector[face];
VectorNormalize(dir);
return dir;
}
Vector FloatCubeMap_t::FaceNormal(int face)
{
float xc=0.5;
float yc=0.5;
Vector dir=2*xc*face_xvector[face]+
2*yc*face_yvector[face]+face_zvector[face];
VectorNormalize(dir);
return dir;
}
void FloatCubeMap_t::Resample( FloatCubeMap_t &out, float flPhongExponent )
{
// terribly slow brute force algorithm just so I can try it out
for(int dface=0;dface<6;dface++)
{
for(int dy=0;dy<out.face_maps[dface].Height;dy++)
for(int dx=0;dx<out.face_maps[dface].Width;dx++)
{
float sum_weights=0;
float sum_rgb[3]={0,0,0};
for(int sface=0;sface<6;sface++)
{
// easy 15% optimization - check if faces point away from each other
if (DotProduct(FaceNormal(sface),FaceNormal(sface))>-0.9)
{
Vector ddir=out.PixelDirection(dface,dx,dy);
for(int sy=0;sy<face_maps[sface].Height;sy++)
for(int sx=0;sx<face_maps[sface].Width;sx++)
{
float dp=DotProduct(ddir,PixelDirection(sface,sx,sy));
if (dp>0.0)
{
dp=pow( dp, flPhongExponent );
sum_weights += dp;
for(int c=0;c<3;c++)
sum_rgb[c] += dp*face_maps[sface].Pixel( sx, sy, c );
}
}
}
}
for(int c=0;c<3;c++)
out.face_maps[dface].Pixel( dx, dy, c )=sum_rgb[c]*(1.0/sum_weights);
}
}
}

526
bitmap/imageformat.cpp Normal file
View File

@ -0,0 +1,526 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#if defined( _WIN32 ) && !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION )
#include <windows.h>
#include "../dx9sdk/include/d3d9types.h"
#endif
#include "bitmap/imageformat.h"
#include "basetypes.h"
#include "tier0/dbg.h"
#include <malloc.h>
#include <memory.h>
#include "nvtc.h"
#include "mathlib/mathlib.h"
#include "mathlib/vector.h"
#include "tier1/utlmemory.h"
#include "tier1/strtools.h"
#include "mathlib/compressed_vector.h"
// Should be last include
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Various important function types for each color format
//-----------------------------------------------------------------------------
static const ImageFormatInfo_t g_ImageFormatInfo[] =
{
{ "UNKNOWN", 0, 0, 0, 0, 0, false }, // IMAGE_FORMAT_UNKNOWN,
{ "RGBA8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_RGBA8888,
{ "ABGR8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_ABGR8888,
{ "RGB888", 3, 8, 8, 8, 0, false }, // IMAGE_FORMAT_RGB888,
{ "BGR888", 3, 8, 8, 8, 0, false }, // IMAGE_FORMAT_BGR888,
{ "RGB565", 2, 5, 6, 5, 0, false }, // IMAGE_FORMAT_RGB565,
{ "I8", 1, 0, 0, 0, 0, false }, // IMAGE_FORMAT_I8,
{ "IA88", 2, 0, 0, 0, 8, false }, // IMAGE_FORMAT_IA88
{ "P8", 1, 0, 0, 0, 0, false }, // IMAGE_FORMAT_P8
{ "A8", 1, 0, 0, 0, 8, false }, // IMAGE_FORMAT_A8
{ "RGB888_BLUESCREEN", 3, 8, 8, 8, 0, false }, // IMAGE_FORMAT_RGB888_BLUESCREEN
{ "BGR888_BLUESCREEN", 3, 8, 8, 8, 0, false }, // IMAGE_FORMAT_BGR888_BLUESCREEN
{ "ARGB8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_ARGB8888
{ "BGRA8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_BGRA8888
{ "DXT1", 0, 0, 0, 0, 0, true }, // IMAGE_FORMAT_DXT1
{ "DXT3", 0, 0, 0, 0, 8, true }, // IMAGE_FORMAT_DXT3
{ "DXT5", 0, 0, 0, 0, 8, true }, // IMAGE_FORMAT_DXT5
{ "BGRX8888", 4, 8, 8, 8, 0, false }, // IMAGE_FORMAT_BGRX8888
{ "BGR565", 2, 5, 6, 5, 0, false }, // IMAGE_FORMAT_BGR565
{ "BGRX5551", 2, 5, 5, 5, 0, false }, // IMAGE_FORMAT_BGRX5551
{ "BGRA4444", 2, 4, 4, 4, 4, false }, // IMAGE_FORMAT_BGRA4444
{ "DXT1_ONEBITALPHA", 0, 0, 0, 0, 0, true }, // IMAGE_FORMAT_DXT1_ONEBITALPHA
{ "BGRA5551", 2, 5, 5, 5, 1, false }, // IMAGE_FORMAT_BGRA5551
{ "UV88", 2, 8, 8, 0, 0, false }, // IMAGE_FORMAT_UV88
{ "UVWQ8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_UVWQ8899
{ "RGBA16161616F", 8, 16, 16, 16, 16, false }, // IMAGE_FORMAT_RGBA16161616F
{ "RGBA16161616", 8, 16, 16, 16, 16, false }, // IMAGE_FORMAT_RGBA16161616
{ "IMAGE_FORMAT_UVLX8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_UVLX8899
{ "IMAGE_FORMAT_R32F", 4, 32, 0, 0, 0, false }, // IMAGE_FORMAT_R32F
{ "IMAGE_FORMAT_RGB323232F", 12, 32, 32, 32, 0, false }, // IMAGE_FORMAT_RGB323232F
{ "IMAGE_FORMAT_RGBA32323232F", 16, 32, 32, 32, 32, false }, // IMAGE_FORMAT_RGBA32323232F
// Vendor-dependent depth formats used for shadow depth mapping
{ "NV_DST16", 2, 16, 0, 0, 0, false }, // IMAGE_FORMAT_NV_DST16
{ "NV_DST24", 4, 24, 0, 0, 0, false }, // IMAGE_FORMAT_NV_DST24
{ "NV_INTZ", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_NV_INTZ
{ "NV_RAWZ", 4, 24, 0, 0, 0, false }, // IMAGE_FORMAT_NV_RAWZ
{ "ATI_DST16", 2, 16, 0, 0, 0, false }, // IMAGE_FORMAT_ATI_DST16
{ "ATI_DST24", 4, 24, 0, 0, 0, false }, // IMAGE_FORMAT_ATI_DST24
{ "NV_NULL", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_NV_NULL
// Vendor-dependent compressed formats typically used for normal map compression
{ "ATI1N", 0, 0, 0, 0, 0, true }, // IMAGE_FORMAT_ATI1N
{ "ATI2N", 0, 0, 0, 0, 0, true }, // IMAGE_FORMAT_ATI2N
#ifdef _X360
{ "X360_DST16", 2, 16, 0, 0, 0, false }, // IMAGE_FORMAT_X360_DST16
{ "X360_DST24", 4, 24, 0, 0, 0, false }, // IMAGE_FORMAT_X360_DST24
{ "X360_DST24F", 4, 24, 0, 0, 0, false }, // IMAGE_FORMAT_X360_DST24F
{ "LINEAR_BGRX8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_LINEAR_BGRX8888
{ "LINEAR_RGBA8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_LINEAR_RGBA8888
{ "LINEAR_ABGR8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_LINEAR_ABGR8888
{ "LINEAR_ARGB8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_LINEAR_ARGB8888
{ "LINEAR_BGRA8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_LINEAR_BGRA8888
{ "LINEAR_RGB888", 3, 8, 8, 8, 0, false }, // IMAGE_FORMAT_LINEAR_RGB888
{ "LINEAR_BGR888", 3, 8, 8, 8, 0, false }, // IMAGE_FORMAT_LINEAR_BGR888
{ "LINEAR_BGRX5551", 2, 5, 5, 5, 0, false }, // IMAGE_FORMAT_LINEAR_BGRX5551
{ "LINEAR_I8", 1, 0, 0, 0, 0, false }, // IMAGE_FORMAT_LINEAR_I8
{ "LINEAR_RGBA16161616", 8, 16, 16, 16, 16, false }, // IMAGE_FORMAT_LINEAR_RGBA16161616
{ "LE_BGRX8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_LE_BGRX8888
{ "LE_BGRA8888", 4, 8, 8, 8, 8, false }, // IMAGE_FORMAT_LE_BGRA8888
#endif
{ "DXT1_RUNTIME", 0, 0, 0, 0, 0, true, }, // IMAGE_FORMAT_DXT1_RUNTIME
{ "DXT5_RUNTIME", 0, 0, 0, 0, 8, true, }, // IMAGE_FORMAT_DXT5_RUNTIME
};
namespace ImageLoader
{
//-----------------------------------------------------------------------------
// Returns info about each image format
//-----------------------------------------------------------------------------
const ImageFormatInfo_t& ImageFormatInfo( ImageFormat fmt )
{
Assert( ( NUM_IMAGE_FORMATS + 1 ) == sizeof( g_ImageFormatInfo ) / sizeof( g_ImageFormatInfo[0] ) );
Assert( unsigned( fmt + 1 ) <= ( NUM_IMAGE_FORMATS ) );
return g_ImageFormatInfo[ fmt + 1 ];
}
int GetMemRequired( int width, int height, int depth, ImageFormat imageFormat, bool mipmap )
{
if ( depth <= 0 )
{
depth = 1;
}
if ( !mipmap )
{
// Block compressed formats
if ( IsCompressed( imageFormat ) )
{
/*
DDSURFACEDESC desc;
memset( &desc, 0, sizeof(desc) );
DWORD dwEncodeType;
dwEncodeType = GetDXTCEncodeType( imageFormat );
desc.dwSize = sizeof( desc );
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
desc.dwWidth = width;
desc.dwHeight = height;
return S3TCgetEncodeSize( &desc, dwEncodeType );
*/
Assert( ( width < 4 ) || !( width % 4 ) );
Assert( ( height < 4 ) || !( height % 4 ) );
Assert( ( depth < 4 ) || !( depth % 4 ) );
if ( width < 4 && width > 0 )
{
width = 4;
}
if ( height < 4 && height > 0 )
{
height = 4;
}
if ( depth < 4 && depth > 1 )
{
depth = 4;
}
int numBlocks = ( width * height ) >> 4;
numBlocks *= depth;
switch ( imageFormat )
{
case IMAGE_FORMAT_DXT1:
case IMAGE_FORMAT_DXT1_RUNTIME:
case IMAGE_FORMAT_ATI1N:
return numBlocks * 8;
case IMAGE_FORMAT_DXT3:
case IMAGE_FORMAT_DXT5:
case IMAGE_FORMAT_DXT5_RUNTIME:
case IMAGE_FORMAT_ATI2N:
return numBlocks * 16;
}
Assert( 0 );
return 0;
}
return width * height * depth * SizeInBytes( imageFormat );
}
// Mipmap version
int memSize = 0;
while ( 1 )
{
memSize += GetMemRequired( width, height, depth, imageFormat, false );
if ( width == 1 && height == 1 && depth == 1 )
{
break;
}
width >>= 1;
height >>= 1;
depth >>= 1;
if ( width < 1 )
{
width = 1;
}
if ( height < 1 )
{
height = 1;
}
if ( depth < 1 )
{
depth = 1;
}
}
return memSize;
}
int GetMipMapLevelByteOffset( int width, int height, ImageFormat imageFormat, int skipMipLevels )
{
int offset = 0;
while( skipMipLevels > 0 )
{
offset += width * height * SizeInBytes(imageFormat);
if( width == 1 && height == 1 )
{
break;
}
width >>= 1;
height >>= 1;
if( width < 1 )
{
width = 1;
}
if( height < 1 )
{
height = 1;
}
skipMipLevels--;
}
return offset;
}
void GetMipMapLevelDimensions( int *width, int *height, int skipMipLevels )
{
while( skipMipLevels > 0 )
{
if( *width == 1 && *height == 1 )
{
break;
}
*width >>= 1;
*height >>= 1;
if( *width < 1 )
{
*width = 1;
}
if( *height < 1 )
{
*height = 1;
}
skipMipLevels--;
}
}
int GetNumMipMapLevels( int width, int height, int depth )
{
if ( depth <= 0 )
{
depth = 1;
}
if( width < 1 || height < 1 || depth < 1 )
return 0;
int numMipLevels = 1;
while( 1 )
{
if( width == 1 && height == 1 && depth == 1 )
break;
width >>= 1;
height >>= 1;
depth >>= 1;
if( width < 1 )
{
width = 1;
}
if( height < 1 )
{
height = 1;
}
if( depth < 1 )
{
depth = 1;
}
numMipLevels++;
}
return numMipLevels;
}
// Turn off warning about FOURCC formats below...
#pragma warning (disable:4063)
#ifdef DX_TO_GL_ABSTRACTION
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
#endif //defined(MAKEFOURCC)
#endif
//-----------------------------------------------------------------------------
// convert back and forth from D3D format to ImageFormat, regardless of
// whether it's supported or not
//-----------------------------------------------------------------------------
ImageFormat D3DFormatToImageFormat( D3DFORMAT format )
{
#if defined( _X360 )
if ( IS_D3DFORMAT_SRGB( format ) )
{
// sanitize the format from possible sRGB state for comparison purposes
format = MAKE_NON_SRGB_FMT( format );
}
#endif
switch ( format )
{
#if !defined( _X360 )
case D3DFMT_R8G8B8:
return IMAGE_FORMAT_BGR888;
#endif
case D3DFMT_A8R8G8B8:
return IMAGE_FORMAT_BGRA8888;
case D3DFMT_X8R8G8B8:
return IMAGE_FORMAT_BGRX8888;
case D3DFMT_R5G6B5:
return IMAGE_FORMAT_BGR565;
case D3DFMT_X1R5G5B5:
return IMAGE_FORMAT_BGRX5551;
case D3DFMT_A1R5G5B5:
return IMAGE_FORMAT_BGRA5551;
case D3DFMT_A4R4G4B4:
return IMAGE_FORMAT_BGRA4444;
case D3DFMT_L8:
return IMAGE_FORMAT_I8;
case D3DFMT_A8L8:
return IMAGE_FORMAT_IA88;
case D3DFMT_A8:
return IMAGE_FORMAT_A8;
case D3DFMT_DXT1:
return IMAGE_FORMAT_DXT1;
case D3DFMT_DXT3:
return IMAGE_FORMAT_DXT3;
case D3DFMT_DXT5:
return IMAGE_FORMAT_DXT5;
case D3DFMT_V8U8:
return IMAGE_FORMAT_UV88;
case D3DFMT_Q8W8V8U8:
return IMAGE_FORMAT_UVWQ8888;
case D3DFMT_X8L8V8U8:
return IMAGE_FORMAT_UVLX8888;
case D3DFMT_A16B16G16R16F:
return IMAGE_FORMAT_RGBA16161616F;
case D3DFMT_A16B16G16R16:
return IMAGE_FORMAT_RGBA16161616;
case D3DFMT_R32F:
return IMAGE_FORMAT_R32F;
case D3DFMT_A32B32G32R32F:
return IMAGE_FORMAT_RGBA32323232F;
// DST and FOURCC formats mapped back to ImageFormat (for vendor-dependent shadow depth textures)
case (D3DFORMAT)(MAKEFOURCC('R','A','W','Z')):
return IMAGE_FORMAT_NV_RAWZ;
case (D3DFORMAT)(MAKEFOURCC('I','N','T','Z')):
return IMAGE_FORMAT_NV_INTZ;
case (D3DFORMAT)(MAKEFOURCC('N','U','L','L')):
return IMAGE_FORMAT_NV_NULL;
case D3DFMT_D16:
#if !defined( _X360 )
return IMAGE_FORMAT_NV_DST16;
#else
return IMAGE_FORMAT_X360_DST16;
#endif
case D3DFMT_D24S8:
#if !defined( _X360 )
return IMAGE_FORMAT_NV_DST24;
#else
return IMAGE_FORMAT_X360_DST24;
#endif
case (D3DFORMAT)(MAKEFOURCC('D','F','1','6')):
return IMAGE_FORMAT_ATI_DST16;
case (D3DFORMAT)(MAKEFOURCC('D','F','2','4')):
return IMAGE_FORMAT_ATI_DST24;
// ATIxN FOURCC formats mapped back to ImageFormat
case (D3DFORMAT)(MAKEFOURCC('A','T','I','1')):
return IMAGE_FORMAT_ATI1N;
case (D3DFORMAT)(MAKEFOURCC('A','T','I','2')):
return IMAGE_FORMAT_ATI2N;
#if defined( _X360 )
case D3DFMT_LIN_A8R8G8B8:
return IMAGE_FORMAT_LINEAR_BGRA8888;
case D3DFMT_LIN_X8R8G8B8:
return IMAGE_FORMAT_LINEAR_BGRX8888;
case D3DFMT_LIN_X1R5G5B5:
return IMAGE_FORMAT_LINEAR_BGRX5551;
case D3DFMT_LIN_L8:
return IMAGE_FORMAT_LINEAR_I8;
case D3DFMT_LIN_A16B16G16R16:
return IMAGE_FORMAT_LINEAR_RGBA16161616;
case D3DFMT_LE_X8R8G8B8:
return IMAGE_FORMAT_LE_BGRX8888;
case D3DFMT_LE_A8R8G8B8:
return IMAGE_FORMAT_LE_BGRA8888;
case D3DFMT_D24FS8:
return IMAGE_FORMAT_X360_DST24F;
#endif
}
Assert( 0 );
return IMAGE_FORMAT_UNKNOWN;
}
D3DFORMAT ImageFormatToD3DFormat( ImageFormat format )
{
// This doesn't care whether it's supported or not
switch ( format )
{
case IMAGE_FORMAT_BGR888:
#if !defined( _X360 )
return D3DFMT_R8G8B8;
#else
return D3DFMT_UNKNOWN;
#endif
case IMAGE_FORMAT_BGRA8888:
return D3DFMT_A8R8G8B8;
case IMAGE_FORMAT_BGRX8888:
return D3DFMT_X8R8G8B8;
case IMAGE_FORMAT_BGR565:
return D3DFMT_R5G6B5;
case IMAGE_FORMAT_BGRX5551:
return D3DFMT_X1R5G5B5;
case IMAGE_FORMAT_BGRA5551:
return D3DFMT_A1R5G5B5;
case IMAGE_FORMAT_BGRA4444:
return D3DFMT_A4R4G4B4;
case IMAGE_FORMAT_I8:
return D3DFMT_L8;
case IMAGE_FORMAT_IA88:
return D3DFMT_A8L8;
case IMAGE_FORMAT_A8:
return D3DFMT_A8;
case IMAGE_FORMAT_DXT1:
case IMAGE_FORMAT_DXT1_ONEBITALPHA:
return D3DFMT_DXT1;
case IMAGE_FORMAT_DXT3:
return D3DFMT_DXT3;
case IMAGE_FORMAT_DXT5:
return D3DFMT_DXT5;
case IMAGE_FORMAT_UV88:
return D3DFMT_V8U8;
case IMAGE_FORMAT_UVWQ8888:
return D3DFMT_Q8W8V8U8;
case IMAGE_FORMAT_UVLX8888:
return D3DFMT_X8L8V8U8;
case IMAGE_FORMAT_RGBA16161616F:
return D3DFMT_A16B16G16R16F;
case IMAGE_FORMAT_RGBA16161616:
return D3DFMT_A16B16G16R16;
case IMAGE_FORMAT_R32F:
return D3DFMT_R32F;
case IMAGE_FORMAT_RGBA32323232F:
return D3DFMT_A32B32G32R32F;
// ImageFormat mapped to vendor-dependent FOURCC formats (for shadow depth textures)
case IMAGE_FORMAT_NV_RAWZ:
return (D3DFORMAT)(MAKEFOURCC('R','A','W','Z'));
case IMAGE_FORMAT_NV_INTZ:
return (D3DFORMAT)(MAKEFOURCC('I','N','T','Z'));
case IMAGE_FORMAT_NV_NULL:
return (D3DFORMAT)(MAKEFOURCC('N','U','L','L'));
case IMAGE_FORMAT_NV_DST16:
return D3DFMT_D16;
case IMAGE_FORMAT_NV_DST24:
return D3DFMT_D24S8;
case IMAGE_FORMAT_ATI_DST16:
return (D3DFORMAT)(MAKEFOURCC('D','F','1','6'));
case IMAGE_FORMAT_ATI_DST24:
return (D3DFORMAT)(MAKEFOURCC('D','F','2','4'));
// ImageFormats mapped to ATIxN FOURCC
case IMAGE_FORMAT_ATI1N:
return (D3DFORMAT)(MAKEFOURCC('A','T','I','1'));
case IMAGE_FORMAT_ATI2N:
return (D3DFORMAT)(MAKEFOURCC('A','T','I','2'));
#if defined( _X360 )
case IMAGE_FORMAT_LINEAR_BGRA8888:
return D3DFMT_LIN_A8R8G8B8;
case IMAGE_FORMAT_LINEAR_BGRX8888:
return D3DFMT_LIN_X8R8G8B8;
case IMAGE_FORMAT_LINEAR_BGRX5551:
return D3DFMT_LIN_X1R5G5B5;
case IMAGE_FORMAT_LINEAR_I8:
return D3DFMT_LIN_L8;
case IMAGE_FORMAT_LINEAR_RGBA16161616:
return D3DFMT_LIN_A16B16G16R16;
case IMAGE_FORMAT_LE_BGRX8888:
return D3DFMT_LE_X8R8G8B8;
case IMAGE_FORMAT_LE_BGRA8888:
return D3DFMT_LE_A8R8G8B8;
case IMAGE_FORMAT_X360_DST16:
return D3DFMT_D16;
case IMAGE_FORMAT_X360_DST24:
return D3DFMT_D24S8;
case IMAGE_FORMAT_X360_DST24F:
return D3DFMT_D24FS8;
#endif
case IMAGE_FORMAT_DXT1_RUNTIME:
return D3DFMT_DXT1;
case IMAGE_FORMAT_DXT5_RUNTIME:
return D3DFMT_DXT5;
}
Assert( 0 );
return D3DFMT_UNKNOWN;
}
#pragma warning (default:4063)
} // ImageLoader namespace ends

571
bitmap/psd.cpp Normal file
View File

@ -0,0 +1,571 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include "bitmap/psd.h"
#include "tier0/dbg.h"
#include "tier1/utlbuffer.h"
#include "filesystem.h"
#include "tier2/tier2.h"
#include "tier2/utlstreambuffer.h"
#include "bitmap/imageformat.h"
#include "bitmap/bitmap.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// The PSD signature bytes
//-----------------------------------------------------------------------------
#define PSD_SIGNATURE 0x38425053
#define PSD_IMGRES_SIGNATURE 0x3842494D
//-----------------------------------------------------------------------------
// Format of the PSD header on disk
// NOTE: PSD file header, everything is bigendian
//-----------------------------------------------------------------------------
#pragma pack (1)
enum PSDMode_t
{
MODE_GREYSCALE = 1,
MODE_PALETTIZED = 2,
MODE_RGBA = 3,
MODE_CMYK = 4,
MODE_MULTICHANNEL = 7,
MODE_LAB = 9,
MODE_COUNT = 10,
};
//////////////////////////////////////////////////////////////////////////
//
// BEGIN PSD FILE:
//
// PSDHeader_t
// unsigned int numBytesPalette;
// byte palette[ numBytesPalette ]; = { (all red palette entries), (all green palette entries), (all blue palette entries) }, where numEntries = numBytesPalette/3;
// unsigned int numBytesImgResources;
// byte imgresources[ numBytesImgResources ]; = { sequence of PSDImgResEntry_t }
// unsigned int numBytesLayers;
// byte layers[ numBytesLayers ];
// unsigned short uCompressionInfo;
// < ~ image data ~ >
//
// END PSD FILE
//
//////////////////////////////////////////////////////////////////////////
struct PSDHeader_t
{
unsigned int m_nSignature;
unsigned short m_nVersion;
unsigned char m_pReserved[6];
unsigned short m_nChannels;
unsigned int m_nRows;
unsigned int m_nColumns;
unsigned short m_nDepth;
unsigned short m_nMode;
};
struct PSDPalette_t
{
unsigned char *m_pRed;
unsigned char *m_pGreen;
unsigned char *m_pBlue;
};
//-----------------------------------------------------------------------------
// NOTE: This is how we could load files using file mapping
//-----------------------------------------------------------------------------
//HANDLE File = CreateFile(FileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
//Assert(File != INVALID_HANDLE_VALUE);
//HANDLE FileMap = CreateFileMapping(File,0,PAGE_READONLY,0,0,0);
//Assert(FileMap != INVALID_HANDLE_VALUE);
//void *FileData = MapViewOfFile(FileMap,FILE_MAP_READ,0,0,0);
//-----------------------------------------------------------------------------
// Is it a PSD file?
//-----------------------------------------------------------------------------
bool IsPSDFile( CUtlBuffer &buf )
{
int nGet = buf.TellGet();
PSDHeader_t header;
buf.Get( &header, sizeof(header) );
buf.SeekGet( CUtlBuffer::SEEK_HEAD, nGet );
if ( BigLong( header.m_nSignature ) != PSD_SIGNATURE )
return false;
if ( BigShort( header.m_nVersion ) != 1 )
return false;
return ( BigShort( header.m_nDepth ) == 8 );
}
bool IsPSDFile( const char *pFileName, const char *pPathID )
{
CUtlBuffer buf;
if ( !g_pFullFileSystem->ReadFile( pFileName, pPathID, buf, sizeof(PSDHeader_t) ) )
{
Warning( "Unable to read file %s\n", pFileName );
return false;
}
return IsPSDFile( buf );
}
//-----------------------------------------------------------------------------
// Returns information about the PSD file
//-----------------------------------------------------------------------------
bool PSDGetInfo( CUtlBuffer &buf, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma )
{
int nGet = buf.TellGet();
PSDHeader_t header;
buf.Get( &header, sizeof(header) );
buf.SeekGet( CUtlBuffer::SEEK_HEAD, nGet );
if ( BigLong( header.m_nSignature ) != PSD_SIGNATURE )
return false;
if ( BigShort( header.m_nVersion ) != 1 )
return false;
if ( BigShort( header.m_nDepth ) != 8 )
return false;
*pWidth = BigLong( header.m_nColumns );
*pHeight = BigLong( header.m_nRows );
*pImageFormat = BigShort( header.m_nChannels ) == 3 ? IMAGE_FORMAT_RGB888 : IMAGE_FORMAT_RGBA8888;
*pSourceGamma = ARTWORK_GAMMA;
return true;
}
bool PSDGetInfo( const char *pFileName, const char *pPathID, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma )
{
CUtlBuffer buf;
if ( !g_pFullFileSystem->ReadFile( pFileName, pPathID, buf, sizeof(PSDHeader_t) ) )
{
Warning( "Unable to read file %s\n", pFileName );
return false;
}
return PSDGetInfo( buf, pWidth, pHeight, pImageFormat, pSourceGamma );
}
//-----------------------------------------------------------------------------
// Get PSD file image resources
//-----------------------------------------------------------------------------
PSDImageResources PSDGetImageResources( CUtlBuffer &buf )
{
int nGet = buf.TellGet();
// Header
PSDHeader_t header;
buf.Get( &header, sizeof( header ) );
// Then palette
unsigned int numBytesPalette = BigLong( buf.GetUnsignedInt() );
buf.SeekGet( CUtlBuffer::SEEK_CURRENT, numBytesPalette );
// Then image resources
unsigned int numBytesImgResources = BigLong( buf.GetUnsignedInt() );
PSDImageResources imgres( numBytesImgResources, ( unsigned char * ) buf.PeekGet() );
// Restore the seek
buf.SeekGet( CUtlBuffer::SEEK_HEAD, nGet );
return imgres;
}
//-----------------------------------------------------------------------------
// Converts from CMYK to RGB
//-----------------------------------------------------------------------------
static inline void CMYKToRGB( RGBA8888_t &color )
{
unsigned char nCyan = 255 - color.r;
unsigned char nMagenta = 255 - color.g;
unsigned char nYellow = 255 - color.b;
unsigned char nBlack = 255 - color.a;
int nCyanBlack = (int)nCyan + (int)nBlack;
int nMagentaBlack = (int)nMagenta + (int)nBlack;
int nYellowBlack = (int)nYellow + (int)nBlack;
color.r = ( nCyanBlack < 255 ) ? 255 - nCyanBlack : 0;
color.g = ( nMagentaBlack < 255 ) ? 255 - nMagentaBlack : 0;
color.b = ( nYellowBlack < 255 ) ? 255 - nYellowBlack : 0;
color.a = 255;
}
//-----------------------------------------------------------------------------
// Deals with uncompressed channels
//-----------------------------------------------------------------------------
static void PSDConvertToRGBA8888( int nChannelsCount, PSDMode_t mode, PSDPalette_t &palette, Bitmap_t &bitmap )
{
bool bShouldFillInAlpha = false;
unsigned char *pDest = bitmap.GetBits();
switch( mode )
{
case MODE_RGBA:
bShouldFillInAlpha = ( nChannelsCount == 3 );
break;
case MODE_PALETTIZED:
{
// Convert from palette
bShouldFillInAlpha = ( nChannelsCount == 1 );
for( int j=0; j < bitmap.Height(); ++j )
{
for ( int k = 0; k < bitmap.Width(); ++k, pDest += 4 )
{
unsigned char nPaletteIndex = pDest[0];
pDest[0] = palette.m_pRed[nPaletteIndex];
pDest[1] = palette.m_pGreen[nPaletteIndex];
pDest[2] = palette.m_pBlue[nPaletteIndex];
}
}
}
break;
case MODE_GREYSCALE:
{
// Monochrome
bShouldFillInAlpha = ( nChannelsCount == 1 );
for( int j=0; j < bitmap.Height(); ++j )
{
for ( int k = 0; k < bitmap.Width(); ++k, pDest += 4 )
{
pDest[1] = pDest[0];
pDest[2] = pDest[0];
}
}
}
break;
case MODE_CMYK:
{
// NOTE: The conversion will fill in alpha by default
bShouldFillInAlpha = false;
for( int j=0; j < bitmap.Height(); ++j )
{
for ( int k = 0; k < bitmap.Width(); ++k, pDest += 4 )
{
CMYKToRGB( *((RGBA8888_t*)pDest) );
}
}
}
break;
}
if ( bShouldFillInAlpha )
{
// No alpha channel, fill in white
unsigned char *pDestAlpha = bitmap.GetBits();
for( int j=0; j < bitmap.Height(); ++j )
{
for ( int k = 0; k < bitmap.Width(); ++k, pDestAlpha += 4 )
{
pDestAlpha[3] = 0xFF;
}
}
}
}
//-----------------------------------------------------------------------------
// Deals with uncompressed channels
//-----------------------------------------------------------------------------
static int s_pChannelIndex[MODE_COUNT+1][4] =
{
{ -1, -1, -1, -1 },
{ 0, 3, -1, -1 }, // MODE_GREYSCALE
{ 0, 3, -1, -1 }, // MODE_PALETTIZED
{ 0, 1, 2, 3 }, // MODE_RGBA
{ 0, 1, 2, 3 }, // MODE_CMYK
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, // MODE_MULTICHANNEL
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, // MODE_LAB
{ 3, -1, -1, -1 }, // Secret second pass mode for CMYK
};
static void PSDReadUncompressedChannels( CUtlBuffer &buf, int nChannelsCount, PSDMode_t mode, PSDPalette_t &palette, Bitmap_t &bitmap )
{
unsigned char *pChannelRow = (unsigned char*)_alloca( bitmap.Width() );
for ( int i=0; i<nChannelsCount; ++i )
{
int nIndex = s_pChannelIndex[mode][i];
Assert( nIndex != -1 );
unsigned char *pDest = bitmap.GetBits();
for( int j=0; j < bitmap.Height(); ++j )
{
buf.Get( pChannelRow, bitmap.Width() );
// Collate the channels together
for ( int k = 0; k < bitmap.Width(); ++k, pDest += 4 )
{
pDest[nIndex] = pChannelRow[k];
}
}
}
PSDConvertToRGBA8888( nChannelsCount, mode, palette, bitmap );
}
//-----------------------------------------------------------------------------
// Deals with compressed channels
//-----------------------------------------------------------------------------
static void PSDReadCompressedChannels( CUtlBuffer &buf, int nChannelsCount, PSDMode_t mode, PSDPalette_t &palette, Bitmap_t &bitmap )
{
unsigned char *pChannelRow = (unsigned char*)_alloca( bitmap.Width() );
for ( int i=0; i<nChannelsCount; ++i )
{
int nIndex = s_pChannelIndex[mode][i];
Assert( nIndex != -1 );
unsigned char *pDest = bitmap.GetBits();
for( int j=0; j < bitmap.Height(); ++j )
{
unsigned char *pSrc = pChannelRow;
unsigned int nPixelsRemaining = bitmap.Width();
while ( nPixelsRemaining > 0 )
{
int nCount = buf.GetChar();
if ( nCount >= 0 )
{
// If nCount is between 0 + 7F, it means copy the next nCount+1 bytes directly
++nCount;
Assert( (unsigned int)nCount <= nPixelsRemaining );
buf.Get( pSrc, nCount );
}
else
{
// If nCount is between 80 and FF, it means replicate the next byte -Count+1 times
nCount = -nCount + 1;
Assert( (unsigned int)nCount <= nPixelsRemaining );
unsigned char nPattern = buf.GetUnsignedChar();
memset( pSrc, nPattern, nCount );
}
pSrc += nCount;
nPixelsRemaining -= nCount;
}
Assert( nPixelsRemaining == 0 );
// Collate the channels together
for ( int k = 0; k < bitmap.Width(); ++k, pDest += 4 )
{
pDest[nIndex] = pChannelRow[k];
}
}
}
PSDConvertToRGBA8888( nChannelsCount, mode, palette, bitmap );
}
//-----------------------------------------------------------------------------
// Reads the PSD file into the specified buffer
//-----------------------------------------------------------------------------
bool PSDReadFileRGBA8888( CUtlBuffer &buf, Bitmap_t &bitmap )
{
PSDHeader_t header;
buf.Get( &header, sizeof(header) );
if ( BigLong( header.m_nSignature ) != PSD_SIGNATURE )
return false;
if ( BigShort( header.m_nVersion ) != 1 )
return false;
if ( BigShort( header.m_nDepth ) != 8 )
return false;
PSDMode_t mode = (PSDMode_t)BigShort( header.m_nMode );
int nChannelsCount = BigShort( header.m_nChannels );
if ( mode == MODE_MULTICHANNEL || mode == MODE_LAB )
return false;
switch ( mode )
{
case MODE_RGBA:
if ( nChannelsCount < 3 )
return false;
break;
case MODE_GREYSCALE:
case MODE_PALETTIZED:
if ( nChannelsCount != 1 && nChannelsCount != 2 )
return false;
break;
case MODE_CMYK:
if ( nChannelsCount < 4 )
return false;
break;
default:
Warning( "Unsupported PSD color mode!\n" );
return false;
}
int nWidth = BigLong( header.m_nColumns );
int nHeight = BigLong( header.m_nRows );
// Skip parts of memory we don't care about
int nColorModeSize = BigLong( buf.GetUnsignedInt() );
Assert( nColorModeSize % 3 == 0 );
unsigned char *pPaletteBits = (unsigned char*)_alloca( nColorModeSize );
PSDPalette_t palette;
palette.m_pRed = palette.m_pGreen = palette.m_pBlue = 0;
if ( nColorModeSize )
{
int nPaletteSize = nColorModeSize / 3;
buf.Get( pPaletteBits, nColorModeSize );
palette.m_pRed = pPaletteBits;
palette.m_pGreen = palette.m_pRed + nPaletteSize;
palette.m_pBlue = palette.m_pGreen + nPaletteSize;
}
int nImageResourcesSize = BigLong( buf.GetUnsignedInt() );
buf.SeekGet( CUtlBuffer::SEEK_CURRENT, nImageResourcesSize );
int nLayersSize = BigLong( buf.GetUnsignedInt() );
buf.SeekGet( CUtlBuffer::SEEK_CURRENT, nLayersSize );
unsigned short nCompressionType = BigShort( buf.GetShort() );
bitmap.Init( nWidth, nHeight, IMAGE_FORMAT_RGBA8888 );
bool bSecondPassCMYKA = ( nChannelsCount > 4 && mode == MODE_CMYK );
if ( nCompressionType == 0 )
{
PSDReadUncompressedChannels( buf, ( nChannelsCount > 4 ) ? 4 : nChannelsCount, mode, palette, bitmap );
}
else
{
// Skip the data that indicates the length of each compressed row in bytes
// NOTE: There are two bytes per row per channel
unsigned int nLineLengthData = sizeof(unsigned short) * bitmap.Height() * nChannelsCount;
buf.SeekGet( CUtlBuffer::SEEK_CURRENT, nLineLengthData );
PSDReadCompressedChannels( buf, ( nChannelsCount > 4 ) ? 4 : nChannelsCount, mode, palette, bitmap );
}
// Read the alpha in a second pass for CMYKA
if ( bSecondPassCMYKA )
{
if ( nCompressionType == 0 )
{
PSDReadUncompressedChannels( buf, 1, MODE_COUNT, palette, bitmap );
}
else
{
PSDReadCompressedChannels( buf, 1, MODE_COUNT, palette, bitmap );
}
}
return true;
}
//-----------------------------------------------------------------------------
// Loads the heightfield from a file
//-----------------------------------------------------------------------------
bool PSDReadFileRGBA8888( const char *pFileName, const char *pPathID, Bitmap_t &bitmap )
{
CUtlStreamBuffer buf( pFileName, pPathID, CUtlBuffer::READ_ONLY );
if ( !g_pFullFileSystem->ReadFile( pFileName, pPathID, buf, sizeof(PSDHeader_t) ) )
{
Warning( "Unable to read file %s\n", pFileName );
return false;
}
return PSDReadFileRGBA8888( buf, bitmap );
}
//////////////////////////////////////////////////////////////////////////
//
// PSD Helper structs implementation
//
//////////////////////////////////////////////////////////////////////////
PSDImageResources::ResElement PSDImageResources::FindElement( Resource eType ) const
{
ResElement res;
memset( &res, 0, sizeof( res ) );
unsigned char const *pvBuffer = m_pvBuffer, * const pvBufferEnd = m_pvBuffer + m_numBytes;
while ( pvBuffer < pvBufferEnd )
{
// 4 : signature
// 2 : type
// 4 : reserved
// 2 : length
// bytes[ length ]
unsigned long uSignature = BigLong( *( unsigned long * )( pvBuffer ) );
pvBuffer += 4;
if ( uSignature != PSD_IMGRES_SIGNATURE )
break;
unsigned short uType = BigShort( *( unsigned short * )( pvBuffer ) );
pvBuffer += 6;
unsigned short uLength = BigShort( *( unsigned short * )( pvBuffer ) );
pvBuffer += 2;
if ( uType == eType )
{
res.m_eType = eType;
res.m_numBytes = uLength;
res.m_pvData = pvBuffer;
break;
}
else
{
pvBuffer += ( ( uLength + 1 ) &~1 );
}
}
return res;
}
PSDResFileInfo::ResFileInfoElement PSDResFileInfo::FindElement( ResFileInfo eType ) const
{
ResFileInfoElement res;
memset( &res, 0, sizeof( res ) );
unsigned char const *pvBuffer = m_res.m_pvData, * const pvBufferEnd = pvBuffer + m_res.m_numBytes;
while ( pvBuffer < pvBufferEnd )
{
// 2 : = 0x1C02
// 1 : type
// 2 : length
// bytes[ length ]
unsigned short uResLabel = BigShort( *( unsigned short * )( pvBuffer ) );
pvBuffer += 2;
unsigned char uType = *pvBuffer;
pvBuffer += 1;
unsigned short uLength = BigShort( *( unsigned short * )( pvBuffer ) );
pvBuffer += 2;
if ( uType == eType && uResLabel == 0x1C02 )
{
res.m_eType = eType;
res.m_numBytes = uLength;
res.m_pvData = pvBuffer;
break;
}
else
{
pvBuffer += uLength;
}
}
return res;
}

919
bitmap/resample.cpp Normal file
View File

@ -0,0 +1,919 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "nvtc.h"
#include "bitmap/imageformat.h"
#include "basetypes.h"
#include "tier0/dbg.h"
#include <malloc.h>
#include <memory.h>
#include "mathlib/mathlib.h"
#include "mathlib/vector.h"
#include "tier1/utlmemory.h"
#include "tier1/strtools.h"
#include "mathlib/compressed_vector.h"
// Should be last include
#include "tier0/memdbgon.h"
namespace ImageLoader
{
//-----------------------------------------------------------------------------
// Gamma correction
//-----------------------------------------------------------------------------
static void ConstructFloatGammaTable( float* pTable, float srcGamma, float dstGamma )
{
for( int i = 0; i < 256; i++ )
{
pTable[i] = 255.0 * pow( (float)i / 255.0f, srcGamma / dstGamma );
}
}
void ConstructGammaTable( unsigned char* pTable, float srcGamma, float dstGamma )
{
int v;
for( int i = 0; i < 256; i++ )
{
double f;
f = 255.0 * pow( (float)i / 255.0f, srcGamma / dstGamma );
v = ( int )(f + 0.5f);
if( v < 0 )
{
v = 0;
}
else if( v > 255 )
{
v = 255;
}
pTable[i] = ( unsigned char )v;
}
}
void GammaCorrectRGBA8888( unsigned char *pSrc, unsigned char* pDst, int width, int height, int depth,
unsigned char* pGammaTable )
{
for (int h = 0; h < depth; ++h )
{
for (int i = 0; i < height; ++i )
{
for (int j = 0; j < width; ++j )
{
int idx = (h * width * height + i * width + j) * 4;
// don't gamma correct alpha
pDst[idx] = pGammaTable[pSrc[idx]];
pDst[idx+1] = pGammaTable[pSrc[idx+1]];
pDst[idx+2] = pGammaTable[pSrc[idx+2]];
}
}
}
}
void GammaCorrectRGBA8888( unsigned char *src, unsigned char* dst, int width, int height, int depth,
float srcGamma, float dstGamma )
{
if (srcGamma == dstGamma)
{
if (src != dst)
{
memcpy( dst, src, GetMemRequired( width, height, depth, IMAGE_FORMAT_RGBA8888, false ) );
}
return;
}
static unsigned char gamma[256];
static float lastSrcGamma = -1;
static float lastDstGamma = -1;
if (lastSrcGamma != srcGamma || lastDstGamma != dstGamma)
{
ConstructGammaTable( gamma, srcGamma, dstGamma );
lastSrcGamma = srcGamma;
lastDstGamma = dstGamma;
}
GammaCorrectRGBA8888( src, dst, width, height, depth, gamma );
}
//-----------------------------------------------------------------------------
// Generate a NICE filter kernel
//-----------------------------------------------------------------------------
static void GenerateNiceFilter( float wratio, float hratio, float dratio, int kernelDiameter, float* pKernel, float *pInvKernel )
{
// Compute a kernel...
int h, i, j;
int kernelWidth = kernelDiameter * wratio;
int kernelHeight = kernelDiameter * hratio;
int kernelDepth = ( dratio != 0 ) ? kernelDiameter * dratio : 1;
// This is a NICE filter
// sinc pi*x * a box from -3 to 3 * sinc ( pi * x/3)
// where x is the pixel # in the destination (shrunken) image.
// only problem here is that the NICE filter has a very large kernel
// (7x7 x wratio x hratio x dratio)
float dx = 1.0f / (float)wratio;
float dy = 1.0f / (float)hratio;
float z, dz;
if (dratio != 0.0f)
{
dz = 1.0f / (float)dratio;
z = -((float)kernelDiameter - dz) * 0.5f;
}
else
{
dz = 0.0f;
z = 0.0f;
}
float total = 0.0f;
for ( h = 0; h < kernelDepth; ++h )
{
float y = -((float)kernelDiameter - dy) * 0.5f;
for ( i = 0; i < kernelHeight; ++i )
{
float x = -((float)kernelDiameter - dx) * 0.5f;
for ( j = 0; j < kernelWidth; ++j )
{
int nKernelIndex = kernelWidth * ( i + h * kernelHeight ) + j;
float d = sqrt( x * x + y * y + z * z );
if (d > kernelDiameter * 0.5f)
{
pKernel[nKernelIndex] = 0.0f;
}
else
{
float t = M_PI * d;
if ( t != 0 )
{
float sinc = sin( t ) / t;
float sinc3 = 3.0f * sin( t / 3.0f ) / t;
pKernel[nKernelIndex] = sinc * sinc3;
}
else
{
pKernel[nKernelIndex] = 1.0f;
}
total += pKernel[nKernelIndex];
}
x += dx;
}
y += dy;
}
z += dz;
}
// normalize
float flInvFactor = ( dratio == 0 ) ? wratio * hratio : dratio * wratio * hratio;
float flInvTotal = (total != 0.0f) ? 1.0f / total : 1.0f;
for ( h = 0; h < kernelDepth; ++h )
{
for ( i = 0; i < kernelHeight; ++i )
{
int nPixel = kernelWidth * ( h * kernelHeight + i );
for ( j = 0; j < kernelWidth; ++j )
{
pKernel[nPixel + j] *= flInvTotal;
pInvKernel[nPixel + j] = flInvFactor * pKernel[nPixel + j];
}
}
}
}
//-----------------------------------------------------------------------------
// Resample an image
//-----------------------------------------------------------------------------
static inline unsigned char Clamp( float x )
{
int idx = (int)(x + 0.5f);
if (idx < 0) idx = 0;
else if (idx > 255) idx = 255;
return idx;
}
inline bool IsPowerOfTwo( int x )
{
return (x & ( x - 1 )) == 0;
}
struct KernelInfo_t
{
float *m_pKernel;
float *m_pInvKernel;
int m_nWidth;
int m_nHeight;
int m_nDepth;
int m_nDiameter;
};
enum KernelType_t
{
KERNEL_DEFAULT = 0,
KERNEL_NORMALMAP,
KERNEL_ALPHATEST,
};
typedef void (*ApplyKernelFunc_t)( const KernelInfo_t &kernel, const ResampleInfo_t &info, int wratio, int hratio, int dratio, float* gammaToLinear, float *pAlphaResult );
//-----------------------------------------------------------------------------
// Apply Kernel to an image
//-----------------------------------------------------------------------------
template< int type, bool bNiceFilter >
class CKernelWrapper
{
public:
static inline int ActualX( int x, const ResampleInfo_t &info )
{
if ( info.m_nFlags & RESAMPLE_CLAMPS )
return clamp( x, 0, info.m_nSrcWidth - 1 );
// This works since info.m_nSrcWidth is a power of two.
// Even for negative #s!
return x & (info.m_nSrcWidth - 1);
}
static inline int ActualY( int y, const ResampleInfo_t &info )
{
if ( info.m_nFlags & RESAMPLE_CLAMPT )
return clamp( y, 0, info.m_nSrcHeight - 1 );
// This works since info.m_nSrcHeight is a power of two.
// Even for negative #s!
return y & (info.m_nSrcHeight - 1);
}
static inline int ActualZ( int z, const ResampleInfo_t &info )
{
if ( info.m_nFlags & RESAMPLE_CLAMPU )
return clamp( z, 0, info.m_nSrcDepth - 1 );
// This works since info.m_nSrcDepth is a power of two.
// Even for negative #s!
return z & (info.m_nSrcDepth - 1);
}
static void ComputeAveragedColor( const KernelInfo_t &kernel, const ResampleInfo_t &info,
int startX, int startY, int startZ, float *gammaToLinear, float *total )
{
total[0] = total[1] = total[2] = total[3] = 0.0f;
for ( int j = 0, srcZ = startZ; j < kernel.m_nDepth; ++j, ++srcZ )
{
int sz = ActualZ( srcZ, info );
sz *= info.m_nSrcWidth * info.m_nSrcHeight;
for ( int k = 0, srcY = startY; k < kernel.m_nHeight; ++k, ++srcY )
{
int sy = ActualY( srcY, info );
sy *= info.m_nSrcWidth;
int kernelIdx;
if ( bNiceFilter )
{
kernelIdx = kernel.m_nWidth * ( k + j * kernel.m_nHeight );
}
else
{
kernelIdx = 0;
}
for ( int l = 0, srcX = startX; l < kernel.m_nWidth; ++l, ++srcX, ++kernelIdx )
{
int sx = ActualX( srcX, info );
int srcPixel = (sz + sy + sx) << 2;
float flKernelFactor;
if ( bNiceFilter )
{
flKernelFactor = kernel.m_pKernel[kernelIdx];
if ( flKernelFactor == 0.0f )
continue;
}
else
{
flKernelFactor = kernel.m_pKernel[0];
}
if ( type == KERNEL_NORMALMAP )
{
total[0] += flKernelFactor * info.m_pSrc[srcPixel + 0];
total[1] += flKernelFactor * info.m_pSrc[srcPixel + 1];
total[2] += flKernelFactor * info.m_pSrc[srcPixel + 2];
total[3] += flKernelFactor * info.m_pSrc[srcPixel + 3];
}
else if ( type == KERNEL_ALPHATEST )
{
total[0] += flKernelFactor * gammaToLinear[ info.m_pSrc[srcPixel + 0] ];
total[1] += flKernelFactor * gammaToLinear[ info.m_pSrc[srcPixel + 1] ];
total[2] += flKernelFactor * gammaToLinear[ info.m_pSrc[srcPixel + 2] ];
if ( info.m_pSrc[srcPixel + 3] > 192 )
{
total[3] += flKernelFactor * 255.0f;
}
}
else
{
total[0] += flKernelFactor * gammaToLinear[ info.m_pSrc[srcPixel + 0] ];
total[1] += flKernelFactor * gammaToLinear[ info.m_pSrc[srcPixel + 1] ];
total[2] += flKernelFactor * gammaToLinear[ info.m_pSrc[srcPixel + 2] ];
total[3] += flKernelFactor * info.m_pSrc[srcPixel + 3];
}
}
}
}
}
static void AddAlphaToAlphaResult( const KernelInfo_t &kernel, const ResampleInfo_t &info,
int startX, int startY, int startZ, float flAlpha, float *pAlphaResult )
{
for ( int j = 0, srcZ = startZ; j < kernel.m_nDepth; ++j, ++srcZ )
{
int sz = ActualZ( srcZ, info );
sz *= info.m_nSrcWidth * info.m_nSrcHeight;
for ( int k = 0, srcY = startY; k < kernel.m_nHeight; ++k, ++srcY )
{
int sy = ActualY( srcY, info );
sy *= info.m_nSrcWidth;
int kernelIdx;
if ( bNiceFilter )
{
kernelIdx = k * kernel.m_nWidth + j * kernel.m_nWidth * kernel.m_nHeight;
}
else
{
kernelIdx = 0;
}
for ( int l = 0, srcX = startX; l < kernel.m_nWidth; ++l, ++srcX, ++kernelIdx )
{
int sx = ActualX( srcX, info );
int srcPixel = sz + sy + sx;
float flKernelFactor;
if ( bNiceFilter )
{
flKernelFactor = kernel.m_pInvKernel[kernelIdx];
if ( flKernelFactor == 0.0f )
continue;
}
else
{
flKernelFactor = kernel.m_pInvKernel[0];
}
pAlphaResult[srcPixel] += flKernelFactor * flAlpha;
}
}
}
}
static void AdjustAlphaChannel( const KernelInfo_t &kernel, const ResampleInfo_t &info,
int wratio, int hratio, int dratio, float *pAlphaResult )
{
// Find the delta between the alpha + source image
for ( int k = 0; k < info.m_nSrcDepth; ++k )
{
for ( int i = 0; i < info.m_nSrcHeight; ++i )
{
int dstPixel = i * info.m_nSrcWidth + k * info.m_nSrcWidth * info.m_nSrcHeight;
for ( int j = 0; j < info.m_nSrcWidth; ++j, ++dstPixel )
{
pAlphaResult[dstPixel] = fabs( pAlphaResult[dstPixel] - info.m_pSrc[dstPixel * 4 + 3] );
}
}
}
// Apply the kernel to the image
int nInitialZ = (dratio >> 1) - ((dratio * kernel.m_nDiameter) >> 1);
int nInitialY = (hratio >> 1) - ((hratio * kernel.m_nDiameter) >> 1);
int nInitialX = (wratio >> 1) - ((wratio * kernel.m_nDiameter) >> 1);
float flAlphaThreshhold = (info.m_flAlphaHiFreqThreshhold >= 0 ) ? 255.0f * info.m_flAlphaHiFreqThreshhold : 255.0f * 0.4f;
float flInvFactor = (dratio == 0) ? 1.0f / (hratio * wratio) : 1.0f / (hratio * wratio * dratio);
for ( int h = 0; h < info.m_nDestDepth; ++h )
{
int startZ = dratio * h + nInitialZ;
for ( int i = 0; i < info.m_nDestHeight; ++i )
{
int startY = hratio * i + nInitialY;
int dstPixel = ( info.m_nDestWidth * (i + h * info.m_nDestHeight) ) << 2;
for ( int j = 0; j < info.m_nDestWidth; ++j, dstPixel += 4 )
{
if ( info.m_pDest[ dstPixel + 3 ] == 255 )
continue;
int startX = wratio * j + nInitialX;
float flAlphaDelta = 0.0f;
for ( int m = 0, srcZ = startZ; m < dratio; ++m, ++srcZ )
{
int sz = ActualZ( srcZ, info );
sz *= info.m_nSrcWidth * info.m_nSrcHeight;
for ( int k = 0, srcY = startY; k < hratio; ++k, ++srcY )
{
int sy = ActualY( srcY, info );
sy *= info.m_nSrcWidth;
for ( int l = 0, srcX = startX; l < wratio; ++l, ++srcX )
{
// HACK: This temp variable fixes an internal compiler error in vs2005
int temp = srcX;
int sx = ActualX( temp, info );
int srcPixel = sz + sy + sx;
flAlphaDelta += pAlphaResult[srcPixel];
}
}
}
flAlphaDelta *= flInvFactor;
if ( flAlphaDelta > flAlphaThreshhold )
{
info.m_pDest[ dstPixel + 3 ] = 255.0f;
}
}
}
}
}
static void ApplyKernel( const KernelInfo_t &kernel, const ResampleInfo_t &info, int wratio, int hratio, int dratio, float* gammaToLinear, float *pAlphaResult )
{
float invDstGamma = 1.0f / info.m_flDestGamma;
// Apply the kernel to the image
int nInitialZ = (dratio >> 1) - ((dratio * kernel.m_nDiameter) >> 1);
int nInitialY = (hratio >> 1) - ((hratio * kernel.m_nDiameter) >> 1);
int nInitialX = (wratio >> 1) - ((wratio * kernel.m_nDiameter) >> 1);
float flAlphaThreshhold = (info.m_flAlphaThreshhold >= 0 ) ? 255.0f * info.m_flAlphaThreshhold : 255.0f * 0.4f;
for ( int k = 0; k < info.m_nDestDepth; ++k )
{
int startZ = dratio * k + nInitialZ;
for ( int i = 0; i < info.m_nDestHeight; ++i )
{
int startY = hratio * i + nInitialY;
int dstPixel = (i * info.m_nDestWidth + k * info.m_nDestWidth * info.m_nDestHeight) << 2;
for ( int j = 0; j < info.m_nDestWidth; ++j, dstPixel += 4 )
{
int startX = wratio * j + nInitialX;
float total[4];
ComputeAveragedColor( kernel, info, startX, startY, startZ, gammaToLinear, total );
// NOTE: Can't use a table here, we lose too many bits
if( type == KERNEL_NORMALMAP )
{
for ( int ch = 0; ch < 4; ++ ch )
info.m_pDest[ dstPixel + ch ] = Clamp( info.m_flColorGoal[ch] + ( info.m_flColorScale[ch] * ( total[ch] - info.m_flColorGoal[ch] ) ) );
}
else if ( type == KERNEL_ALPHATEST )
{
// If there's more than 40% coverage, then keep the pixel (renormalize the color based on coverage)
float flAlpha = ( total[3] >= flAlphaThreshhold ) ? 255 : 0;
for ( int ch = 0; ch < 3; ++ ch )
info.m_pDest[ dstPixel + ch ] = Clamp( 255.0f * pow( ( info.m_flColorGoal[ch] + ( info.m_flColorScale[ch] * ( ( total[ch] > 0 ? total[ch] : 0 ) - info.m_flColorGoal[ch] ) ) ) / 255.0f, invDstGamma ) );
info.m_pDest[ dstPixel + 3 ] = Clamp( flAlpha );
AddAlphaToAlphaResult( kernel, info, startX, startY, startZ, flAlpha, pAlphaResult );
}
else
{
for ( int ch = 0; ch < 3; ++ ch )
info.m_pDest[ dstPixel + ch ] = Clamp( 255.0f * pow( ( info.m_flColorGoal[ch] + ( info.m_flColorScale[ch] * ( ( total[ch] > 0 ? total[ch] : 0 ) - info.m_flColorGoal[ch] ) ) ) / 255.0f, invDstGamma ) );
info.m_pDest[ dstPixel + 3 ] = Clamp( info.m_flColorGoal[3] + ( info.m_flColorScale[3] * ( total[3] - info.m_flColorGoal[3] ) ) );
}
}
}
if ( type == KERNEL_ALPHATEST )
{
AdjustAlphaChannel( kernel, info, wratio, hratio, dratio, pAlphaResult );
}
}
}
};
typedef CKernelWrapper< KERNEL_DEFAULT, false > ApplyKernelDefault_t;
typedef CKernelWrapper< KERNEL_NORMALMAP, false > ApplyKernelNormalmap_t;
typedef CKernelWrapper< KERNEL_ALPHATEST, false > ApplyKernelAlphatest_t;
typedef CKernelWrapper< KERNEL_DEFAULT, true > ApplyKernelDefaultNice_t;
typedef CKernelWrapper< KERNEL_NORMALMAP, true > ApplyKernelNormalmapNice_t;
typedef CKernelWrapper< KERNEL_ALPHATEST, true > ApplyKernelAlphatestNice_t;
static ApplyKernelFunc_t g_KernelFunc[] =
{
ApplyKernelDefault_t::ApplyKernel,
ApplyKernelNormalmap_t::ApplyKernel,
ApplyKernelAlphatest_t::ApplyKernel,
};
static ApplyKernelFunc_t g_KernelFuncNice[] =
{
ApplyKernelDefaultNice_t::ApplyKernel,
ApplyKernelNormalmapNice_t::ApplyKernel,
ApplyKernelAlphatestNice_t::ApplyKernel,
};
bool ResampleRGBA8888( const ResampleInfo_t& info )
{
// No resampling needed, just gamma correction
if ( info.m_nSrcWidth == info.m_nDestWidth && info.m_nSrcHeight == info.m_nDestHeight && info.m_nSrcDepth == info.m_nDestDepth )
{
// Here, we need to gamma convert the source image..
GammaCorrectRGBA8888( info.m_pSrc, info.m_pDest, info.m_nSrcWidth, info.m_nSrcHeight, info.m_nSrcDepth, info.m_flSrcGamma, info.m_flDestGamma );
return true;
}
// fixme: has to be power of two for now.
if( !IsPowerOfTwo(info.m_nSrcWidth) || !IsPowerOfTwo(info.m_nSrcHeight) || !IsPowerOfTwo(info.m_nSrcDepth) ||
!IsPowerOfTwo(info.m_nDestWidth) || !IsPowerOfTwo(info.m_nDestHeight) || !IsPowerOfTwo(info.m_nDestDepth) )
{
return false;
}
// fixme: can only downsample for now.
if( (info.m_nSrcWidth < info.m_nDestWidth) || (info.m_nSrcHeight < info.m_nDestHeight) || (info.m_nSrcDepth < info.m_nDestDepth) )
{
return false;
}
// Compute gamma tables...
static float gammaToLinear[256];
static float lastSrcGamma = -1;
if (lastSrcGamma != info.m_flSrcGamma)
{
ConstructFloatGammaTable( gammaToLinear, info.m_flSrcGamma, 1.0f );
lastSrcGamma = info.m_flSrcGamma;
}
int wratio = info.m_nSrcWidth / info.m_nDestWidth;
int hratio = info.m_nSrcHeight / info.m_nDestHeight;
int dratio = (info.m_nSrcDepth != info.m_nDestDepth) ? info.m_nSrcDepth / info.m_nDestDepth : 0;
KernelInfo_t kernel;
float* pTempMemory = 0;
float* pTempInvMemory = 0;
static float* kernelCache[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static float* pInvKernelCache[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
float pKernelMem[1];
float pInvKernelMem[1];
if ( info.m_nFlags & RESAMPLE_NICE_FILTER )
{
// Kernel size is measured in dst pixels
kernel.m_nDiameter = 6;
// Compute a kernel...
kernel.m_nWidth = kernel.m_nDiameter * wratio;
kernel.m_nHeight = kernel.m_nDiameter * hratio;
kernel.m_nDepth = kernel.m_nDiameter * dratio;
if ( kernel.m_nDepth == 0 )
{
kernel.m_nDepth = 1;
}
// Cache the filter (2d kernels only)....
int power = -1;
if ( (wratio == hratio) && (dratio == 0) )
{
power = 0;
int tempWidth = wratio;
while (tempWidth > 1)
{
++power;
tempWidth >>= 1;
}
// Don't cache anything bigger than 512x512
if (power >= 10)
{
power = -1;
}
}
if (power >= 0)
{
if (!kernelCache[power])
{
kernelCache[power] = new float[kernel.m_nWidth * kernel.m_nHeight];
pInvKernelCache[power] = new float[kernel.m_nWidth * kernel.m_nHeight];
GenerateNiceFilter( wratio, hratio, dratio, kernel.m_nDiameter, kernelCache[power], pInvKernelCache[power] );
}
kernel.m_pKernel = kernelCache[power];
kernel.m_pInvKernel = pInvKernelCache[power];
}
else
{
// Don't cache non-square kernels, or 3d kernels
pTempMemory = new float[kernel.m_nWidth * kernel.m_nHeight * kernel.m_nDepth];
pTempInvMemory = new float[kernel.m_nWidth * kernel.m_nHeight * kernel.m_nDepth];
GenerateNiceFilter( wratio, hratio, dratio, kernel.m_nDiameter, pTempMemory, pTempInvMemory );
kernel.m_pKernel = pTempMemory;
kernel.m_pInvKernel = pTempInvMemory;
}
}
else
{
// Compute a kernel...
kernel.m_nWidth = wratio;
kernel.m_nHeight = hratio;
kernel.m_nDepth = dratio ? dratio : 1;
kernel.m_nDiameter = 1;
// Simple implementation of a box filter that doesn't block the stack!
pKernelMem[0] = 1.0f / (float)(kernel.m_nWidth * kernel.m_nHeight * kernel.m_nDepth);
pInvKernelMem[0] = 1.0f;
kernel.m_pKernel = pKernelMem;
kernel.m_pInvKernel = pInvKernelMem;
}
float *pAlphaResult = NULL;
KernelType_t type;
if ( info.m_nFlags & RESAMPLE_NORMALMAP )
{
type = KERNEL_NORMALMAP;
}
else if ( info.m_nFlags & RESAMPLE_ALPHATEST )
{
int nSize = info.m_nSrcHeight * info.m_nSrcWidth * info.m_nSrcDepth * sizeof(float);
pAlphaResult = (float*)malloc( nSize );
memset( pAlphaResult, 0, nSize );
type = KERNEL_ALPHATEST;
}
else
{
type = KERNEL_DEFAULT;
}
if ( info.m_nFlags & RESAMPLE_NICE_FILTER )
{
g_KernelFuncNice[type]( kernel, info, wratio, hratio, dratio, gammaToLinear, pAlphaResult );
if (pTempMemory)
{
delete[] pTempMemory;
}
}
else
{
g_KernelFunc[type]( kernel, info, wratio, hratio, dratio, gammaToLinear, pAlphaResult );
}
if ( pAlphaResult )
{
free( pAlphaResult );
}
return true;
}
bool ResampleRGBA16161616( const ResampleInfo_t& info )
{
// HDRFIXME: This is some lame shit right here. (We need to get NICE working, etc, etc.)
// Make sure everything is power of two.
Assert( ( info.m_nSrcWidth & ( info.m_nSrcWidth - 1 ) ) == 0 );
Assert( ( info.m_nSrcHeight & ( info.m_nSrcHeight - 1 ) ) == 0 );
Assert( ( info.m_nDestWidth & ( info.m_nDestWidth - 1 ) ) == 0 );
Assert( ( info.m_nDestHeight & ( info.m_nDestHeight - 1 ) ) == 0 );
// Make sure that we aren't upscsaling the image. . .we do`n't support that very well.
Assert( info.m_nSrcWidth >= info.m_nDestWidth );
Assert( info.m_nSrcHeight >= info.m_nDestHeight );
int nSampleWidth = info.m_nSrcWidth / info.m_nDestWidth;
int nSampleHeight = info.m_nSrcHeight / info.m_nDestHeight;
unsigned short *pSrc = ( unsigned short * )info.m_pSrc;
unsigned short *pDst = ( unsigned short * )info.m_pDest;
int x, y;
for( y = 0; y < info.m_nDestHeight; y++ )
{
for( x = 0; x < info.m_nDestWidth; x++ )
{
int accum[4];
accum[0] = accum[1] = accum[2] = accum[3] = 0;
int nSampleY;
for( nSampleY = 0; nSampleY < nSampleHeight; nSampleY++ )
{
int nSampleX;
for( nSampleX = 0; nSampleX < nSampleWidth; nSampleX++ )
{
accum[0] += ( int )pSrc[((x*nSampleWidth+nSampleX)+(y*nSampleHeight+nSampleY)*info.m_nSrcWidth)*4+0];
accum[1] += ( int )pSrc[((x*nSampleWidth+nSampleX)+(y*nSampleHeight+nSampleY)*info.m_nSrcWidth)*4+1];
accum[2] += ( int )pSrc[((x*nSampleWidth+nSampleX)+(y*nSampleHeight+nSampleY)*info.m_nSrcWidth)*4+2];
accum[3] += ( int )pSrc[((x*nSampleWidth+nSampleX)+(y*nSampleHeight+nSampleY)*info.m_nSrcWidth)*4+3];
}
}
int i;
for( i = 0; i < 4; i++ )
{
accum[i] /= ( nSampleWidth * nSampleHeight );
accum[i] = max( accum[i], 0 );
accum[i] = min( accum[i], 65535 );
pDst[(x+y*info.m_nDestWidth)*4+i] = ( unsigned short )accum[i];
}
}
}
return true;
}
bool ResampleRGB323232F( const ResampleInfo_t& info )
{
// HDRFIXME: This is some lame shit right here. (We need to get NICE working, etc, etc.)
// Make sure everything is power of two.
Assert( ( info.m_nSrcWidth & ( info.m_nSrcWidth - 1 ) ) == 0 );
Assert( ( info.m_nSrcHeight & ( info.m_nSrcHeight - 1 ) ) == 0 );
Assert( ( info.m_nDestWidth & ( info.m_nDestWidth - 1 ) ) == 0 );
Assert( ( info.m_nDestHeight & ( info.m_nDestHeight - 1 ) ) == 0 );
// Make sure that we aren't upscaling the image. . .we do`n't support that very well.
Assert( info.m_nSrcWidth >= info.m_nDestWidth );
Assert( info.m_nSrcHeight >= info.m_nDestHeight );
int nSampleWidth = info.m_nSrcWidth / info.m_nDestWidth;
int nSampleHeight = info.m_nSrcHeight / info.m_nDestHeight;
float *pSrc = ( float * )info.m_pSrc;
float *pDst = ( float * )info.m_pDest;
int x, y;
for( y = 0; y < info.m_nDestHeight; y++ )
{
for( x = 0; x < info.m_nDestWidth; x++ )
{
float accum[4];
accum[0] = accum[1] = accum[2] = accum[3] = 0;
int nSampleY;
for( nSampleY = 0; nSampleY < nSampleHeight; nSampleY++ )
{
int nSampleX;
for( nSampleX = 0; nSampleX < nSampleWidth; nSampleX++ )
{
accum[0] += pSrc[((x*nSampleWidth+nSampleX)+(y*nSampleHeight+nSampleY)*info.m_nSrcWidth)*3+0];
accum[1] += pSrc[((x*nSampleWidth+nSampleX)+(y*nSampleHeight+nSampleY)*info.m_nSrcWidth)*3+1];
accum[2] += pSrc[((x*nSampleWidth+nSampleX)+(y*nSampleHeight+nSampleY)*info.m_nSrcWidth)*3+2];
}
}
int i;
for( i = 0; i < 3; i++ )
{
accum[i] /= ( nSampleWidth * nSampleHeight );
pDst[(x+y*info.m_nDestWidth)*3+i] = accum[i];
}
}
}
return true;
}
//-----------------------------------------------------------------------------
// Generates mipmap levels
//-----------------------------------------------------------------------------
void GenerateMipmapLevels( unsigned char* pSrc, unsigned char* pDst, int width,
int height, int depth, ImageFormat imageFormat, float srcGamma, float dstGamma, int numLevels )
{
int dstWidth = width;
int dstHeight = height;
int dstDepth = depth;
// temporary storage for the mipmaps
int tempMem = GetMemRequired( dstWidth, dstHeight, dstDepth, IMAGE_FORMAT_RGBA8888, false );
CUtlMemory<unsigned char> tmpImage;
tmpImage.EnsureCapacity( tempMem );
while( true )
{
// This generates a mipmap in RGBA8888, linear space
ResampleInfo_t info;
info.m_pSrc = pSrc;
info.m_pDest = tmpImage.Base();
info.m_nSrcWidth = width;
info.m_nSrcHeight = height;
info.m_nSrcDepth = depth;
info.m_nDestWidth = dstWidth;
info.m_nDestHeight = dstHeight;
info.m_nDestDepth = dstDepth;
info.m_flSrcGamma = srcGamma;
info.m_flDestGamma = dstGamma;
ResampleRGBA8888( info );
// each mipmap level needs to be color converted separately
ConvertImageFormat( tmpImage.Base(), IMAGE_FORMAT_RGBA8888,
pDst, imageFormat, dstWidth, dstHeight, 0, 0 );
if (numLevels == 0)
{
// We're done after we've made the 1x1 mip level
if (dstWidth == 1 && dstHeight == 1 && dstDepth == 1)
return;
}
else
{
if (--numLevels <= 0)
return;
}
// Figure out where the next level goes
int memRequired = ImageLoader::GetMemRequired( dstWidth, dstHeight, dstDepth, imageFormat, false);
pDst += memRequired;
// shrink by a factor of 2, but clamp at 1 pixel (non-square textures)
dstWidth = dstWidth > 1 ? dstWidth >> 1 : 1;
dstHeight = dstHeight > 1 ? dstHeight >> 1 : 1;
dstDepth = dstDepth > 1 ? dstDepth >> 1 : 1;
}
}
void GenerateMipmapLevelsLQ( unsigned char* pSrc, unsigned char* pDst, int width, int height,
ImageFormat imageFormat, int numLevels )
{
CUtlMemory<unsigned char> tmpImage;
const unsigned char* pSrcLevel = pSrc;
int mipmap0Size = GetMemRequired( width, height, 1, IMAGE_FORMAT_RGBA8888, false );
// TODO: Could work with any 8888 format without conversion.
if ( imageFormat != IMAGE_FORMAT_RGBA8888 )
{
// Damn and blast, had to allocate memory.
tmpImage.EnsureCapacity( mipmap0Size );
ConvertImageFormat( tmpImage.Base(), IMAGE_FORMAT_RGBA8888, pSrc, imageFormat, width, height, 0, 0 );
pSrcLevel = tmpImage.Base();
}
// Copy the 0th level over.
memcpy( pDst, pSrcLevel, mipmap0Size );
int dstWidth = width;
int dstHeight = height;
unsigned char* pDstLevel = pDst + mipmap0Size;
int srcWidth = width;
int srcHeight = height;
// Distance from one pixel to the next
const int cStride = 4;
do
{
dstWidth = Max( 1, dstWidth >> 1 );
dstHeight = Max( 1, dstHeight >> 1 );
// Distance from one row to the next.
const int cSrcPitch = cStride * srcWidth * ( srcHeight > 1 ? 1 : 0);
const int cSrcStride = srcWidth > 1 ? cStride : 0;
const unsigned char* pSrcPixel = pSrcLevel;
unsigned char* pDstPixel = pDstLevel;
for ( int j = 0; j < dstHeight; ++j )
{
for ( int i = 0; i < dstWidth; ++i )
{
// This doesn't round. It's crappy. It's a simple bilerp.
pDstPixel[ 0 ] = ( ( unsigned int ) pSrcPixel[ 0 ] + ( unsigned int ) pSrcPixel[ 0 + cSrcStride ] + ( unsigned int ) pSrcPixel[ 0 + cSrcPitch ] + ( unsigned int ) pSrcPixel[ 0 + cSrcPitch + cSrcStride ] ) >> 2;
pDstPixel[ 1 ] = ( ( unsigned int ) pSrcPixel[ 1 ] + ( unsigned int ) pSrcPixel[ 1 + cSrcStride ] + ( unsigned int ) pSrcPixel[ 1 + cSrcPitch ] + ( unsigned int ) pSrcPixel[ 1 + cSrcPitch + cSrcStride ] ) >> 2;
pDstPixel[ 2 ] = ( ( unsigned int ) pSrcPixel[ 2 ] + ( unsigned int ) pSrcPixel[ 2 + cSrcStride ] + ( unsigned int ) pSrcPixel[ 2 + cSrcPitch ] + ( unsigned int ) pSrcPixel[ 2 + cSrcPitch + cSrcStride ] ) >> 2;
pDstPixel[ 3 ] = ( ( unsigned int ) pSrcPixel[ 3 ] + ( unsigned int ) pSrcPixel[ 3 + cSrcStride ] + ( unsigned int ) pSrcPixel[ 3 + cSrcPitch ] + ( unsigned int ) pSrcPixel[ 3 + cSrcPitch + cSrcStride ] ) >> 2;
pDstPixel += cStride;
pSrcPixel += cStride * 2; // We advance 2 source pixels for each pixel.
}
// Need to bump down a row.
pSrcPixel += cSrcPitch;
}
// Update for the next go round!
pSrcLevel = pDstLevel;
pDstLevel += GetMemRequired( dstWidth, dstHeight, 1, IMAGE_FORMAT_RGBA8888, false );
srcWidth = Max( 1, srcWidth >> 1 );
srcHeight = Max( 1, srcHeight >> 1 );
} while ( srcWidth > 1 || srcHeight > 1 );
}
} // ImageLoader namespace ends

1001
bitmap/tgaloader.cpp Normal file

File diff suppressed because it is too large Load Diff

353
bitmap/tgawriter.cpp Normal file
View File

@ -0,0 +1,353 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <stdlib.h>
#include <stdio.h>
#include "tier0/dbg.h"
#include <malloc.h>
#include "filesystem.h"
#include "bitmap/tgawriter.h"
#include "tier1/utlbuffer.h"
#include "bitmap/imageformat.h"
#include "tier2/tier2.h"
#include "tier2/fileutils.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
namespace TGAWriter
{
#pragma pack(1)
struct TGAHeader_t
{
unsigned char id_length;
unsigned char colormap_type;
unsigned char image_type;
unsigned short colormap_index;
unsigned short colormap_length;
unsigned char colormap_size;
unsigned short x_origin;
unsigned short y_origin;
unsigned short width;
unsigned short height;
unsigned char pixel_size;
unsigned char attributes;
};
#pragma pack()
#define fputc myfputc
#define fwrite myfwrite
static void fputLittleShort( unsigned short s, CUtlBuffer &buffer )
{
buffer.PutChar( s & 0xff );
buffer.PutChar( s >> 8 );
}
static inline void myfputc( unsigned char c, FileHandle_t fileHandle )
{
g_pFullFileSystem->Write( &c, 1, fileHandle );
}
static inline void myfwrite( void const *data, int size1, int size2, FileHandle_t fileHandle )
{
g_pFullFileSystem->Write( data, size1 * size2, fileHandle );
}
//-----------------------------------------------------------------------------
// FIXME: assumes that we don't need to do gamma correction.
//-----------------------------------------------------------------------------
bool WriteToBuffer( unsigned char *pImageData, CUtlBuffer &buffer, int width, int height,
ImageFormat srcFormat, ImageFormat dstFormat )
{
TGAHeader_t header;
// Fix the dstFormat to match what actually is going to go into the file
switch( dstFormat )
{
case IMAGE_FORMAT_RGB888:
dstFormat = IMAGE_FORMAT_BGR888;
break;
#if defined( _X360 )
case IMAGE_FORMAT_LINEAR_RGB888:
dstFormat = IMAGE_FORMAT_LINEAR_BGR888;
break;
#endif
case IMAGE_FORMAT_RGBA8888:
dstFormat = IMAGE_FORMAT_BGRA8888;
break;
}
header.id_length = 0; // comment length
header.colormap_type = 0; // ???
switch( dstFormat )
{
case IMAGE_FORMAT_BGR888:
#if defined( _X360 )
case IMAGE_FORMAT_LINEAR_BGR888:
#endif
header.image_type = 2; // 24/32 bit uncompressed TGA
header.pixel_size = 24;
break;
case IMAGE_FORMAT_BGRA8888:
header.image_type = 2; // 24/32 bit uncompressed TGA
header.pixel_size = 32;
break;
case IMAGE_FORMAT_I8:
header.image_type = 1; // 8 bit uncompressed TGA
header.pixel_size = 8;
break;
default:
return false;
break;
}
header.colormap_index = 0;
header.colormap_length = 0;
header.colormap_size = 0;
header.x_origin = 0;
header.y_origin = 0;
header.width = ( unsigned short )width;
header.height = ( unsigned short )height;
header.attributes = 0x20; // Makes it so we don't have to vertically flip the image
buffer.PutChar( header.id_length );
buffer.PutChar( header.colormap_type );
buffer.PutChar( header.image_type );
fputLittleShort( header.colormap_index, buffer );
fputLittleShort( header.colormap_length, buffer );
buffer.PutChar( header.colormap_size );
fputLittleShort( header.x_origin, buffer );
fputLittleShort( header.y_origin, buffer );
fputLittleShort( header.width, buffer );
fputLittleShort( header.height, buffer );
buffer.PutChar( header.pixel_size );
buffer.PutChar( header.attributes );
int nSizeInBytes = width * height * ImageLoader::SizeInBytes( dstFormat );
buffer.EnsureCapacity( buffer.TellPut() + nSizeInBytes );
unsigned char *pDst = (unsigned char*)buffer.PeekPut();
if ( !ImageLoader::ConvertImageFormat( pImageData, srcFormat, pDst, dstFormat, width, height ) )
return false;
buffer.SeekPut( CUtlBuffer::SEEK_CURRENT, nSizeInBytes );
return true;
}
bool WriteDummyFileNoAlloc( const char *fileName, int width, int height, enum ImageFormat dstFormat )
{
TGAHeader_t tgaHeader;
Assert( g_pFullFileSystem );
if( !g_pFullFileSystem )
{
return false;
}
COutputFile fp( fileName );
int nBytesPerPixel, nImageType, nPixelSize;
switch( dstFormat )
{
case IMAGE_FORMAT_BGR888:
#if defined( _X360 )
case IMAGE_FORMAT_LINEAR_BGR888:
#endif
nBytesPerPixel = 3; // 24/32 bit uncompressed TGA
nPixelSize = 24;
nImageType = 2;
break;
case IMAGE_FORMAT_BGRA8888:
nBytesPerPixel = 4; // 24/32 bit uncompressed TGA
nPixelSize = 32;
nImageType = 2;
break;
case IMAGE_FORMAT_I8:
nBytesPerPixel = 1; // 8 bit uncompressed TGA
nPixelSize = 8;
nImageType = 1;
break;
default:
return false;
break;
}
memset( &tgaHeader, 0, sizeof(tgaHeader) );
tgaHeader.id_length = 0;
tgaHeader.image_type = (unsigned char) nImageType;
tgaHeader.width = (unsigned short) width;
tgaHeader.height = (unsigned short) height;
tgaHeader.pixel_size = (unsigned char) nPixelSize;
tgaHeader.attributes = 0x20;
// Write the Targa header
fp.Write( &tgaHeader, sizeof(TGAHeader_t) );
// Write out width * height black pixels
unsigned char black[4] = { 0x1E, 0x9A, 0xFF, 0x00 };
for (int i = 0; i < width * height; i++)
{
fp.Write( black, nBytesPerPixel );
}
return true;
}
bool WriteTGAFile( const char *fileName, int width, int height, enum ImageFormat srcFormat, uint8 const *srcData, int nStride )
{
TGAHeader_t tgaHeader;
COutputFile fp( fileName );
int nBytesPerPixel, nImageType, nPixelSize;
bool bMustConvert = false;
ImageFormat dstFormat = srcFormat;
switch( srcFormat )
{
case IMAGE_FORMAT_BGR888:
#if defined( _X360 )
case IMAGE_FORMAT_LINEAR_BGR888:
#endif
nBytesPerPixel = 3; // 24/32 bit uncompressed TGA
nPixelSize = 24;
nImageType = 2;
break;
case IMAGE_FORMAT_BGRA8888:
nBytesPerPixel = 4; // 24/32 bit uncompressed TGA
nPixelSize = 32;
nImageType = 2;
break;
case IMAGE_FORMAT_RGBA8888:
bMustConvert = true;
dstFormat = IMAGE_FORMAT_BGRA8888;
nBytesPerPixel = 4; // 24/32 bit uncompressed TGA
nPixelSize = 32;
nImageType = 2;
break;
case IMAGE_FORMAT_I8:
nBytesPerPixel = 1; // 8 bit uncompressed TGA
nPixelSize = 8;
nImageType = 1;
break;
default:
return false;
break;
}
memset( &tgaHeader, 0, sizeof(tgaHeader) );
tgaHeader.id_length = 0;
tgaHeader.image_type = (unsigned char) nImageType;
tgaHeader.width = (unsigned short) width;
tgaHeader.height = (unsigned short) height;
tgaHeader.pixel_size = (unsigned char) nPixelSize;
tgaHeader.attributes = 0x20;
// Write the Targa header
fp.Write( &tgaHeader, sizeof(TGAHeader_t) );
// Write out image data
if ( bMustConvert )
{
uint8 *pLineBuf = new uint8[ nBytesPerPixel * width ];
while( height-- )
{
ImageLoader::ConvertImageFormat( srcData, srcFormat, pLineBuf, dstFormat, width, 1 );
fp.Write( pLineBuf, nBytesPerPixel * width );
srcData += nStride;
}
delete[] pLineBuf;
}
else
{
while( height-- )
{
fp.Write( srcData, nBytesPerPixel * width );
srcData += nStride;
}
}
return true;
}
bool WriteRectNoAlloc( unsigned char *pImageData, const char *fileName, int nXOrigin, int nYOrigin, int width, int height, int nStride, enum ImageFormat srcFormat )
{
Assert( g_pFullFileSystem );
if( !g_pFullFileSystem )
{
return false;
}
FileHandle_t fp;
fp = g_pFullFileSystem->Open( fileName, "r+b" );
//
// Read in the targa header
//
TGAHeader_t tgaHeader;
g_pFullFileSystem->Read( &tgaHeader, sizeof(tgaHeader), fp );
int nBytesPerPixel, nPixelSize;
switch( srcFormat )
{
case IMAGE_FORMAT_BGR888:
#if defined( _X360 )
case IMAGE_FORMAT_LINEAR_BGR888:
#endif
nBytesPerPixel = 3; // 24/32 bit uncompressed TGA
nPixelSize = 24;
break;
case IMAGE_FORMAT_BGRA8888:
nBytesPerPixel = 4; // 24/32 bit uncompressed TGA
nPixelSize = 32;
break;
case IMAGE_FORMAT_I8:
nBytesPerPixel = 1; // 8 bit uncompressed TGA
nPixelSize = 8;
break;
default:
return false;
break;
}
// Verify src data matches the targa we're going to write into
if ( nPixelSize != tgaHeader.pixel_size )
{
Warning( "TGA doesn't match source data.\n" );
return false;
}
// Seek to the origin of the target subrect from the beginning of the file
g_pFullFileSystem->Seek( fp, nBytesPerPixel * (tgaHeader.width * nYOrigin + nXOrigin), FILESYSTEM_SEEK_CURRENT );
unsigned char *pSrc = pImageData;
// Run through each scanline of the incoming rect
for (int row=0; row < height; row++ )
{
g_pFullFileSystem->Write( pSrc, nBytesPerPixel * width, fp );
// Advance src pointer to next scanline
pSrc += nBytesPerPixel * nStride;
// Seek ahead in the file
g_pFullFileSystem->Seek( fp, nBytesPerPixel * ( tgaHeader.width - width ), FILESYSTEM_SEEK_CURRENT );
}
g_pFullFileSystem->Close( fp );
return true;
}
} // end namespace TGAWriter

View File

@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// CHOREOOBJECTS.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$macro SRCDIR ".."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE;..\game\shared;..\utils\common"
}
}
$Project "choreoobjects"
{
$Folder "Source Files"
{
$File "$SRCDIR\game\shared\choreoactor.cpp"
$File "$SRCDIR\game\shared\choreochannel.cpp"
$File "$SRCDIR\game\shared\choreoevent.cpp"
$File "$SRCDIR\game\shared\choreoscene.cpp"
$File "$SRCDIR\game\shared\sceneimage.cpp"
}
$Folder "Header Files"
{
$File "$SRCDIR\game\shared\choreoactor.h"
$File "$SRCDIR\game\shared\choreochannel.h"
$File "$SRCDIR\game\shared\choreoevent.h"
$File "$SRCDIR\game\shared\choreoscene.h"
$File "$SRCDIR\game\shared\ichoreoeventcallback.h"
$File "$SRCDIR\game\shared\sceneimage.h"
}
$Folder "Public Header Files"
{
$File "$SRCDIR\public\mathlib\mathlib.h"
$File "$SRCDIR\public\mathlib\vector.h"
$File "$SRCDIR\public\mathlib\vector2d.h"
}
}

View File

@ -0,0 +1,19 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// ClientNetMessage.cpp: implementation of the CClientNetMessage class.
//
//////////////////////////////////////////////////////////////////////
#include "ClientNetMessage.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

138
common/ClientNetMessage.h Normal file
View File

@ -0,0 +1,138 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef CLIENTNETMESSAGE_H
#define CLIENTNETMESSAGE_H
#ifdef _WIN32
#pragma once
#pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#endif
#include "inetmessage.h"
#include "protocol.h"
#include "checksum_crc.h"
#include "tier0/dbg.h"
class bf_read;
class bf_write;
#define DECLARE_CLIENTNETMESSAGE( msgtype ) \
public: \
int ReadFromBuffer( bf_read * buffer ); \
int WriteToBuffer( bf_write * buffer ); \
void Clear(); \
const char *ToString(); \
static int GetType() { return msgtype; }; \
static const char *GetName() { return #msgtype; };
class CNetMessage : public INetMessage
{
public:
CNetMessage() { m_bReliable = 0; m_bOwnData = false; };
virtual ~CNetMessage() {};
void SetReliable( bool state = true) {m_bReliable = state;};
bool IsReliable() { return m_bReliable; };
bool IsConnectionless() { return false;};
virtual const char *ToString() { return "Unknown CNetMessage"; };
public:
bool m_bReliable; // true if message should be send reliable
bool m_bOwnData; // true if message object uses dynamic allocated memory
};
class CLC_SendFile : public CNetMessage
{
DECLARE_CLIENTNETMESSAGE( clc_sendfile );
CLC_SendFile(CRC32_t fileCRC)
{
m_bReliable = true;
m_bOwnData = false;
m_FileCRC = fileCRC;
}
public:
CRC32_t m_FileCRC; // CRC of file to send
};
class CLC_Move : public CNetMessage
{
DECLARE_CLIENTNETMESSAGE( clc_move );
CLC_Move( int numBackup, int numNew, int length, unsigned char * data)
{
m_bReliable = true;
m_bOwnData = false;
m_nNumBackupCommands = numBackup;
m_nNumNewCommands = numNew;
m_nLength = length; // in bits
m_Data = data;
}
public:
int m_nNumBackupCommands;
int m_nNumNewCommands;
int m_nLength;
unsigned char *m_Data;
};
class CLC_StringCmd : public CNetMessage
{
DECLARE_CLIENTNETMESSAGE( clc_stringcmd );
CLC_StringCmd(const char *command)
{
Assert( command );
m_szClientCommand = (char*)command;
m_bReliable = true;
m_bOwnData = false;
};
public:
char *m_szClientCommand;
};
class CLC_Delta : public CNetMessage
{
DECLARE_CLIENTNETMESSAGE( clc_delta );
CLC_Delta( int deltaSequeenceNr );
public:
int m_nSequenceNumber;
};
class CLC_VoiceData : public CNetMessage
{
DECLARE_CLIENTNETMESSAGE( clc_voicedata );
CLC_VoiceData( unsigned char *data, int length )
{
Assert( data );
m_Data = data;
m_nLength = length;
m_bReliable = false;
m_bOwnData = false;
};
public:
int m_nLength;
unsigned char *m_Data;
};
#endif // CLIENTNETMESSAGE_H

922
common/ConfigManager.cpp Normal file
View File

@ -0,0 +1,922 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <windows.h>
#include "interface.h"
#include "tier0/icommandline.h"
#include "filesystem_tools.h"
#include "KeyValues.h"
#include "tier1/utlbuffer.h"
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include "ConfigManager.h"
#include "SourceAppInfo.h"
#include "steam/steam_api.h"
extern CSteamAPIContext *steamapicontext;
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
#define GAME_CONFIG_FILENAME "GameConfig.txt"
#define TOKEN_SDK_VERSION "SDKVersion"
// Version history:
// 0 - Initial release
// 1 - Versioning added, DoD configuration added
// 2 - Ep1 added
// 3 - Ep2, TF2, and Portal added
// 4 - TF2 moved to its own engine
#define SDK_LAUNCHER_VERSION 5
// Half-Life 2
defaultConfigInfo_t HL2Info =
{
"Half-Life 2",
"hl2",
"halflife2.fgd",
"info_player_start",
"hl2.exe",
GetAppSteamAppId( k_App_HL2 )
};
// Counter-Strike: Source
defaultConfigInfo_t CStrikeInfo =
{
"Counter-Strike: Source",
"cstrike",
"cstrike.fgd",
"info_player_terrorist",
"hl2.exe",
GetAppSteamAppId( k_App_CSS )
};
//Half-Life 2: Deathmatch
defaultConfigInfo_t HL2DMInfo =
{
"Half-Life 2: Deathmatch",
"hl2mp",
"hl2mp.fgd",
"info_player_deathmatch",
"hl2.exe",
GetAppSteamAppId( k_App_HL2MP )
};
// Day of Defeat: Source
defaultConfigInfo_t DODInfo =
{
"Day of Defeat: Source",
"dod",
"dod.fgd",
"info_player_allies",
"hl2.exe",
GetAppSteamAppId( k_App_DODS )
};
// Half-Life 2 Episode 1
defaultConfigInfo_t Episode1Info =
{
"Half-Life 2: Episode One",
"episodic",
"halflife2.fgd",
"info_player_start",
"hl2.exe",
GetAppSteamAppId( k_App_HL2_EP1 )
};
// Half-Life 2 Episode 2
defaultConfigInfo_t Episode2Info =
{
"Half-Life 2: Episode Two",
"ep2",
"halflife2.fgd",
"info_player_start",
"hl2.exe",
GetAppSteamAppId( k_App_HL2_EP2 )
};
// Team Fortress 2
defaultConfigInfo_t TF2Info =
{
"Team Fortress 2",
"tf",
"tf.fgd",
"info_player_teamspawn",
"hl2.exe",
GetAppSteamAppId( k_App_TF2 )
};
// Portal
defaultConfigInfo_t PortalInfo =
{
"Portal",
"portal",
"portal.fgd",
"info_player_start",
"hl2.exe",
GetAppSteamAppId( k_App_PORTAL )
};
// Portal
defaultConfigInfo_t SourceTestInfo =
{
"SourceTest",
"sourcetest",
"halflife2.fgd",
"info_player_start",
"hl2.exe",
243730
};
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CGameConfigManager::CGameConfigManager( void ) : m_pData( NULL ), m_LoadStatus( LOADSTATUS_NONE )
{
// Start with default directory
GetModuleFileName( ( HINSTANCE )GetModuleHandle( NULL ), m_szBaseDirectory, sizeof( m_szBaseDirectory ) );
Q_StripLastDir( m_szBaseDirectory, sizeof( m_szBaseDirectory ) ); // Get rid of the filename.
Q_StripTrailingSlash( m_szBaseDirectory );
m_eSDKEpoch = (eSDKEpochs) SDK_LAUNCHER_VERSION;
}
//-----------------------------------------------------------------------------
// Destructor
//-----------------------------------------------------------------------------
CGameConfigManager::~CGameConfigManager( void )
{
// Release the keyvalues
if ( m_pData != NULL )
{
m_pData->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose: Config loading interface
// Input : *baseDir - base directory for our file
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CGameConfigManager::LoadConfigs( const char *baseDir )
{
return LoadConfigsInternal( baseDir, false );
}
//-----------------------------------------------------------------------------
// Purpose: Loads a file into the given utlbuffer.
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool ReadUtlBufferFromFile( CUtlBuffer &buffer, const char *szPath )
{
struct _stat fileInfo;
if ( _stat( szPath, &fileInfo ) == -1 )
{
return false;
}
buffer.EnsureCapacity( fileInfo.st_size );
int nFile = _open( szPath, _O_BINARY | _O_RDONLY );
if ( nFile == -1 )
{
return false;
}
if ( _read( nFile, buffer.Base(), fileInfo.st_size ) != fileInfo.st_size )
{
_close( nFile );
return false;
}
_close( nFile );
buffer.SeekPut( CUtlBuffer::SEEK_HEAD, fileInfo.st_size );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Loads a file into the given utlbuffer.
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool SaveUtlBufferToFile( CUtlBuffer &buffer, const char *szPath )
{
int nFile = _open( szPath, _O_TEXT | _O_CREAT | _O_TRUNC | _O_RDWR, _S_IWRITE );
if ( nFile == -1 )
{
return false;
}
int nSize = buffer.TellMaxPut();
if ( _write( nFile, buffer.Base(), nSize ) < nSize )
{
_close( nFile );
return false;
}
_close( nFile );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Load a game configuration file (with fail-safes)
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CGameConfigManager::LoadConfigsInternal( const char *baseDir, bool bRecursiveCall )
{
// Init the config if it doesn't exist
if ( !IsLoaded() )
{
m_pData = new KeyValues( GAME_CONFIG_FILENAME );
if ( !IsLoaded() )
{
m_LoadStatus = LOADSTATUS_ERROR;
return false;
}
}
// Clear it out
m_pData->Clear();
// Build our default directory
if ( baseDir != NULL && baseDir[0] != NULL )
{
SetBaseDirectory( baseDir );
}
// Make a full path name
char szPath[MAX_PATH];
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s", GetBaseDirectory(), GAME_CONFIG_FILENAME );
bool bLoaded = false;
CUtlBuffer buffer( 0, 0, CUtlBuffer::TEXT_BUFFER );
if ( ReadUtlBufferFromFile( buffer, szPath ) )
{
bLoaded = m_pData->LoadFromBuffer( szPath, buffer, NULL, NULL );
}
if ( !bLoaded )
{
// Attempt to re-create the configs
if ( CreateAllDefaultConfigs() )
{
// Only allow this once
if ( !bRecursiveCall )
return LoadConfigsInternal( baseDir, true );
// Version the config.
VersionConfig();
}
m_LoadStatus = LOADSTATUS_ERROR;
return false;
}
else
{
// Check to see if the gameconfig.txt is up to date.
UpdateConfigsInternal();
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Add to the current config.
//-----------------------------------------------------------------------------
void CGameConfigManager::UpdateConfigsInternal( void )
{
// Check to a valid gameconfig.txt file buffer.
if ( !IsLoaded() )
return;
// Check for version first. If the version is up to date, it is assumed to be accurate
if ( IsConfigCurrent() )
return;
KeyValues *pGameBlock = GetGameBlock();
if ( !pGameBlock )
{
// If we don't have a game block, reset the config file.
ResetConfigs();
return;
}
KeyValues *pDefaultBlock = new KeyValues( "DefaultConfigs" );
if ( pDefaultBlock != NULL )
{
// Compile our default configurations
GetDefaultGameBlock( pDefaultBlock );
// Compare our default block to our current configs
KeyValues *pNextSubKey = pDefaultBlock->GetFirstTrueSubKey();
while ( pNextSubKey != NULL )
{
// If we already have the name, we don't care about it
if ( pGameBlock->FindKey( pNextSubKey->GetName() ) )
{
// Advance by one key
pNextSubKey = pNextSubKey->GetNextTrueSubKey();
continue;
}
// Copy the data through to our game block
KeyValues *pKeyCopy = pNextSubKey->MakeCopy();
pGameBlock->AddSubKey( pKeyCopy );
// Advance by one key
pNextSubKey = pNextSubKey->GetNextTrueSubKey();
}
// All done
pDefaultBlock->deleteThis();
}
// Save the new config.
SaveConfigs();
// Add the new version as we have been updated.
VersionConfig();
}
//-----------------------------------------------------------------------------
// Purpose: Update the gameconfig.txt version number.
//-----------------------------------------------------------------------------
void CGameConfigManager::VersionConfig( void )
{
// Check to a valid gameconfig.txt file buffer.
if ( !IsLoaded() )
return;
// Look for the a version key value pair and update it.
KeyValues *pKeyVersion = m_pData->FindKey( TOKEN_SDK_VERSION );
// Update the already existing version key value pair.
if ( pKeyVersion )
{
if ( pKeyVersion->GetInt() == m_eSDKEpoch )
return;
m_pData->SetInt( TOKEN_SDK_VERSION, m_eSDKEpoch );
}
// Create a new version key value pair.
else
{
m_pData->SetInt( TOKEN_SDK_VERSION, m_eSDKEpoch );
}
// Save the configuration.
SaveConfigs();
}
//-----------------------------------------------------------------------------
// Purpose: Check to see if the version of the gameconfig.txt is up to date.
//-----------------------------------------------------------------------------
bool CGameConfigManager::IsConfigCurrent( void )
{
// Check to a valid gameconfig.txt file buffer.
if ( !IsLoaded() )
return false;
KeyValues *pKeyValue = m_pData->FindKey( TOKEN_SDK_VERSION );
if ( !pKeyValue )
return false;
int nVersion = pKeyValue->GetInt();
if ( nVersion == m_eSDKEpoch )
return true;
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Get the base path for a default config's install (handling steam's paths)
//-----------------------------------------------------------------------------
void CGameConfigManager::GetRootGameDirectory( char *out, size_t outLen, const char *rootDir )
{
Q_strncpy( out, rootDir, outLen );
}
//-----------------------------------------------------------------------------
// Purpose: Get the base path for a default config's content sources (handling steam's paths)
//-----------------------------------------------------------------------------
void CGameConfigManager::GetRootContentDirectory( char *out, size_t outLen, const char *rootDir )
{
// Steam install is different
if ( g_pFullFileSystem )
{
Q_snprintf( out, outLen, "%s\\sourcesdk_content", rootDir );
}
else
{
Q_snprintf( out, outLen, "%s\\content", rootDir );
}
}
// Default game configuration template
const char szDefaultConfigText[] =
"\"%gamename%\"\
{\
\"GameDir\" \"%gamedir%\"\
\"Hammer\"\
{\
\"TextureFormat\" \"5\"\
\"MapFormat\" \"4\"\
\"DefaultTextureScale\" \"0.250000\"\
\"DefaultLightmapScale\" \"16\"\
\"DefaultSolidEntity\" \"func_detail\"\
\"DefaultPointEntity\" \"%defaultpointentity%\"\
\"GameExeDir\" \"%gameexe%\"\
\"MapDir\" \"%gamemaps%\"\
\"CordonTexture\" \"tools\\toolsskybox\"\
\"MaterialExcludeCount\" \"0\"\
\"GameExe\" \"%gameEXE%\"\
\"BSP\" \"%bspdir%\"\
\"Vis\" \"%visdir%\"\
\"Light\" \"%lightdir%\"\
}}";
// NOTE: This function could use some re-write, it can't handle non-retail paths well
//-----------------------------------------------------------------------------
// Purpose: Add a templated default configuration with proper paths
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CGameConfigManager::AddDefaultConfig( const defaultConfigInfo_t &info, KeyValues *out, const char *rootDirectory, const char *gameExeDir )
{
// NOTE: Freed by head keyvalue
KeyValues *newConfig = new KeyValues( info.gameName );
if ( newConfig->LoadFromBuffer( "defaultcfg.txt", szDefaultConfigText ) == false )
return false;
newConfig->SetName( info.gameName );
// Game's root directory (with special steam name handling)
char rootGameDir[MAX_PATH];
GetRootGameDirectory( rootGameDir, sizeof( rootGameDir ), rootDirectory );
// Game's content directory
char contentRootDir[MAX_PATH];
GetRootContentDirectory( contentRootDir, sizeof( contentRootDir ), rootDirectory );
char szPath[MAX_PATH];
// Game directory
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s", rootGameDir, info.gameDir );
if ( !g_pFullFileSystem->IsDirectory( szPath ) )
return false;
newConfig->SetString( "GameDir", szPath );
// Create the Hammer portion of this block
KeyValues *hammerBlock = newConfig->FindKey( "Hammer" );
if ( hammerBlock == NULL )
return false;
hammerBlock->SetString( "GameExeDir", gameExeDir );
// Fill in the proper default point entity
hammerBlock->SetString( "DefaultPointEntity", info.defaultPointEntity );
// Fill in the default VMF directory
char contentMapDir[MAX_PATH];
Q_snprintf( contentMapDir, sizeof( contentMapDir ), "%s\\%s\\mapsrc", contentRootDir, info.gameDir );
hammerBlock->SetString( "MapDir", contentMapDir );
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s\\maps", rootGameDir, info.gameDir );
hammerBlock->SetString( "BSPDir", szPath );
// Fill in the game executable
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s", gameExeDir, info.exeName );
hammerBlock->SetString( "GameEXE", szPath );
//Fill in game FGDs
if ( info.FGD[0] != '\0' )
{
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s", GetBaseDirectory(), info.FGD );
hammerBlock->SetString( "GameData0", szPath );
}
// Fill in the tools path
Q_snprintf( szPath, sizeof( szPath ), "%s\\vbsp.exe", GetBaseDirectory() );
hammerBlock->SetString( "BSP", szPath );
Q_snprintf( szPath, sizeof( szPath ), "%s\\vvis.exe", GetBaseDirectory() );
hammerBlock->SetString( "Vis", szPath );
Q_snprintf( szPath, sizeof( szPath ), "%s\\vrad.exe", GetBaseDirectory() );
hammerBlock->SetString( "Light", szPath );
// Get our insertion point
KeyValues *insertSpot = out->GetFirstTrueSubKey();
// Set this as the sub key if there's nothing already there
if ( insertSpot == NULL )
{
out->AddSubKey( newConfig );
}
else
{
// Find the last subkey
while ( insertSpot->GetNextTrueSubKey() )
{
insertSpot = insertSpot->GetNextTrueSubKey();
}
// Become a peer to it
insertSpot->SetNextKey( newConfig );
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Determines whether the requested appID is installed on this computer
// Input : nAppID - ID to verify
// Output : Returns true if installed, false if not.
//-----------------------------------------------------------------------------
bool CGameConfigManager::IsAppSubscribed( int nAppID )
{
bool bIsSubscribed = false;
if ( steamapicontext && steamapicontext->SteamApps() )
{
// See if specified app is installed
bIsSubscribed = steamapicontext->SteamApps()->BIsSubscribedApp( nAppID );
}
else
{
// If we aren't running FileSystem Steam then we must be doing internal development. Give everything.
bIsSubscribed = true;
}
return bIsSubscribed;
}
//-----------------------------------------------------------------------------
// Purpose: Create default configurations for all Valve retail applications
//-----------------------------------------------------------------------------
bool CGameConfigManager::CreateAllDefaultConfigs( void )
{
bool bRetVal = true;
// Start our new block
KeyValues *configBlock = new KeyValues( "Configs" );
KeyValues *gameBlock = configBlock->CreateNewKey();
gameBlock->SetName( "Games" );
GetDefaultGameBlock( gameBlock );
bRetVal = !gameBlock->IsEmpty();
// Make a full path name
char szPath[MAX_PATH];
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s", GetBaseDirectory(), GAME_CONFIG_FILENAME );
CUtlBuffer buffer;
configBlock->RecursiveSaveToFile( buffer, 0 );
SaveUtlBufferToFile( buffer, szPath );
configBlock->deleteThis();
m_LoadStatus = LOADSTATUS_CREATED;
return bRetVal;
}
//-----------------------------------------------------------------------------
// Purpose: Load game information from an INI file
//-----------------------------------------------------------------------------
bool CGameConfigManager::ConvertGameConfigsINI( void )
{
const char *iniFilePath = GetIniFilePath();
// Load our INI file
int nNumConfigs = GetPrivateProfileInt( "Configs", "NumConfigs", 0, iniFilePath );
if ( nNumConfigs <= 0 )
return false;
// Build a new keyvalue file
KeyValues *headBlock = new KeyValues( "Configs" );
// Create the block for games
KeyValues *gamesBlock = headBlock->CreateNewKey( );
gamesBlock->SetName( "Games" );
int i;
int nStrlen;
char szSectionName[MAX_PATH];
char textBuffer[MAX_PATH];
// Parse all the configs
for ( int nConfig = 0; nConfig < nNumConfigs; nConfig++ )
{
// Each came configuration is stored in a different section, named "GameConfig0..GameConfigN".
// If the "Name" key exists in this section, try to load the configuration from this section.
sprintf(szSectionName, "GameConfig%d", nConfig);
int nCount = GetPrivateProfileString(szSectionName, "Name", "", textBuffer, sizeof(textBuffer), iniFilePath);
if (nCount > 0)
{
// Make a new section
KeyValues *subGame = gamesBlock->CreateNewKey();
subGame->SetName( textBuffer );
GetPrivateProfileString( szSectionName, "ModDir", "", textBuffer, sizeof(textBuffer), iniFilePath);
// Add the mod dir
subGame->SetString( "GameDir", textBuffer );
// Start a block for Hammer settings
KeyValues *hammerBlock = subGame->CreateNewKey();
hammerBlock->SetName( "Hammer" );
i = 0;
// Get all FGDs
do
{
char szGameData[MAX_PATH];
sprintf( szGameData, "GameData%d", i );
nStrlen = GetPrivateProfileString( szSectionName, szGameData, "", textBuffer, sizeof(textBuffer), iniFilePath );
if ( nStrlen > 0 )
{
hammerBlock->SetString( szGameData, textBuffer );
i++;
}
} while ( nStrlen > 0 );
hammerBlock->SetInt( "TextureFormat", GetPrivateProfileInt( szSectionName, "TextureFormat", 5 /*FIXME: tfVMT*/, iniFilePath ) );
hammerBlock->SetInt( "MapFormat", GetPrivateProfileInt( szSectionName, "MapFormat", 4 /*FIXME: mfHalfLife2*/, iniFilePath ) );
// Default texture scale
GetPrivateProfileString( szSectionName, "DefaultTextureScale", "1", textBuffer, sizeof(textBuffer), iniFilePath );
float defaultTextureScale = (float) atof( textBuffer );
if ( defaultTextureScale == 0 )
{
defaultTextureScale = 1.0f;
}
hammerBlock->SetFloat( "DefaultTextureScale", defaultTextureScale );
hammerBlock->SetInt( "DefaultLightmapScale", GetPrivateProfileInt( szSectionName, "DefaultLightmapScale", 16 /*FIXME: DEFAULT_LIGHTMAP_SCALE*/, iniFilePath ) );
GetPrivateProfileString( szSectionName, "GameExe", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "GameExe", textBuffer );
GetPrivateProfileString( szSectionName, "DefaultSolidEntity", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "DefaultSolidEntity", textBuffer );
GetPrivateProfileString( szSectionName, "DefaultPointEntity", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "DefaultPointEntity", textBuffer );
GetPrivateProfileString( szSectionName, "BSP", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "BSP", textBuffer );
GetPrivateProfileString( szSectionName, "Vis", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "Vis", textBuffer );
GetPrivateProfileString( szSectionName, "Light", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "Light", textBuffer );
GetPrivateProfileString( szSectionName, "GameExeDir", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "GameExeDir", textBuffer );
GetPrivateProfileString( szSectionName, "MapDir", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "MapDir", textBuffer );
GetPrivateProfileString( szSectionName, "BSPDir", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "BSPDir", textBuffer );
GetPrivateProfileString( szSectionName, "CordonTexture", "", textBuffer, sizeof(textBuffer), iniFilePath );
hammerBlock->SetString( "CordonTexture", textBuffer );
GetPrivateProfileString( szSectionName, "MaterialExcludeCount", "0", textBuffer, sizeof(textBuffer), iniFilePath );
int materialExcludeCount = atoi( textBuffer );
hammerBlock->SetInt( "MaterialExcludeCount", materialExcludeCount );
char excludeDir[MAX_PATH];
// Write out all excluded directories
for( i = 0; i < materialExcludeCount; i++ )
{
sprintf( &excludeDir[0], "-MaterialExcludeDir%d", i );
GetPrivateProfileString( szSectionName, excludeDir, "", textBuffer, sizeof( textBuffer ), iniFilePath );
hammerBlock->SetString( excludeDir, textBuffer );
}
}
}
// Make a full path name
char szPath[MAX_PATH];
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s", GetBaseDirectory(), GAME_CONFIG_FILENAME );
CUtlBuffer buffer;
headBlock->RecursiveSaveToFile( buffer, 0 );
SaveUtlBufferToFile( buffer, szPath );
// Rename the old INI file
char newFilePath[MAX_PATH];
Q_snprintf( newFilePath, sizeof( newFilePath ), "%s.OLD", iniFilePath );
rename( iniFilePath, newFilePath );
// Notify that we were converted
m_LoadStatus = LOADSTATUS_CONVERTED;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Write out a game configuration file
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CGameConfigManager::SaveConfigs( const char *baseDir )
{
if ( !IsLoaded() )
return false;
// Build our default directory
if ( baseDir != NULL && baseDir[0] != NULL )
{
SetBaseDirectory( baseDir );
}
// Make a full path name
char szPath[MAX_PATH];
Q_strncpy( szPath, GetBaseDirectory(), sizeof(szPath) );
Q_AppendSlash( szPath, sizeof(szPath) );
Q_strncat( szPath, GAME_CONFIG_FILENAME, sizeof( szPath ), COPY_ALL_CHARACTERS );
CUtlBuffer buffer;
m_pData->RecursiveSaveToFile( buffer, 0 );
return SaveUtlBufferToFile( buffer, szPath );
}
//-----------------------------------------------------------------------------
// Purpose: Find the directory our .exe is based out of
//-----------------------------------------------------------------------------
const char *CGameConfigManager::GetBaseDirectory( void )
{
return m_szBaseDirectory;
}
//-----------------------------------------------------------------------------
// Purpose: Find the root directory
//-----------------------------------------------------------------------------
const char *CGameConfigManager::GetRootDirectory( void )
{
static char path[MAX_PATH] = {0};
if ( path[0] == 0 )
{
Q_strncpy( path, GetBaseDirectory(), sizeof( path ) );
Q_StripLastDir( path, sizeof( path ) ); // Get rid of the 'bin' directory
Q_StripTrailingSlash( path );
}
return path;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the game configuation block
//-----------------------------------------------------------------------------
KeyValues *CGameConfigManager::GetGameBlock( void )
{
if ( !IsLoaded() )
return NULL;
return ( m_pData->FindKey( TOKEN_GAMES, true ) );
}
//-----------------------------------------------------------------------------
// Purpose: Returns a piece of the game configuation block of the given name
// Input : *keyName - name of the block to return
//-----------------------------------------------------------------------------
KeyValues *CGameConfigManager::GetGameSubBlock( const char *keyName )
{
if ( !IsLoaded() )
return NULL;
KeyValues *pGameBlock = GetGameBlock();
if ( pGameBlock == NULL )
return NULL;
// Return the data
KeyValues *pSubBlock = pGameBlock->FindKey( keyName );
return pSubBlock;
}
//-----------------------------------------------------------------------------
// Purpose: Get the gamecfg.ini file for conversion
//-----------------------------------------------------------------------------
const char *CGameConfigManager::GetIniFilePath( void )
{
static char iniFilePath[MAX_PATH] = {0};
if ( iniFilePath[0] == 0 )
{
Q_strncpy( iniFilePath, GetBaseDirectory(), sizeof( iniFilePath ) );
Q_strncat( iniFilePath, "\\gamecfg.ini", sizeof( iniFilePath ), COPY_ALL_CHARACTERS );
}
return iniFilePath;
}
//-----------------------------------------------------------------------------
// Purpose: Deletes the current config and recreates it with default values
//-----------------------------------------------------------------------------
bool CGameConfigManager::ResetConfigs( const char *baseDir /*= NULL*/ )
{
// Build our default directory
if ( baseDir != NULL && baseDir[0] != NULL )
{
SetBaseDirectory( baseDir );
}
// Make a full path name
char szPath[MAX_PATH];
Q_snprintf( szPath, sizeof( szPath ), "%s\\%s", GetBaseDirectory(), GAME_CONFIG_FILENAME );
// Delete the file
if ( unlink( szPath ) )
return false;
// Load the file again (causes defaults to be created)
if ( LoadConfigsInternal( baseDir, false ) == false )
return false;
// Save it out
return SaveConfigs( baseDir );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGameConfigManager::SetBaseDirectory( const char *pDirectory )
{
// Clear it
if ( pDirectory == NULL || pDirectory[0] == '\0' )
{
m_szBaseDirectory[0] = '\0';
return;
}
// Copy it
Q_strncpy( m_szBaseDirectory, pDirectory, sizeof( m_szBaseDirectory ) );
Q_StripTrailingSlash( m_szBaseDirectory );
}
//-----------------------------------------------------------------------------
// Purpose: Create a block of keyvalues containing our default configurations
// Output : A block of keyvalues
//-----------------------------------------------------------------------------
bool CGameConfigManager::GetDefaultGameBlock( KeyValues *pIn )
{
CUtlVector<defaultConfigInfo_t> defaultConfigs;
// Add HL2 games to list
defaultConfigs.AddToTail( HL2DMInfo );
defaultConfigs.AddToTail( HL2Info );
defaultConfigs.AddToTail( Episode1Info );
defaultConfigs.AddToTail( Episode2Info );
defaultConfigs.AddToTail( PortalInfo );
defaultConfigs.AddToTail( SourceTestInfo );
// Add TF2 games to list
defaultConfigs.AddToTail( TF2Info );
defaultConfigs.AddToTail( DODInfo );
defaultConfigs.AddToTail( CStrikeInfo );
if ( pIn == NULL )
return false;
char szPath[MAX_PATH];
// Add all default configs
int nNumConfigs = defaultConfigs.Count();
for ( int i = 0; i < nNumConfigs; i++ )
{
// If it's installed, add it
if ( IsAppSubscribed( defaultConfigs[i].steamAppID ) )
{
GetRootGameDirectory( szPath, sizeof( szPath ), GetRootDirectory() );
AddDefaultConfig( defaultConfigs[i], pIn, GetRootDirectory(), szPath );
}
}
return true;
}

110
common/ConfigManager.h Normal file
View File

@ -0,0 +1,110 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef CONFIGMANAGER_H
#define CONFIGMANAGER_H
#ifdef _WIN32
#pragma once
#endif
#include "KeyValues.h"
#include "utlvector.h"
#include "filesystem_init.h"
// See filesystem_init for the vconfig registry values.
#define TOKEN_GAMES "Games"
#define TOKEN_GAME_DIRECTORY "GameDir"
#define TOKEN_TOOLS "Tools"
struct defaultConfigInfo_t
{
char gameName[MAX_PATH];
char gameDir[MAX_PATH];
char FGD[MAX_PATH];
char defaultPointEntity[MAX_PATH];
char exeName[MAX_PATH];
int steamAppID;
};
enum eSDKEpochs
{
HL2 = 1,
EP1 = 2,
EP2 = 3,
SP2009 = 4,
MP2009 = 5,
};
extern defaultConfigInfo_t *gDefaultConfigs[];
class CGameConfigManager
{
public:
enum loadStatus_t
{
LOADSTATUS_NONE = 0, // Configs were loaded with no error
LOADSTATUS_CONVERTED, // GameConfig.txt did not exist and was created by converting GameCfg.INI
LOADSTATUS_CREATED, // GameCfg.INI was not found, the system created the default configuration based on found GameInfo.txt resources
LOADSTATUS_ERROR, // File was not loaded and was unable to perform the above fail-safe procedures
};
CGameConfigManager( void );
CGameConfigManager( const char *fileName );
~CGameConfigManager( void );
bool LoadConfigs( const char *baseDir = NULL );
bool SaveConfigs( const char *baseDir = NULL );
bool ResetConfigs( const char *baseDir = NULL );
int GetNumConfigs( void );
KeyValues *GetGameBlock( void );
KeyValues *GetGameSubBlock( const char *keyName );
bool GetDefaultGameBlock( KeyValues *pIn );
bool IsLoaded( void ) const { return m_pData != NULL; }
bool WasConvertedOnLoad( void ) const { return m_LoadStatus == LOADSTATUS_CONVERTED; }
bool WasCreatedOnLoad( void ) const { return m_LoadStatus == LOADSTATUS_CREATED; }
bool AddDefaultConfig( const defaultConfigInfo_t &info, KeyValues *out, const char *rootDirectory, const char *gameExeDir );
void SetBaseDirectory( const char *pDirectory );
void GetRootGameDirectory( char *out, size_t outLen, const char *rootDir );
const char *GetRootDirectory( void );
void SetSDKEpoch( eSDKEpochs epoch ) { m_eSDKEpoch = epoch; };
private:
void GetRootContentDirectory( char *out, size_t outLen, const char *rootDir );
const char *GetBaseDirectory( void );
const char *GetIniFilePath( void );
bool LoadConfigsInternal( const char *baseDir, bool bRecursiveCall );
void UpdateConfigsInternal( void );
void VersionConfig( void );
bool IsConfigCurrent( void );
bool ConvertGameConfigsINI( void );
bool CreateAllDefaultConfigs( void );
bool IsAppSubscribed( int nAppID );
loadStatus_t m_LoadStatus; // Holds various state about what occured while loading
KeyValues *m_pData; // Data as read from configuration file
char m_szBaseDirectory[MAX_PATH]; // Default directory
eSDKEpochs m_eSDKEpoch; // Holds the "working version" of the SDK for times when we need to create an older set of game configurations.
// This is required now that the SDK is deploying the tools for both the latest and previous versions of the engine.
};
#endif // CONFIGMANAGER_H

94
common/FindSteamServers.h Normal file
View File

@ -0,0 +1,94 @@
//========= 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.
//
//*****************************************************************************
//
// Contents:
//
//
//
// Authors: Taylor Sherman
//
// Target restrictions:
//
// Tool restrictions:
//
// Things to do:
//
//
//
//*****************************************************************************
#ifndef INCLUDED_STEAM_FINDSTEAMSERVERS_H
#define INCLUDED_STEAM_FINDSTEAMSERVERS_H
#if defined(_MSC_VER) && (_MSC_VER > 1000)
#pragma once
#endif
#ifdef STEAM_FINDSERVERS_STATIC_LIB
#define STEAM_FSS_CALL
#define STEAM_FSS_API
#else
#ifndef STEAM_API
#ifdef STEAM_EXPORTS
#define STEAM_API __declspec(dllexport)
#else
#define STEAM_API __declspec(dllimport)
#endif
#endif
#ifndef STEAM_CALL
#define STEAM_CALL __cdecl
#endif
#define STEAM_FSS_CALL STEAM_CALL
#define STEAM_FSS_API STEAM_API
#endif
#include <limits.h>
#include "steamcommon.h"
/******************************************************************************
**
** Types
**
******************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
enum
{
eSteamFindSteamServersLibraryError = -1,
eSteamFindSteamServersLibraryBusy = -2
};
// returns number of IP addresses returned by the GDS for this server type
// negative return means error
STEAM_FSS_API int STEAM_FSS_CALL SteamFindServersNumServers(ESteamServerType eServerType);
// Get nth ipaddr:port for this server type
// buffer needs to be 22 chars long: aaa.bbb.ccc.ddd:12345 plus null
//
// returns 0 if succsessful, negative is error
STEAM_FSS_API int STEAM_FSS_CALL SteamFindServersIterateServer(ESteamServerType eServerType, unsigned int nServer, char *szIpAddrPort, int szIpAddrPortLen);
STEAM_FSS_API const char * STEAM_FSS_CALL SteamFindServersGetErrorString();
#ifdef __cplusplus
}
#endif
#endif /* #ifndef INCLUDED_STEAM_COMMON_STEAMCOMMON_H */

2241
common/GL/gl.h Normal file

File diff suppressed because it is too large Load Diff

1985
common/GL/gl_mangle.h Normal file

File diff suppressed because it is too large Load Diff

11028
common/GL/glext.h Normal file

File diff suppressed because it is too large Load Diff

353
common/GL/glu.h Normal file
View File

@ -0,0 +1,353 @@
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice including the dates of first publication and
* either this permission notice or a reference to
* http://oss.sgi.com/projects/FreeB/
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of Silicon Graphics, Inc.
* shall not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization from
* Silicon Graphics, Inc.
*/
#ifndef __glu_h__
#define __glu_h__
#if defined(USE_MGL_NAMESPACE)
#include "glu_mangle.h"
#endif
#include <GL/gl.h>
#ifndef GLAPIENTRY
#if defined(_MSC_VER) || defined(__MINGW32__)
#define GLAPIENTRY __stdcall
#else
#define GLAPIENTRY
#endif
#endif
#ifndef GLAPIENTRYP
#define GLAPIENTRYP GLAPIENTRY *
#endif
#if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GLU32)
# undef GLAPI
# define GLAPI __declspec(dllexport)
#elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL)
/* tag specifying we're building for DLL runtime support */
# undef GLAPI
# define GLAPI __declspec(dllimport)
#elif !defined(GLAPI)
/* for use with static link lib build of Win32 edition only */
# define GLAPI extern
#endif /* _STATIC_MESA support */
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************/
/* Extensions */
#define GLU_EXT_object_space_tess 1
#define GLU_EXT_nurbs_tessellator 1
/* Boolean */
#define GLU_FALSE 0
#define GLU_TRUE 1
/* Version */
#define GLU_VERSION_1_1 1
#define GLU_VERSION_1_2 1
#define GLU_VERSION_1_3 1
/* StringName */
#define GLU_VERSION 100800
#define GLU_EXTENSIONS 100801
/* ErrorCode */
#define GLU_INVALID_ENUM 100900
#define GLU_INVALID_VALUE 100901
#define GLU_OUT_OF_MEMORY 100902
#define GLU_INCOMPATIBLE_GL_VERSION 100903
#define GLU_INVALID_OPERATION 100904
/* NurbsDisplay */
/* GLU_FILL */
#define GLU_OUTLINE_POLYGON 100240
#define GLU_OUTLINE_PATCH 100241
/* NurbsCallback */
#define GLU_NURBS_ERROR 100103
#define GLU_ERROR 100103
#define GLU_NURBS_BEGIN 100164
#define GLU_NURBS_BEGIN_EXT 100164
#define GLU_NURBS_VERTEX 100165
#define GLU_NURBS_VERTEX_EXT 100165
#define GLU_NURBS_NORMAL 100166
#define GLU_NURBS_NORMAL_EXT 100166
#define GLU_NURBS_COLOR 100167
#define GLU_NURBS_COLOR_EXT 100167
#define GLU_NURBS_TEXTURE_COORD 100168
#define GLU_NURBS_TEX_COORD_EXT 100168
#define GLU_NURBS_END 100169
#define GLU_NURBS_END_EXT 100169
#define GLU_NURBS_BEGIN_DATA 100170
#define GLU_NURBS_BEGIN_DATA_EXT 100170
#define GLU_NURBS_VERTEX_DATA 100171
#define GLU_NURBS_VERTEX_DATA_EXT 100171
#define GLU_NURBS_NORMAL_DATA 100172
#define GLU_NURBS_NORMAL_DATA_EXT 100172
#define GLU_NURBS_COLOR_DATA 100173
#define GLU_NURBS_COLOR_DATA_EXT 100173
#define GLU_NURBS_TEXTURE_COORD_DATA 100174
#define GLU_NURBS_TEX_COORD_DATA_EXT 100174
#define GLU_NURBS_END_DATA 100175
#define GLU_NURBS_END_DATA_EXT 100175
/* NurbsError */
#define GLU_NURBS_ERROR1 100251
#define GLU_NURBS_ERROR2 100252
#define GLU_NURBS_ERROR3 100253
#define GLU_NURBS_ERROR4 100254
#define GLU_NURBS_ERROR5 100255
#define GLU_NURBS_ERROR6 100256
#define GLU_NURBS_ERROR7 100257
#define GLU_NURBS_ERROR8 100258
#define GLU_NURBS_ERROR9 100259
#define GLU_NURBS_ERROR10 100260
#define GLU_NURBS_ERROR11 100261
#define GLU_NURBS_ERROR12 100262
#define GLU_NURBS_ERROR13 100263
#define GLU_NURBS_ERROR14 100264
#define GLU_NURBS_ERROR15 100265
#define GLU_NURBS_ERROR16 100266
#define GLU_NURBS_ERROR17 100267
#define GLU_NURBS_ERROR18 100268
#define GLU_NURBS_ERROR19 100269
#define GLU_NURBS_ERROR20 100270
#define GLU_NURBS_ERROR21 100271
#define GLU_NURBS_ERROR22 100272
#define GLU_NURBS_ERROR23 100273
#define GLU_NURBS_ERROR24 100274
#define GLU_NURBS_ERROR25 100275
#define GLU_NURBS_ERROR26 100276
#define GLU_NURBS_ERROR27 100277
#define GLU_NURBS_ERROR28 100278
#define GLU_NURBS_ERROR29 100279
#define GLU_NURBS_ERROR30 100280
#define GLU_NURBS_ERROR31 100281
#define GLU_NURBS_ERROR32 100282
#define GLU_NURBS_ERROR33 100283
#define GLU_NURBS_ERROR34 100284
#define GLU_NURBS_ERROR35 100285
#define GLU_NURBS_ERROR36 100286
#define GLU_NURBS_ERROR37 100287
/* NurbsProperty */
#define GLU_AUTO_LOAD_MATRIX 100200
#define GLU_CULLING 100201
#define GLU_SAMPLING_TOLERANCE 100203
#define GLU_DISPLAY_MODE 100204
#define GLU_PARAMETRIC_TOLERANCE 100202
#define GLU_SAMPLING_METHOD 100205
#define GLU_U_STEP 100206
#define GLU_V_STEP 100207
#define GLU_NURBS_MODE 100160
#define GLU_NURBS_MODE_EXT 100160
#define GLU_NURBS_TESSELLATOR 100161
#define GLU_NURBS_TESSELLATOR_EXT 100161
#define GLU_NURBS_RENDERER 100162
#define GLU_NURBS_RENDERER_EXT 100162
/* NurbsSampling */
#define GLU_OBJECT_PARAMETRIC_ERROR 100208
#define GLU_OBJECT_PARAMETRIC_ERROR_EXT 100208
#define GLU_OBJECT_PATH_LENGTH 100209
#define GLU_OBJECT_PATH_LENGTH_EXT 100209
#define GLU_PATH_LENGTH 100215
#define GLU_PARAMETRIC_ERROR 100216
#define GLU_DOMAIN_DISTANCE 100217
/* NurbsTrim */
#define GLU_MAP1_TRIM_2 100210
#define GLU_MAP1_TRIM_3 100211
/* QuadricDrawStyle */
#define GLU_POINT 100010
#define GLU_LINE 100011
#define GLU_FILL 100012
#define GLU_SILHOUETTE 100013
/* QuadricCallback */
/* GLU_ERROR */
/* QuadricNormal */
#define GLU_SMOOTH 100000
#define GLU_FLAT 100001
#define GLU_NONE 100002
/* QuadricOrientation */
#define GLU_OUTSIDE 100020
#define GLU_INSIDE 100021
/* TessCallback */
#define GLU_TESS_BEGIN 100100
#define GLU_BEGIN 100100
#define GLU_TESS_VERTEX 100101
#define GLU_VERTEX 100101
#define GLU_TESS_END 100102
#define GLU_END 100102
#define GLU_TESS_ERROR 100103
#define GLU_TESS_EDGE_FLAG 100104
#define GLU_EDGE_FLAG 100104
#define GLU_TESS_COMBINE 100105
#define GLU_TESS_BEGIN_DATA 100106
#define GLU_TESS_VERTEX_DATA 100107
#define GLU_TESS_END_DATA 100108
#define GLU_TESS_ERROR_DATA 100109
#define GLU_TESS_EDGE_FLAG_DATA 100110
#define GLU_TESS_COMBINE_DATA 100111
/* TessContour */
#define GLU_CW 100120
#define GLU_CCW 100121
#define GLU_INTERIOR 100122
#define GLU_EXTERIOR 100123
#define GLU_UNKNOWN 100124
/* TessProperty */
#define GLU_TESS_WINDING_RULE 100140
#define GLU_TESS_BOUNDARY_ONLY 100141
#define GLU_TESS_TOLERANCE 100142
/* TessError */
#define GLU_TESS_ERROR1 100151
#define GLU_TESS_ERROR2 100152
#define GLU_TESS_ERROR3 100153
#define GLU_TESS_ERROR4 100154
#define GLU_TESS_ERROR5 100155
#define GLU_TESS_ERROR6 100156
#define GLU_TESS_ERROR7 100157
#define GLU_TESS_ERROR8 100158
#define GLU_TESS_MISSING_BEGIN_POLYGON 100151
#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152
#define GLU_TESS_MISSING_END_POLYGON 100153
#define GLU_TESS_MISSING_END_CONTOUR 100154
#define GLU_TESS_COORD_TOO_LARGE 100155
#define GLU_TESS_NEED_COMBINE_CALLBACK 100156
/* TessWinding */
#define GLU_TESS_WINDING_ODD 100130
#define GLU_TESS_WINDING_NONZERO 100131
#define GLU_TESS_WINDING_POSITIVE 100132
#define GLU_TESS_WINDING_NEGATIVE 100133
#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134
/*************************************************************/
#ifdef __cplusplus
class GLUnurbs;
class GLUquadric;
class GLUtesselator;
#else
typedef struct GLUnurbs GLUnurbs;
typedef struct GLUquadric GLUquadric;
typedef struct GLUtesselator GLUtesselator;
#endif
typedef GLUnurbs GLUnurbsObj;
typedef GLUquadric GLUquadricObj;
typedef GLUtesselator GLUtesselatorObj;
typedef GLUtesselator GLUtriangulatorObj;
#define GLU_TESS_MAX_COORD 1.0e150
/* Internal convenience typedefs */
typedef void (GLAPIENTRYP _GLUfuncptr)();
GLAPI void GLAPIENTRY gluBeginCurve (GLUnurbs* nurb);
GLAPI void GLAPIENTRY gluBeginPolygon (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluBeginSurface (GLUnurbs* nurb);
GLAPI void GLAPIENTRY gluBeginTrim (GLUnurbs* nurb);
GLAPI GLint GLAPIENTRY gluBuild1DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
GLAPI GLint GLAPIENTRY gluBuild1DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, const void *data);
GLAPI GLint GLAPIENTRY gluBuild2DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
GLAPI GLint GLAPIENTRY gluBuild2DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
GLAPI GLint GLAPIENTRY gluBuild3DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
GLAPI GLint GLAPIENTRY gluBuild3DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
GLAPI GLboolean GLAPIENTRY gluCheckExtension (const GLubyte *extName, const GLubyte *extString);
GLAPI void GLAPIENTRY gluCylinder (GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks);
GLAPI void GLAPIENTRY gluDeleteNurbsRenderer (GLUnurbs* nurb);
GLAPI void GLAPIENTRY gluDeleteQuadric (GLUquadric* quad);
GLAPI void GLAPIENTRY gluDeleteTess (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops);
GLAPI void GLAPIENTRY gluEndCurve (GLUnurbs* nurb);
GLAPI void GLAPIENTRY gluEndPolygon (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluEndSurface (GLUnurbs* nurb);
GLAPI void GLAPIENTRY gluEndTrim (GLUnurbs* nurb);
GLAPI const GLubyte * GLAPIENTRY gluErrorString (GLenum error);
GLAPI void GLAPIENTRY gluGetNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat* data);
GLAPI const GLubyte * GLAPIENTRY gluGetString (GLenum name);
GLAPI void GLAPIENTRY gluGetTessProperty (GLUtesselator* tess, GLenum which, GLdouble* data);
GLAPI void GLAPIENTRY gluLoadSamplingMatrices (GLUnurbs* nurb, const GLfloat *model, const GLfloat *perspective, const GLint *view);
GLAPI void GLAPIENTRY gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ);
GLAPI GLUnurbs* GLAPIENTRY gluNewNurbsRenderer (void);
GLAPI GLUquadric* GLAPIENTRY gluNewQuadric (void);
GLAPI GLUtesselator* GLAPIENTRY gluNewTess (void);
GLAPI void GLAPIENTRY gluNextContour (GLUtesselator* tess, GLenum type);
GLAPI void GLAPIENTRY gluNurbsCallback (GLUnurbs* nurb, GLenum which, _GLUfuncptr CallBackFunc);
GLAPI void GLAPIENTRY gluNurbsCallbackData (GLUnurbs* nurb, GLvoid* userData);
GLAPI void GLAPIENTRY gluNurbsCallbackDataEXT (GLUnurbs* nurb, GLvoid* userData);
GLAPI void GLAPIENTRY gluNurbsCurve (GLUnurbs* nurb, GLint knotCount, GLfloat *knots, GLint stride, GLfloat *control, GLint order, GLenum type);
GLAPI void GLAPIENTRY gluNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat value);
GLAPI void GLAPIENTRY gluNurbsSurface (GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type);
GLAPI void GLAPIENTRY gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);
GLAPI void GLAPIENTRY gluPartialDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops, GLdouble start, GLdouble sweep);
GLAPI void GLAPIENTRY gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
GLAPI void GLAPIENTRY gluPickMatrix (GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint *viewport);
GLAPI GLint GLAPIENTRY gluProject (GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ);
GLAPI void GLAPIENTRY gluPwlCurve (GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type);
GLAPI void GLAPIENTRY gluQuadricCallback (GLUquadric* quad, GLenum which, _GLUfuncptr CallBackFunc);
GLAPI void GLAPIENTRY gluQuadricDrawStyle (GLUquadric* quad, GLenum draw);
GLAPI void GLAPIENTRY gluQuadricNormals (GLUquadric* quad, GLenum normal);
GLAPI void GLAPIENTRY gluQuadricOrientation (GLUquadric* quad, GLenum orientation);
GLAPI void GLAPIENTRY gluQuadricTexture (GLUquadric* quad, GLboolean texture);
GLAPI GLint GLAPIENTRY gluScaleImage (GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut);
GLAPI void GLAPIENTRY gluSphere (GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks);
GLAPI void GLAPIENTRY gluTessBeginContour (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluTessBeginPolygon (GLUtesselator* tess, GLvoid* data);
GLAPI void GLAPIENTRY gluTessCallback (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc);
GLAPI void GLAPIENTRY gluTessEndContour (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluTessEndPolygon (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluTessNormal (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ);
GLAPI void GLAPIENTRY gluTessProperty (GLUtesselator* tess, GLenum which, GLdouble data);
GLAPI void GLAPIENTRY gluTessVertex (GLUtesselator* tess, GLdouble *location, GLvoid* data);
GLAPI GLint GLAPIENTRY gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ);
GLAPI GLint GLAPIENTRY gluUnProject4 (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW);
#ifdef __cplusplus
}
#endif
#endif /* __glu_h__ */

86
common/GL/glu_mangle.h Normal file
View File

@ -0,0 +1,86 @@
/*
* Mesa 3-D graphics library
* Version: 3.0
* Copyright (C) 1995-1998 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef GLU_MANGLE_H
#define GLU_MANGLE_H
#define gluLookAt mgluLookAt
#define gluOrtho2D mgluOrtho2D
#define gluPerspective mgluPerspective
#define gluPickMatrix mgluPickMatrix
#define gluProject mgluProject
#define gluUnProject mgluUnProject
#define gluErrorString mgluErrorString
#define gluScaleImage mgluScaleImage
#define gluBuild1DMipmaps mgluBuild1DMipmaps
#define gluBuild2DMipmaps mgluBuild2DMipmaps
#define gluNewQuadric mgluNewQuadric
#define gluDeleteQuadric mgluDeleteQuadric
#define gluQuadricDrawStyle mgluQuadricDrawStyle
#define gluQuadricOrientation mgluQuadricOrientation
#define gluQuadricNormals mgluQuadricNormals
#define gluQuadricTexture mgluQuadricTexture
#define gluQuadricCallback mgluQuadricCallback
#define gluCylinder mgluCylinder
#define gluSphere mgluSphere
#define gluDisk mgluDisk
#define gluPartialDisk mgluPartialDisk
#define gluNewNurbsRenderer mgluNewNurbsRenderer
#define gluDeleteNurbsRenderer mgluDeleteNurbsRenderer
#define gluLoadSamplingMatrices mgluLoadSamplingMatrices
#define gluNurbsProperty mgluNurbsProperty
#define gluGetNurbsProperty mgluGetNurbsProperty
#define gluBeginCurve mgluBeginCurve
#define gluEndCurve mgluEndCurve
#define gluNurbsCurve mgluNurbsCurve
#define gluBeginSurface mgluBeginSurface
#define gluEndSurface mgluEndSurface
#define gluNurbsSurface mgluNurbsSurface
#define gluBeginTrim mgluBeginTrim
#define gluEndTrim mgluEndTrim
#define gluPwlCurve mgluPwlCurve
#define gluNurbsCallback mgluNurbsCallback
#define gluNewTess mgluNewTess
#define gluDeleteTess mgluDeleteTess
#define gluTessBeginPolygon mgluTessBeginPolygon
#define gluTessBeginContour mgluTessBeginContour
#define gluTessVertex mgluTessVertex
#define gluTessEndPolygon mgluTessEndPolygon
#define gluTessEndContour mgluTessEndContour
#define gluTessProperty mgluTessProperty
#define gluTessNormal mgluTessNormal
#define gluTessCallback mgluTessCallback
#define gluGetTessProperty mgluGetTessProperty
#define gluBeginPolygon mgluBeginPolygon
#define gluNextContour mgluNextContour
#define gluEndPolygon mgluEndPolygon
#define gluGetString mgluGetString
#define gluBuild1DMipmapLevels mgluBuild1DMipmapLevels
#define gluBuild2DMipmapLevels mgluBuild2DMipmapLevels
#define gluBuild3DMipmapLevels mgluBuild3DMipmapLevels
#define gluBuild3DMipmaps mgluBuild3DMipmaps
#define gluCheckExtension mgluCheckExtension
#define gluUnProject4 mgluUnProject4
#define gluNurbsCallbackData mgluNurbsCallbackData
#define gluNurbsCallbackDataEXT mgluNurbsCallbackDataEXT
#endif

View File

@ -0,0 +1,41 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#ifndef IGAMECONSOLE_H
#define IGAMECONSOLE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/interface.h"
//-----------------------------------------------------------------------------
// Purpose: interface to game/dev console
//-----------------------------------------------------------------------------
abstract_class IGameConsole : public IBaseInterface
{
public:
// activates the console, makes it visible and brings it to the foreground
virtual void Activate() = 0;
virtual void Initialize() = 0;
// hides the console
virtual void Hide() = 0;
// clears the console
virtual void Clear() = 0;
// return true if the console has focus
virtual bool IsConsoleVisible() = 0;
virtual void SetParent( int parent ) = 0;
};
#define GAMECONSOLE_INTERFACE_VERSION "GameConsole004"
#endif // IGAMECONSOLE_H

121
common/GameUI/IGameUI.h Normal file
View File

@ -0,0 +1,121 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef IGAMEUI_H
#define IGAMEUI_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include "vgui/IPanel.h"
#if !defined( _X360 )
#include "xbox/xboxstubs.h"
#endif
// reasons why the user can't connect to a game server
enum ESteamLoginFailure
{
STEAMLOGINFAILURE_NONE,
STEAMLOGINFAILURE_BADTICKET,
STEAMLOGINFAILURE_NOSTEAMLOGIN,
STEAMLOGINFAILURE_VACBANNED,
STEAMLOGINFAILURE_LOGGED_IN_ELSEWHERE
};
enum ESystemNotify
{
SYSTEMNOTIFY_STORAGEDEVICES_CHANGED,
SYSTEMNOTIFY_USER_SIGNEDIN,
SYSTEMNOTIFY_USER_SIGNEDOUT,
SYSTEMNOTIFY_XUIOPENING,
SYSTEMNOTIFY_XUICLOSED,
SYSTEMNOTIFY_INVITE_SHUTDOWN, // Cross-game invite is causing us to shutdown
};
//-----------------------------------------------------------------------------
// Purpose: contains all the functions that the GameUI dll exports
//-----------------------------------------------------------------------------
abstract_class IGameUI
{
public:
// initialization/shutdown
virtual void Initialize( CreateInterfaceFn appFactory ) = 0;
virtual void PostInit() = 0;
// connect to other interfaces at the same level (gameui.dll/server.dll/client.dll)
virtual void Connect( CreateInterfaceFn gameFactory ) = 0;
virtual void Start() = 0;
virtual void Shutdown() = 0;
virtual void RunFrame() = 0;
// notifications
virtual void OnGameUIActivated() = 0;
virtual void OnGameUIHidden() = 0;
// OLD: Use OnConnectToServer2
virtual void OLD_OnConnectToServer(const char *game, int IP, int port) = 0;
virtual void OnDisconnectFromServer_OLD( uint8 eSteamLoginFailure, const char *username ) = 0;
virtual void OnLevelLoadingStarted(bool bShowProgressDialog) = 0;
virtual void OnLevelLoadingFinished(bool bError, const char *failureReason, const char *extendedReason) = 0;
// level loading progress, returns true if the screen needs updating
virtual bool UpdateProgressBar(float progress, const char *statusText) = 0;
// Shows progress desc, returns previous setting... (used with custom progress bars )
virtual bool SetShowProgressText( bool show ) = 0;
// !!!!!!!!!members added after "GameUI011" initial release!!!!!!!!!!!!!!!!!!!
virtual void ShowNewGameDialog( int chapter ) = 0;
// Xbox 360
virtual void SessionNotification( const int notification, const int param = 0 ) = 0;
virtual void SystemNotification( const int notification ) = 0;
virtual void ShowMessageDialog( const uint nType, vgui::Panel *pOwner ) = 0;
virtual void UpdatePlayerInfo( uint64 nPlayerId, const char *pName, int nTeam, byte cVoiceState, int nPlayersNeeded, bool bHost ) = 0;
virtual void SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping ) = 0;
virtual void OnCreditsFinished( void ) = 0;
// inserts specified panel as background for level load dialog
virtual void SetLoadingBackgroundDialog( vgui::VPANEL panel ) = 0;
// Bonus maps interfaces
virtual void BonusMapUnlock( const char *pchFileName = NULL, const char *pchMapName = NULL ) = 0;
virtual void BonusMapComplete( const char *pchFileName = NULL, const char *pchMapName = NULL ) = 0;
virtual void BonusMapChallengeUpdate( const char *pchFileName, const char *pchMapName, const char *pchChallengeName, int iBest ) = 0;
virtual void BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName ) = 0;
virtual void BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold ) = 0;
virtual void BonusMapDatabaseSave( void ) = 0;
virtual int BonusMapNumAdvancedCompleted( void ) = 0;
virtual void BonusMapNumMedals( int piNumMedals[ 3 ] ) = 0;
virtual void OnConnectToServer2(const char *game, int IP, int connectionPort, int queryPort) = 0;
// X360 Storage device validation:
// returns true right away if storage device has been previously selected.
// otherwise returns false and will set the variable pointed by pStorageDeviceValidated to 1
// once the storage device is selected by user.
virtual bool ValidateStorageDevice( int *pStorageDeviceValidated ) = 0;
virtual void SetProgressOnStart() = 0;
virtual void OnDisconnectFromServer( uint8 eSteamLoginFailure ) = 0;
virtual void OnConfirmQuit( void ) = 0;
virtual bool IsMainMenuVisible( void ) = 0;
// Client DLL is providing us with a panel that it wants to replace the main menu with
virtual void SetMainMenuOverride( vgui::VPANEL panel ) = 0;
// Client DLL is telling us that a main menu command was issued, probably from its custom main menu panel
virtual void SendMainMenuCommand( const char *pszCommand ) = 0;
};
#define GAMEUI_INTERFACE_VERSION "GameUI011"
#endif // IGAMEUI_H

View File

@ -0,0 +1,243 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include <stdio.h>
#include <malloc.h>
#include "ObjectList.h"
#include "tier1/strtools.h"
//#include "port.h"
//#include "mem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ObjectList::ObjectList()
{
head = tail = current = NULL;
number = 0;
}
ObjectList::~ObjectList()
{
Clear( false );
}
bool ObjectList::AddHead(void * newObject)
{
// create new element
element_t * newElement = (element_t *) calloc(1, sizeof(element_t));
if (newElement == NULL )
return false; // out of memory
// insert element
newElement->object = newObject;
if (head)
{
newElement->next = head;
head->prev = newElement;
};
head = newElement;
// if list was empty set new tail
if (tail==NULL) tail = head;
number++;
return true;
}
void * ObjectList::RemoveHead()
{
void * retObj;
// check head is present
if (head)
{
retObj = head->object;
element_t * newHead = head->next;
if (newHead) newHead->prev = NULL;
// if only one element is in list also update tail
// if we remove this prev element
if (tail==head) tail = NULL;
free(head);
head = newHead;
number--;
} else
retObj = NULL;
return retObj;
}
bool ObjectList::AddTail(void * newObject)
{
element_t * newElement = (element_t *) calloc(1, sizeof(element_t));
if (newElement == NULL)
return false; // out of memory;
newElement->object = newObject;
if (tail)
{
newElement->prev = tail;
tail->next = newElement;
}
tail = newElement;
// if list was empty set new head
if (head==NULL) head = tail;
number++;
return true;
}
void * ObjectList::RemoveTail()
{
void * retObj;
// check tail is present
if (tail)
{
retObj = tail->object;
element_t * newTail = tail->prev;
if (newTail) newTail->next = NULL;
// if only one element is in list also update tail
// if we remove this prev element
if (head==tail) head = NULL;
free(tail);
tail = newTail;
number--;
} else
retObj = NULL;
return retObj;
}
bool ObjectList::IsEmpty()
{
return ( head == NULL );
}
int ObjectList::CountElements()
{
return number;
}
bool ObjectList::Contains(void * object)
{
element_t * e = head;
while(e && e->object!=object) { e = e->next;}
if ( e )
{
current = e;
return true;
}
else
{
return false;
}
}
void ObjectList::Clear( bool freeElementsMemory )
{
element_t * ne;
element_t * e = head;
while(e)
{
ne = e->next;
if ( freeElementsMemory && e->object )
free( e->object );
free(e);
e = ne;
}
head = tail = current = NULL;
number = 0;
}
bool ObjectList::Remove( void * object )
{
element_t * e = head;
while(e && e->object!=object) { e = e->next;}
if (e!=NULL)
{
if (e->prev) e->prev->next = e->next;
if (e->next) e->next->prev = e->prev;
if (head==e) head = e->next;
if (tail==e) tail = e->prev;
if (current == e) current= e->next;
free(e);
number--;
}
return (e!=NULL);
}
void ObjectList::Init()
{
head = tail = current = NULL;
number = 0;
}
void * ObjectList::GetFirst()
{
if (head)
{
current = head->next;
return head->object;
}
else
{
current = NULL;
return NULL;
};
}
void * ObjectList::GetNext()
{
void * retObj = NULL;
if (current)
{
retObj = current->object;
current = current->next;
}
return retObj;
}
bool ObjectList::Add(void *newObject)
{
return AddTail( newObject );
}

View File

@ -0,0 +1,58 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// ObjectList.h: interface for the ObjectList class.
//
//////////////////////////////////////////////////////////////////////
#ifndef OBJECTLIST_H
#define OBJECTLIST_H
#pragma once
#include "IObjectContainer.h" // Added by ClassView
class ObjectList : public IObjectContainer
{
public:
void Init();
bool Add( void * newObject );
void * GetFirst();
void * GetNext();
ObjectList();
virtual ~ObjectList();
void Clear( bool freeElementsMemory );
int CountElements();
void * RemoveTail();
void * RemoveHead();
bool AddTail(void * newObject);
bool AddHead(void * newObject);
bool Remove(void * object);
bool Contains(void * object);
bool IsEmpty();
typedef struct element_s {
element_s * prev; // pointer to the last element or NULL
element_s * next; // pointer to the next elemnet or NULL
void * object; // the element's object
} element_t;
protected:
element_t * head; // first element in list
element_t * tail; // last element in list
element_t * current; // current element in list
int number;
};
#endif // !defined

131
common/GameUI/Random.cpp Normal file
View File

@ -0,0 +1,131 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Basic random number generator
//
// $NoKeywords: $
//===========================================================================//
#include <time.h>
#include "Random.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define IA 16807
#define IM 2147483647
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
static long idum = 0;
void SeedRandomNumberGenerator(long lSeed)
{
if (lSeed)
{
idum = lSeed;
}
else
{
idum = -time(NULL);
}
if (1000 < idum)
{
idum = -idum;
}
else if (-1000 < idum)
{
idum -= 22261048;
}
}
long ran1(void)
{
int j;
long k;
static long iy=0;
static long iv[NTAB];
if (idum <= 0 || !iy)
{
if (-(idum) < 1) idum=1;
else idum = -(idum);
for (j=NTAB+7;j>=0;j--)
{
k=(idum)/IQ;
idum=IA*(idum-k*IQ)-IR*k;
if (idum < 0) idum += IM;
if (j < NTAB) iv[j] = idum;
}
iy=iv[0];
}
k=(idum)/IQ;
idum=IA*(idum-k*IQ)-IR*k;
if (idum < 0) idum += IM;
j=iy/NDIV;
iy=iv[j];
iv[j] = idum;
return iy;
}
// fran1 -- return a random floating-point number on the interval [0,1)
//
#define AM (1.0/IM)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float fran1(void)
{
float temp = (float)AM*ran1();
if (temp > RNMX) return (float)RNMX;
else return temp;
}
#ifndef _XBOX
float RandomFloat( float flLow, float flHigh )
{
if (idum == 0)
{
SeedRandomNumberGenerator(0);
}
float fl = fran1(); // float in [0,1)
return (fl * (flHigh-flLow)) + flLow; // float in [low,high)
}
#endif
long RandomLong( long lLow, long lHigh )
{
if (idum == 0)
{
SeedRandomNumberGenerator(0);
}
unsigned long maxAcceptable;
unsigned long x = lHigh-lLow+1;
unsigned long n;
if (x <= 0 || MAX_RANDOM_RANGE < x-1)
{
return lLow;
}
// The following maps a uniform distribution on the interval [0,MAX_RANDOM_RANGE]
// to a smaller, client-specified range of [0,x-1] in a way that doesn't bias
// the uniform distribution unfavorably. Even for a worst case x, the loop is
// guaranteed to be taken no more than half the time, so for that worst case x,
// the average number of times through the loop is 2. For cases where x is
// much smaller than MAX_RANDOM_RANGE, the average number of times through the
// loop is very close to 1.
//
maxAcceptable = MAX_RANDOM_RANGE - ((MAX_RANDOM_RANGE+1) % x );
do
{
n = ran1();
} while (n > maxAcceptable);
return lLow + (n % x);
}

30
common/GameUI/Random.h Normal file
View File

@ -0,0 +1,30 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Generalized 32-bit random number generator
// Range is 0x00000000 - 0x7FFFFFFF
//
// $NoKeywords: $
//=============================================================================//
#ifndef RANDOM_H
#define RANDOM_H
#ifdef _WIN32
#pragma once
#endif
// the random number seeding is automatic
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
// restarts random generator
// setting lSeed to 0 causes the current time to be used as the seed
// random number generator will automatically seed itself on first use with current time if this is not called
extern void SeedRandomNumberGenerator(long lSeed = 0);
// returns a random integer of range [low, high]
extern long RandomLong( long lLow, long lHigh );
// returns a random float of range [low, high)
extern float RandomFloat( float flLow, float flHigh );
#endif // RANDOM_H

View File

@ -0,0 +1,334 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cvarslider.h"
#include <stdio.h>
#include "tier1/KeyValues.h"
#include "tier1/convar.h"
#include <vgui/IVGui.h>
#include <vgui_controls/PropertyPage.h>
#define CVARSLIDER_SCALE_FACTOR 100.0f
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( CCvarSlider );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CCvarSlider::CCvarSlider( Panel *parent, const char *name ) : Slider( parent, name )
{
SetupSlider( 0, 1, "", false );
m_bCreatedInCode = false;
AddActionSignalTarget( this );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CCvarSlider::CCvarSlider( Panel *parent, const char *panelName, char const *caption,
float minValue, float maxValue, char const *cvarname, bool bAllowOutOfRange )
: Slider( parent, panelName )
{
AddActionSignalTarget( this );
SetupSlider( minValue, maxValue, cvarname, bAllowOutOfRange );
// For backwards compatability. Ignore .res file settings for forced setup sliders.
m_bCreatedInCode = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvarSlider::SetupSlider( float minValue, float maxValue, const char *cvarname, bool bAllowOutOfRange )
{
// make sure min/max don't go outside cvar range if there's one
ConVarRef var( cvarname, true );
if ( var.IsValid() )
{
float flCVarMin;
if ( var.GetMin( flCVarMin ) )
{
minValue = m_bUseConVarMinMax ? flCVarMin : MAX( minValue, flCVarMin );
}
float flCVarMax;
if ( var.GetMax( flCVarMax ) )
{
maxValue = m_bUseConVarMinMax ? flCVarMax : MIN( maxValue, flCVarMax );
}
}
m_flMinValue = minValue;
m_flMaxValue = maxValue;
// scale by CVARSLIDER_SCALE_FACTOR
SetRange( (int)( CVARSLIDER_SCALE_FACTOR * minValue ), (int)( CVARSLIDER_SCALE_FACTOR * maxValue ) );
char szMin[ 32 ];
char szMax[ 32 ];
Q_snprintf( szMin, sizeof( szMin ), "%.2f", minValue );
Q_snprintf( szMax, sizeof( szMax ), "%.2f", maxValue );
SetTickCaptions( szMin, szMax );
Q_strncpy( m_szCvarName, cvarname, sizeof( m_szCvarName ) );
m_bModifiedOnce = false;
m_bAllowOutOfRange = bAllowOutOfRange;
// Set slider to current value
Reset();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CCvarSlider::~CCvarSlider()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvarSlider::ApplySettings( KeyValues *inResourceData )
{
BaseClass::ApplySettings( inResourceData );
if ( !m_bCreatedInCode )
{
float minValue = inResourceData->GetFloat( "minvalue", 0 );
float maxValue = inResourceData->GetFloat( "maxvalue", 1 );
const char *cvarname = inResourceData->GetString( "cvar_name", "" );
bool bAllowOutOfRange = inResourceData->GetInt( "allowoutofrange", 0 ) != 0;
SetupSlider( minValue, maxValue, cvarname, bAllowOutOfRange );
if ( GetParent() )
{
// HACK: If our parent is a property page, we want the dialog containing it
if ( dynamic_cast<vgui::PropertyPage*>(GetParent()) && GetParent()->GetParent() )
{
GetParent()->GetParent()->AddActionSignalTarget( this );
}
else
{
GetParent()->AddActionSignalTarget( this );
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Get control settings for editing
//-----------------------------------------------------------------------------
void CCvarSlider::GetSettings( KeyValues *outResourceData )
{
BaseClass::GetSettings(outResourceData);
if ( !m_bCreatedInCode )
{
outResourceData->SetFloat( "minvalue", m_flMinValue );
outResourceData->SetFloat( "maxvalue", m_flMaxValue );
outResourceData->SetString( "cvar_name", m_szCvarName );
outResourceData->SetInt( "allowoutofrange", m_bAllowOutOfRange );
}
}
void CCvarSlider::SetCVarName( char const *cvarname )
{
Q_strncpy( m_szCvarName, cvarname, sizeof( m_szCvarName ) );
m_bModifiedOnce = false;
// Set slider to current value
Reset();
}
void CCvarSlider::SetMinMaxValues( float minValue, float maxValue, bool bSetTickDisplay )
{
SetRange( (int)( CVARSLIDER_SCALE_FACTOR * minValue ), (int)( CVARSLIDER_SCALE_FACTOR * maxValue ) );
if ( bSetTickDisplay )
{
char szMin[ 32 ];
char szMax[ 32 ];
Q_snprintf( szMin, sizeof( szMin ), "%.2f", minValue );
Q_snprintf( szMax, sizeof( szMax ), "%.2f", maxValue );
SetTickCaptions( szMin, szMax );
}
// Set slider to current value
Reset();
}
void CCvarSlider::SetTickColor( Color color )
{
m_TickColor = color;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvarSlider::Paint()
{
// Get engine's current value
// float curvalue = engine->pfnGetCvarFloat( m_szCvarName );
ConVarRef var( m_szCvarName, true );
if ( !var.IsValid() )
return;
float curvalue = var.GetFloat();
// did it get changed from under us?
if (curvalue != m_fStartValue)
{
int val = (int)( CVARSLIDER_SCALE_FACTOR * curvalue );
m_fStartValue = curvalue;
m_fCurrentValue = curvalue;
SetValue( val );
m_iStartValue = GetValue();
}
BaseClass::Paint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvarSlider::ApplyChanges()
{
if (m_bModifiedOnce)
{
m_iStartValue = GetValue();
if (m_bAllowOutOfRange)
{
m_fStartValue = m_fCurrentValue;
}
else
{
m_fStartValue = (float) m_iStartValue / CVARSLIDER_SCALE_FACTOR;
}
//engine->Cvar_SetValue( m_szCvarName, m_fStartValue );
ConVarRef var( m_szCvarName, true );
if ( !var.IsValid() )
return;
var.SetValue( (float)m_fStartValue );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float CCvarSlider::GetSliderValue()
{
if (m_bAllowOutOfRange)
{
return m_fCurrentValue;
}
else
{
return ((float)GetValue())/ CVARSLIDER_SCALE_FACTOR;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvarSlider::SetSliderValue(float fValue)
{
int nVal = (int)( CVARSLIDER_SCALE_FACTOR * fValue );
SetValue( nVal, false);
// remember this slider value
m_iLastSliderValue = GetValue();
if (m_fCurrentValue != fValue)
{
m_fCurrentValue = fValue;
m_bModifiedOnce = true;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvarSlider::Reset()
{
// Set slider to current value
// m_fStartValue = engine->pfnGetCvarFloat( m_szCvarName );
ConVarRef var( m_szCvarName, true );
if ( !var.IsValid() )
{
m_fCurrentValue = m_fStartValue = 0.0f;
SetValue( 0, false );
m_iStartValue = GetValue();
m_iLastSliderValue = m_iStartValue;
return;
}
m_fStartValue = var.GetFloat();
m_fCurrentValue = m_fStartValue;
int value = (int)( CVARSLIDER_SCALE_FACTOR * m_fStartValue );
SetValue( value, false );
m_iStartValue = GetValue();
m_iLastSliderValue = m_iStartValue;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CCvarSlider::HasBeenModified()
{
if (GetValue() != m_iStartValue)
{
m_bModifiedOnce = true;
}
return m_bModifiedOnce;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : position -
//-----------------------------------------------------------------------------
void CCvarSlider::OnSliderMoved()
{
if (HasBeenModified())
{
if (m_iLastSliderValue != GetValue())
{
m_iLastSliderValue = GetValue();
m_fCurrentValue = ((float) m_iLastSliderValue)/CVARSLIDER_SCALE_FACTOR;
}
// tell parent that we've been modified
PostActionSignal(new KeyValues("ControlModified"));
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvarSlider::OnSliderDragEnd( void )
{
if ( !m_bCreatedInCode )
{
ApplyChanges();
}
}

View File

@ -0,0 +1,63 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CVARSLIDER_H
#define CVARSLIDER_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Slider.h>
class CCvarSlider : public vgui::Slider
{
DECLARE_CLASS_SIMPLE( CCvarSlider, vgui::Slider );
public:
CCvarSlider( vgui::Panel *parent, const char *panelName );
CCvarSlider( vgui::Panel *parent, const char *panelName, char const *caption,
float minValue, float maxValue, char const *cvarname, bool bAllowOutOfRange=false );
~CCvarSlider();
void SetupSlider( float minValue, float maxValue, const char *cvarname, bool bAllowOutOfRange );
void SetCVarName( char const *cvarname );
void SetMinMaxValues( float minValue, float maxValue, bool bSetTickdisplay = true );
void SetTickColor( Color color );
virtual void Paint();
virtual void ApplySettings( KeyValues *inResourceData );
virtual void GetSettings( KeyValues *outResourceData );
void ApplyChanges();
float GetSliderValue();
void SetSliderValue(float fValue);
void Reset();
bool HasBeenModified();
private:
MESSAGE_FUNC( OnSliderMoved, "SliderMoved" );
MESSAGE_FUNC( OnSliderDragEnd, "SliderDragEnd" );
CPanelAnimationVar( bool, m_bUseConVarMinMax, "use_convar_minmax", "0" );
bool m_bAllowOutOfRange;
bool m_bModifiedOnce;
float m_fStartValue;
int m_iStartValue;
int m_iLastSliderValue;
float m_fCurrentValue;
char m_szCvarName[ 64 ];
bool m_bCreatedInCode;
float m_flMinValue;
float m_flMaxValue;
};
#endif // CVARSLIDER_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SCRIPTOBJECT_H
#define SCRIPTOBJECT_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Panel.h>
class CPanelListPanel;
#define SCRIPT_VERSION 1.0f
typedef void * FileHandle_t;
enum objtype_t
{
O_BADTYPE,
O_BOOL,
O_NUMBER,
O_LIST,
O_STRING,
O_OBSOLETE,
O_SLIDER,
O_CATEGORY,
};
typedef struct
{
objtype_t type;
char szDescription[32];
} objtypedesc_t;
class CScriptListItem
{
public:
CScriptListItem();
CScriptListItem( char const *strItem, char const *strValue );
char szItemText[128];
char szValue[256];
CScriptListItem *pNext;
};
class CScriptObject : public vgui::Panel
{
public:
void AddItem( CScriptListItem *pItem );
void RemoveAndDeleteAllItems( void );
CScriptObject( void );
~CScriptObject();
bool ReadFromBuffer( const char **pBuffer, bool isNewObject );
void WriteToConfig();
void WriteToFile( FileHandle_t fp );
void WriteToScriptFile( FileHandle_t fp );
void SetCurValue( char const *strValue );
objtype_t GetType( char *pszType );
objtype_t type;
char cvarname[64 ];
char prompt[ 256 ];
char tooltip[ 256 ];
CScriptListItem *pListItems;
float fMin, fMax;
char defValue[ 128 ]; // Default value string
float fdefValue; // Float version of default value.
char curValue[ 128 ];
float fcurValue;
bool bSetInfo; // Prepend "Setinfo" to keyvalue pair in config?
// Linked list of default list box items.
CScriptObject *pNext;
};
abstract_class CDescription
{
public:
CDescription( void );
virtual ~CDescription();
bool ReadFromBuffer( const char **pBuffer, bool bAllowNewObject );
bool InitFromFile( const char *pszFileName, bool bAllowNewObject = true );
void TransferCurrentValues( const char *pszConfigFile );
void AddObject( CScriptObject *pItem );
void WriteToConfig();
void WriteToFile( FileHandle_t fp );
void WriteToScriptFile( FileHandle_t fp );
virtual void WriteScriptHeader( FileHandle_t fp ) = 0; // Clients must implement this.
virtual void WriteFileHeader( FileHandle_t fp ) = 0; // Clients must implement this.
void setDescription( const char *pszDesc );
void setHint( const char *pszHint );
const char *GetDescription( void ) { return m_pszDescriptionType; };
const char *getHint( void ) { return m_pszHintText; } ;
public:
CScriptObject *pObjList;
CScriptObject *FindObject( const char *pszObjectName );
private:
char *m_pszHintText;
char *m_pszDescriptionType;
};
namespace vgui
{
class Label;
class Panel;
}
class mpcontrol_t : public vgui::Panel
{
public:
mpcontrol_t( vgui::Panel *parent, char const *panelName );
virtual void OnSizeChanged( int wide, int tall ) OVERRIDE;
objtype_t type;
vgui::Panel *pControl;
vgui::Label *pPrompt;
CScriptObject *pScrObj;
mpcontrol_t *next;
};
class CInfoDescription : public CDescription
{
public:
CInfoDescription( void );
virtual void WriteScriptHeader( FileHandle_t fp ) OVERRIDE;
virtual void WriteFileHeader( FileHandle_t fp ) OVERRIDE;
};
void UTIL_StripInvalidCharacters( char *pszInput, int maxlen );
#endif // SCRIPTOBJECT_H

43
common/IAdminServer.h Normal file
View File

@ -0,0 +1,43 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef IADMINSERVER_H
#define IADMINSERVER_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
// handle to a game window
typedef unsigned int ManageServerUIHandle_t;
class IManageServer;
//-----------------------------------------------------------------------------
// Purpose: Interface to server administration functions
//-----------------------------------------------------------------------------
abstract_class IAdminServer : public IBaseInterface
{
public:
// opens a manage server dialog for a local server
virtual ManageServerUIHandle_t OpenManageServerDialog(const char *serverName, const char *gameDir) = 0;
// opens a manage server dialog to a remote server
virtual ManageServerUIHandle_t OpenManageServerDialog(unsigned int gameIP, unsigned int gamePort, const char *password) = 0;
// forces the game info dialog closed
virtual void CloseManageServerDialog(ManageServerUIHandle_t gameDialog) = 0;
// Gets a handle to the interface
virtual IManageServer *GetManageServerInterface(ManageServerUIHandle_t handle) = 0;
};
#define ADMINSERVER_INTERFACE_VERSION "AdminServer002"
#endif // IAdminServer_H

View File

@ -0,0 +1,45 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef IFILESYSTEMOPENDIALOG_H
#define IFILESYSTEMOPENDIALOG_H
#ifdef _WIN32
#pragma once
#endif
#define FILESYSTEMOPENDIALOG_VERSION "FileSystemOpenDlg003"
class IFileSystem;
abstract_class IFileSystemOpenDialog
{
public:
// You must call this first to set the hwnd.
virtual void Init( CreateInterfaceFn factory, void *parentHwnd ) = 0;
// Call this to free the dialog.
virtual void Release() = 0;
// Use these to configure the dialog.
virtual void AddFileMask( const char *pMask ) = 0;
virtual void SetInitialDir( const char *pDir, const char *pPathID = NULL ) = 0;
virtual void SetFilterMdlAndJpgFiles( bool bFilter ) = 0;
virtual void GetFilename( char *pOut, int outLen ) const = 0; // Get the filename they chose.
// Call this to make the dialog itself. Returns true if they clicked OK and false
// if they canceled it.
virtual bool DoModal() = 0;
// This uses the standard windows file open dialog.
virtual bool DoModal_WindowsDialog() = 0;
};
#endif // IFILESYSTEMOPENDIALOG_H

34
common/IManageServer.h Normal file
View File

@ -0,0 +1,34 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef IMANAGESERVER_H
#define IMANAGESERVER_H
#ifdef _WIN32
#pragma once
#endif
#include <interface.h>
//-----------------------------------------------------------------------------
// Purpose: basic callback interface for the manage server list, to update status text et al
//-----------------------------------------------------------------------------
abstract_class IManageServer : public IBaseInterface
{
public:
// activates the manage page
virtual void ShowPage() = 0;
// sets whether or not the server is remote
virtual void SetAsRemoteServer(bool remote) = 0;
// prints text to the console
virtual void AddToConsole(const char *msg) = 0;
};
#define IMANAGESERVER_INTERFACE_VERSION "IManageServer002"
#endif // IMANAGESERVER_H

32
common/IObjectContainer.h Normal file
View File

@ -0,0 +1,32 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: IObjectContainer.h: interface for the ObjectContainer class.
//
// $NoKeywords: $
//=============================================================================//
#ifndef IOBJECTCONTAINER_H
#define IOBJECTCONTAINER_H
#pragma once
class IObjectContainer
{
public:
virtual ~IObjectContainer() {};
virtual void Init() = 0;
virtual bool Add(void * newObject) = 0;
virtual bool Remove(void * object) = 0;
virtual void Clear(bool freeElementsMemory) = 0;
virtual void * GetFirst() = 0;
virtual void * GetNext() = 0;
virtual int CountElements() = 0;;
virtual bool Contains(void * object) = 0;
virtual bool IsEmpty() = 0;
};
#endif // !defined IOBJECTCONTAINER_H

81
common/IRunGameEngine.h Normal file
View File

@ -0,0 +1,81 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef IRUNGAMEENGINE_H
#define IRUNGAMEENGINE_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#ifdef GetUserName
#undef GetUserName
#endif
//-----------------------------------------------------------------------------
// Purpose: Interface to running the game engine
//-----------------------------------------------------------------------------
abstract_class IRunGameEngine : public IBaseInterface
{
public:
// Returns true if the engine is running, false otherwise.
virtual bool IsRunning() = 0;
// Adds text to the engine command buffer. Only works if IsRunning()
// returns true on success, false on failure
virtual bool AddTextCommand(const char *text) = 0;
// runs the engine with the specified command line parameters. Only works if !IsRunning()
// returns true on success, false on failure
virtual bool RunEngine(const char *gameDir, const char *commandLineParams) = 0;
// returns true if the player is currently connected to a game server
virtual bool IsInGame() = 0;
// gets information about the server the engine is currently connected to
// returns true on success, false on failure
virtual bool GetGameInfo(char *infoBuffer, int bufferSize) = 0;
// tells the engine our userID
virtual void SetTrackerUserID(int trackerID, const char *trackerName) = 0;
// this next section could probably moved to another interface
// iterates users
// returns the number of user
virtual int GetPlayerCount() = 0;
// returns a playerID for a player
// playerIndex is in the range [0, GetPlayerCount)
virtual unsigned int GetPlayerFriendsID(int playerIndex) = 0;
// gets the in-game name of another user, returns NULL if that user doesn't exists
virtual const char *GetPlayerName(int friendsID, char *name, int namelen) = 0;
// gets the friends name of a player
virtual const char *GetPlayerFriendsName(int friendsID, char *name, int namelen) = 0;
// returns the engine build number and mod version string for server versioning
virtual unsigned int GetEngineBuildNumber() = 0;
virtual const char *GetProductVersionString() = 0;
// new interface to RunEngine (done so we don't have to roll the interface version)
virtual bool RunEngine2(const char *gameDir, const char *commandLineParams, bool isSourceGame) = 0;
enum ERunResult
{
k_ERunResultOkay = 0,
k_ERunResultModNotInstalled = 1,
k_ERunResultAppNotFound = 2,
k_ERunResultNotInitialized = 3,
};
virtual ERunResult RunEngine( int iAppID, const char *gameDir, const char *commandLineParams ) = 0;
};
#define RUNGAMEENGINE_INTERFACE_VERSION "RunGameEngine005"
#endif // IRUNGAMEENGINE_H

View File

@ -0,0 +1,33 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef IVGUIMODULELOADER_H
#define IVGUIMODULELOADER_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
//-----------------------------------------------------------------------------
// Purpose: interface to accessing all loaded modules
//-----------------------------------------------------------------------------
abstract_class IVGuiModuleLoader : public IBaseInterface
{
public:
virtual int GetModuleCount() = 0;
virtual const char *GetModuleLabel(int moduleIndex) = 0;
virtual CreateInterfaceFn GetModuleFactory(int moduleIndex) = 0;
virtual bool ActivateModule(int moduleIndex) = 0;
virtual bool ActivateModule(const char *moduleName) = 0;
virtual void SetPlatformToRestart() = 0;
};
#define VGUIMODULELOADER_INTERFACE_VERSION "VGuiModuleLoader003"
#endif // IVGUIMODULELOADER_H

64
common/IVguiModule.h Normal file
View File

@ -0,0 +1,64 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef IVGUIMODULE_H
#define IVGUIMODULE_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include <vgui/VGUI.h>
//-----------------------------------------------------------------------------
// Purpose: Standard interface to loading vgui modules
//-----------------------------------------------------------------------------
abstract_class IVGuiModule : public IBaseInterface
{
public:
// called first to setup the module with the vgui
// returns true on success, false on failure
virtual bool Initialize(CreateInterfaceFn *vguiFactories, int factoryCount) = 0;
// called after all the modules have been initialized
// modules should use this time to link to all the other module interfaces
virtual bool PostInitialize(CreateInterfaceFn *modules, int factoryCount) = 0;
// called when the module is selected from the menu or otherwise activated
virtual bool Activate() = 0;
// returns true if the module is successfully initialized and available
virtual bool IsValid() = 0;
// requests that the UI is temporarily disabled and all data files saved
virtual void Deactivate() = 0;
// restart from a Deactivate()
virtual void Reactivate() = 0;
// called when the module is about to be shutdown
virtual void Shutdown() = 0;
// returns a handle to the main module panel
virtual vgui::VPANEL GetPanel() = 0;
// sets the parent of the main module panel
virtual void SetParent(vgui::VPANEL parent) = 0;
// messages sent through through the panel returned by GetPanel():
//
// "ConnectedToGame" "ip" "port" "gamedir"
// "DisconnectedFromGame"
// "ActiveGameName" "name"
// "LoadingStarted" "type" "name"
// "LoadingFinished" "type" "name"
};
#define VGUIMODULE_INTERFACE_VERSION "VGuiModule002"
#endif // IVGUIMODULE_H

View File

@ -0,0 +1,57 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ISERVERBROWSER_H
#define ISERVERBROWSER_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
//-----------------------------------------------------------------------------
// Purpose: Interface to server browser module
//-----------------------------------------------------------------------------
abstract_class IServerBrowser
{
public:
// activates the server browser window, brings it to the foreground
virtual bool Activate() = 0;
// joins a game directly
virtual bool JoinGame( uint32 unGameIP, uint16 usGamePort, const char *pszConnectCode ) = 0;
// joins a specified game - game info dialog will only be opened if the server is fully or passworded
virtual bool JoinGame( uint64 ulSteamIDFriend, const char *pszConnectCode ) = 0;
// opens a game info dialog to watch the specified server; associated with the friend 'userName'
virtual bool OpenGameInfoDialog( uint64 ulSteamIDFriend, const char *pszConnectCode ) = 0;
// forces the game info dialog closed
virtual void CloseGameInfoDialog( uint64 ulSteamIDFriend ) = 0;
// closes all the game info dialogs
virtual void CloseAllGameInfoDialogs() = 0;
/// Given a map name, strips off some stuff and returns the "friendly" name of the map.
/// Returns the cleaned out map name into the caller's buffer, and returns the friendly
/// game type name.
virtual const char *GetMapFriendlyNameAndGameType( const char *pszMapName, char *szFriendlyMapName, int cchFriendlyName ) = 0;
// Enable filtering of workshop maps, requires the game/tool loading us to feed subscription data. This is a
// slightly ugly workaround to TF2 not yet having native workshop UI in quickplay, once that is in place this should
// either be stripped back out or expanded to be directly aware of the steam workshop without being managed.
virtual void SetWorkshopEnabled( bool bManaged ) = 0;
virtual void AddWorkshopSubscribedMap( const char *pszMapName ) = 0;
virtual void RemoveWorkshopSubscribedMap( const char *pszMapName ) = 0;
};
#define SERVERBROWSER_INTERFACE_VERSION "ServerBrowser005"
#endif // ISERVERBROWSER_H

View File

@ -0,0 +1,290 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
//#include "..\..\serverbrowser\pch_serverbrowser.h"
#undef _snprintf // needed since matchmakingtypes.h inlines a bare _snprintf
#include "convar.h"
#include "KeyValues.h"
#include "filesystem.h"
#include "steam/steamclientpublic.h"
#include "steam/matchmakingtypes.h"
#include <time.h>
#include "blacklisted_server_manager.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBlacklistedServerManager::CBlacklistedServerManager()
{
m_iNextServerID = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Reset the list of blacklisted servers to empty.
//-----------------------------------------------------------------------------
void CBlacklistedServerManager::Reset( void )
{
m_Blacklist.RemoveAll();
m_iNextServerID = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Appends all the servers inside the specified file to the blacklist.
// Returns count of appended servers, zero for failure.
//-----------------------------------------------------------------------------
int CBlacklistedServerManager::LoadServersFromFile( const char *pszFilename, bool bResetTimes )
{
KeyValues *pKV = new KeyValues( "serverblacklist" );
if ( !pKV->LoadFromFile( g_pFullFileSystem, pszFilename, "MOD" ) )
return 0;
int count = 0;
for ( KeyValues *pData = pKV->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
{
const char *pszName = pData->GetString( "name" );
uint32 ulDate = pData->GetInt( "date" );
if ( bResetTimes )
{
time_t today;
time( &today );
ulDate = today;
}
const char *pszNetAddr = pData->GetString( "addr" );
if ( pszNetAddr && pszNetAddr[0] && pszName && pszName[0] )
{
int iIdx = m_Blacklist.AddToTail();
m_Blacklist[iIdx].m_nServerID = m_iNextServerID++;
V_strncpy( m_Blacklist[iIdx].m_szServerName, pszName, sizeof( m_Blacklist[iIdx].m_szServerName ) );
m_Blacklist[iIdx].m_ulTimeBlacklistedAt = ulDate;
m_Blacklist[iIdx].m_NetAdr.SetFromString( pszNetAddr );
++count;
}
}
pKV->deleteThis();
return count;
}
//-----------------------------------------------------------------------------
// Purpose: save blacklist to disk
//-----------------------------------------------------------------------------
void CBlacklistedServerManager::SaveToFile( const char *pszFilename )
{
KeyValues *pKV = new KeyValues( "serverblacklist" );
for ( int i = 0; i < m_Blacklist.Count(); i++ )
{
KeyValues *pSubKey = new KeyValues( "server" );
pSubKey->SetString( "name", m_Blacklist[i].m_szServerName );
pSubKey->SetInt( "date", m_Blacklist[i].m_ulTimeBlacklistedAt );
pSubKey->SetString( "addr", m_Blacklist[i].m_NetAdr.ToString() );
pKV->AddSubKey( pSubKey );
}
pKV->SaveToFile( g_pFullFileSystem, pszFilename, "MOD" );
pKV->deleteThis();
}
//-----------------------------------------------------------------------------
// Purpose: Add the given server to the blacklist. Return added server.
//-----------------------------------------------------------------------------
blacklisted_server_t *CBlacklistedServerManager::AddServer( gameserveritem_t &server )
{
// Make sure we don't already have this IP in the list somewhere
netadr_t netAdr( server.m_NetAdr.GetIP(), server.m_NetAdr.GetConnectionPort() );
// Don't let them add reserved addresses to their blacklists
if ( netAdr.IsReservedAdr() )
return NULL;
int iIdx = m_Blacklist.AddToTail();
V_strncpy( m_Blacklist[iIdx].m_szServerName, server.GetName(), sizeof( m_Blacklist[iIdx].m_szServerName ) );
time_t today;
time( &today );
m_Blacklist[iIdx].m_ulTimeBlacklistedAt = today;
m_Blacklist[iIdx].m_NetAdr = netAdr;
m_Blacklist[iIdx].m_nServerID = m_iNextServerID++;
return &m_Blacklist[iIdx];
}
//-----------------------------------------------------------------------------
// Purpose: Add the given server to the blacklist. Return added server.
//-----------------------------------------------------------------------------
blacklisted_server_t *CBlacklistedServerManager::AddServer( const char *serverName, uint32 serverIP, int serverPort )
{
netadr_t netAdr( serverIP, serverPort );
// Don't let them add reserved addresses to their blacklists
if ( netAdr.IsReservedAdr() )
return NULL;
int iIdx = m_Blacklist.AddToTail();
V_strncpy( m_Blacklist[iIdx].m_szServerName, serverName, sizeof( m_Blacklist[iIdx].m_szServerName ) );
time_t today;
time( &today );
m_Blacklist[iIdx].m_ulTimeBlacklistedAt = today;
m_Blacklist[iIdx].m_NetAdr = netAdr;
m_Blacklist[iIdx].m_nServerID = m_iNextServerID++;
return &m_Blacklist[iIdx];
}
//-----------------------------------------------------------------------------
// Purpose: Add the given server to the blacklist. Return added server.
//-----------------------------------------------------------------------------
blacklisted_server_t *CBlacklistedServerManager::AddServer( const char *serverName, const char *netAddressString, uint32 timestamp )
{
netadr_t netAdr( netAddressString );
// Don't let them add reserved addresses to their blacklists
if ( netAdr.IsReservedAdr() )
return NULL;
int iIdx = m_Blacklist.AddToTail();
V_strncpy( m_Blacklist[iIdx].m_szServerName, serverName, sizeof( m_Blacklist[iIdx].m_szServerName ) );
m_Blacklist[iIdx].m_ulTimeBlacklistedAt = timestamp;
m_Blacklist[iIdx].m_NetAdr = netAdr;
m_Blacklist[iIdx].m_nServerID = m_iNextServerID++;
return &m_Blacklist[iIdx];
}
//-----------------------------------------------------------------------------
// Purpose: Remove server with matching 'server id' from list
//-----------------------------------------------------------------------------
void CBlacklistedServerManager::RemoveServer( int iServerID )
{
for ( int i = 0; i < m_Blacklist.Count(); i++ )
{
if ( m_Blacklist[i].m_nServerID == iServerID )
{
m_Blacklist.Remove(i);
break;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Given a serverID, return its blacklist entry
//-----------------------------------------------------------------------------
blacklisted_server_t *CBlacklistedServerManager::GetServer( int iServerID )
{
for ( int i = 0; i < m_Blacklist.Count(); i++ )
{
if ( m_Blacklist[i].m_nServerID == iServerID )
return &m_Blacklist[i];
}
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if given server is blacklisted
//-----------------------------------------------------------------------------
bool CBlacklistedServerManager::IsServerBlacklisted( const gameserveritem_t &server ) const
{
return IsServerBlacklisted( server.m_NetAdr.GetIP(), server.m_NetAdr.GetConnectionPort(), server.GetName() );
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if given server is blacklisted
//-----------------------------------------------------------------------------
bool CBlacklistedServerManager::IsServerBlacklisted( uint32 serverIP, int serverPort, const char *serverName ) const
{
netadr_t netAdr( serverIP, serverPort );
ConVarRef sb_showblacklists( "sb_showblacklists" );
for ( int i = 0; i < m_Blacklist.Count(); i++ )
{
if ( m_Blacklist[i].m_NetAdr.ip[3] == 0 )
{
if ( m_Blacklist[i].m_NetAdr.CompareClassCAdr( netAdr ) )
{
if ( sb_showblacklists.IsValid() && sb_showblacklists.GetBool() )
{
Msg( "Blacklisted '%s' (%s), due to rule '%s' (Class C).\n", serverName, netAdr.ToString(), m_Blacklist[i].m_NetAdr.ToString() );
}
return true;
}
}
else
{
if ( m_Blacklist[i].m_NetAdr.CompareAdr( netAdr, (m_Blacklist[i].m_NetAdr.GetPort() == 0) ) )
{
if ( sb_showblacklists.IsValid() && sb_showblacklists.GetBool() )
{
Msg( "Blacklisted '%s' (%s), due to rule '%s'.\n", serverName, netAdr.ToString(), m_Blacklist[i].m_NetAdr.ToString() );
}
return true;
}
}
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if the given server is allowed to be blacklisted at all
//-----------------------------------------------------------------------------
bool CBlacklistedServerManager::CanServerBeBlacklisted( gameserveritem_t &server ) const
{
return CanServerBeBlacklisted( server.m_NetAdr.GetIP(), server.m_NetAdr.GetConnectionPort(), server.GetName() );
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if the given server is allowed to be blacklisted at all
//-----------------------------------------------------------------------------
bool CBlacklistedServerManager::CanServerBeBlacklisted( uint32 serverIP, int serverPort, const char *serverName ) const
{
netadr_t netAdr( serverIP, serverPort );
if ( !netAdr.IsValid() )
return false;
// Don't let them add reserved addresses to their blacklists
if ( netAdr.IsReservedAdr() )
return false;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Returns vector of blacklisted servers
//-----------------------------------------------------------------------------
const CUtlVector< blacklisted_server_t > &CBlacklistedServerManager::GetServerVector( void ) const
{
return m_Blacklist;
}

View File

@ -0,0 +1,74 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef BLACKLISTEDSERVERMANAGER_H
#define BLACKLISTEDSERVERMANAGER_H
#ifdef _WIN32
#pragma once
#endif
#include "platform.h"
#include "netadr.h"
#include "utlvector.h"
#define BLACKLIST_DEFAULT_SAVE_FILE "cfg/server_blacklist.txt"
class gameserveritem_t;
struct blacklisted_server_t
{
int m_nServerID;
char m_szServerName[64];
uint32 m_ulTimeBlacklistedAt;
netadr_t m_NetAdr;
};
//-----------------------------------------------------------------------------
// Purpose: Collection of blacklisted servers
//-----------------------------------------------------------------------------
class CBlacklistedServerManager
{
public:
CBlacklistedServerManager();
void Reset( void );
blacklisted_server_t *AddServer( gameserveritem_t &server );
blacklisted_server_t *AddServer( const char *serverName, uint32 serverIP, int serverPort );
blacklisted_server_t *AddServer( const char *serverName, const char *netAddressString, uint32 timestamp );
void RemoveServer( int iServerID ); // remove server with matching 'server id' from list
void SaveToFile( const char *filename );
int LoadServersFromFile( const char *pszFilename, bool bResetTimes ); // returns count of appended servers, zero for failure
blacklisted_server_t *GetServer( int iServerID ); // return server with matching 'server id'
int GetServerCount( void ) const;
const CUtlVector< blacklisted_server_t > &GetServerVector( void ) const;
bool IsServerBlacklisted( const gameserveritem_t &server ) const;
bool IsServerBlacklisted( uint32 serverIP, int serverPort, const char *serverName ) const;
bool CanServerBeBlacklisted( gameserveritem_t &server ) const;
bool CanServerBeBlacklisted( uint32 serverIP, int serverPort, const char *serverName ) const;
private:
CUtlVector< blacklisted_server_t > m_Blacklist;
int m_iNextServerID; // for vgui use
};
inline int CBlacklistedServerManager::GetServerCount( void ) const
{
return m_Blacklist.Count();
}
#endif // BLACKLISTEDSERVERMANAGER_H

80
common/SourceAppInfo.cpp Normal file
View File

@ -0,0 +1,80 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: languages definition
//
//=============================================================================
#include "SourceAppInfo.h"
#include "tier0/dbg.h"
struct SourceAppInfo_t
{
const char *m_pchFullName;
const char *m_pchModName;
int m_nSteamAppId;
ESourceApp m_ESourceApp;
};
static const SourceAppInfo_t s_SteamAppInfo[] =
{
{ "Source SDK Base", "sourcetest", 215, k_App_SDK_BASE },
{ "Half-Life 2", "hl2", 220, k_App_HL2 } ,
{ "Counter-Strike: Source", "cstrike", 240, k_App_CSS } ,
{ "Day of Defeat: Source", "dod", 300, k_App_DODS } ,
{ "Half-Life 2: Deathmatch", "hl2mp", 320, k_App_HL2MP } ,
{ "Half-Life 2: Lost Coast", "lostcoast", 340, k_App_LOST_COAST } ,
{ "Half-Life Deathmatch: Source", "hl1mp", 360, k_App_HL1DM } ,
{ "Half-Life 2: Episode One", "episodic", 380, k_App_HL2_EP1 },
{ "Portal", "portal", 400, k_App_PORTAL } ,
{ "Half-Life 2: Episode Two", "ep2", 420, k_App_HL2_EP2 } ,
{ "Team Fortress 2", "tf", 440, k_App_TF2 } ,
};
//-----------------------------------------------------------------------------
// Purpose: return the short string name used for this language by SteamUI
//-----------------------------------------------------------------------------
const char *GetAppFullName( ESourceApp eSourceApp )
{
Assert( Q_ARRAYSIZE(s_SteamAppInfo) == k_App_MAX );
if ( s_SteamAppInfo[ eSourceApp ].m_ESourceApp == eSourceApp )
{
return s_SteamAppInfo[ eSourceApp ].m_pchFullName;
}
Assert( !"enum ESourceApp order mismatched from AppInfo_t s_SteamAppInfo, fix it!" );
return s_SteamAppInfo[0].m_pchFullName;
}
//-----------------------------------------------------------------------------
// Purpose: return the short string name used for this language by SteamUI
//-----------------------------------------------------------------------------
const char *GetAppModName( ESourceApp eSourceApp )
{
Assert( Q_ARRAYSIZE(s_SteamAppInfo) == k_App_MAX );
if ( s_SteamAppInfo[ eSourceApp ].m_ESourceApp == eSourceApp )
{
return s_SteamAppInfo[ eSourceApp ].m_pchModName;
}
Assert( !"enum ESourceApp order mismatched from AppInfo_t s_SteamAppInfo, fix it!" );
return s_SteamAppInfo[0].m_pchModName;
}
//-----------------------------------------------------------------------------
// Purpose: return the short string name used for this language by SteamUI
//-----------------------------------------------------------------------------
const int GetAppSteamAppId( ESourceApp eSourceApp )
{
Assert( Q_ARRAYSIZE(s_SteamAppInfo) == k_App_MAX );
if ( s_SteamAppInfo[ eSourceApp ].m_ESourceApp == eSourceApp )
{
return s_SteamAppInfo[ eSourceApp ].m_nSteamAppId;
}
Assert( !"enum ESourceApp order mismatched from AppInfo_t s_SteamAppInfo, fix it!" );
return s_SteamAppInfo[0].m_nSteamAppId;
}

28
common/SourceAppInfo.h Normal file
View File

@ -0,0 +1,28 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifndef SOURCE_APP_INFO_H
#define SOURCE_APP_INFO_H
#ifdef _WIN32
#pragma once
#endif
enum ESourceApp
{
k_App_SDK_BASE = 0,
k_App_HL2,
k_App_CSS,
k_App_DODS,
k_App_HL2MP,
k_App_LOST_COAST,
k_App_HL1DM,
k_App_HL2_EP1,
k_App_PORTAL,
k_App_HL2_EP2,
k_App_TF2,
k_App_MAX
};
const int GetAppSteamAppId( ESourceApp eSourceApp );
const char *GetAppModName( ESourceApp eSourceApp );
const char *GetAppFullName( ESourceApp eSourceApp );
#endif

193
common/SteamAppStartup.cpp Normal file
View File

@ -0,0 +1,193 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifdef _WIN32
#include "SteamAppStartup.h"
#define WIN32_LEAN_AND_MEAN
#include <assert.h>
#include <windows.h>
#include <process.h>
#include <direct.h>
#include <stdio.h>
#include <sys/stat.h>
#define STEAM_PARM "-steam"
void LaunchSelfViaSteam(const char *params);
bool FileExists(const char *fileName)
{
struct _stat statbuf;
return (_stat(fileName, &statbuf) == 0);
}
//-----------------------------------------------------------------------------
// Purpose: Launches steam if necessary
//-----------------------------------------------------------------------------
bool ShouldLaunchAppViaSteam(const char *lpCmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName)
{
// see if steam is on the command line
const char *steamStr = strstr(lpCmdLine, STEAM_PARM);
// check the character following it is a whitespace or null
if (steamStr)
{
const char *postChar = steamStr + strlen(STEAM_PARM);
if (*postChar == 0 || isspace(*postChar))
{
// we're running under steam already, let the app continue
return false;
}
}
// we're not running under steam, see which filesystems are available
if (FileExists(stdioFilesystemDllName))
{
// we're being run with a stdio filesystem, so we can continue without steam
return false;
}
// make sure we have a steam filesystem available
if (!FileExists(steamFilesystemDllName))
{
return false;
}
// we have the steam filesystem, and no stdio filesystem, so we must need to be run under steam
// launch steam
LaunchSelfViaSteam(lpCmdLine);
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Handles launching the game indirectly via steam
//-----------------------------------------------------------------------------
void LaunchSelfViaSteam(const char *params)
{
// calculate the details of our launch
char appPath[MAX_PATH];
::GetModuleFileName((HINSTANCE)GetModuleHandle(NULL), appPath, sizeof(appPath));
// strip out the exe name
char *slash = strrchr(appPath, '\\');
if (slash)
{
*slash = 0;
}
// save out our details to the registry
HKEY hKey;
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
{
DWORD dwType = REG_SZ;
DWORD dwSize = static_cast<DWORD>( strlen(appPath) + 1 );
RegSetValueEx(hKey, "TempAppPath", NULL, dwType, (LPBYTE)appPath, dwSize);
dwSize = static_cast<DWORD>( strlen(params) + 1 );
RegSetValueEx(hKey, "TempAppCmdLine", NULL, dwType, (LPBYTE)params, dwSize);
// clear out the appID (since we don't know it yet)
dwType = REG_DWORD;
int appID = -1;
RegSetValueEx(hKey, "TempAppID", NULL, dwType, (LPBYTE)&appID, sizeof(appID));
RegCloseKey(hKey);
}
// search for an active steam instance
HWND hwnd = ::FindWindow("Valve_SteamIPC_Class", "Hidden Window");
if (hwnd)
{
::PostMessage(hwnd, WM_USER + 3, 0, 0);
}
else
{
// couldn't find steam, find and launch it
// first, search backwards through our current set of directories
char steamExe[MAX_PATH];
steamExe[0] = 0;
char dir[MAX_PATH];
if (::GetCurrentDirectoryA(sizeof(dir), dir))
{
char *slash = strrchr(dir, '\\');
while (slash)
{
// see if steam_dev.exe is in the directory first
slash[1] = 0;
strcat(slash, "steam_dev.exe");
FILE *f = fopen(dir, "rb");
if (f)
{
// found it
fclose(f);
strcpy(steamExe, dir);
break;
}
// see if steam.exe is in the directory
slash[1] = 0;
strcat(slash, "steam.exe");
f = fopen(dir, "rb");
if (f)
{
// found it
fclose(f);
strcpy(steamExe, dir);
break;
}
// kill the string at the slash
slash[0] = 0;
// move to the previous slash
slash = strrchr(dir, '\\');
}
}
if (!steamExe[0])
{
// still not found, use the one in the registry
HKEY hKey;
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
{
DWORD dwType;
DWORD dwSize = sizeof(steamExe);
RegQueryValueEx( hKey, "SteamExe", NULL, &dwType, (LPBYTE)steamExe, &dwSize);
RegCloseKey( hKey );
}
}
if (!steamExe[0])
{
// still no path, error
::MessageBox(NULL, "Error running game: could not find steam.exe to launch", "Fatal Error", MB_OK | MB_ICONERROR);
return;
}
// fix any slashes
for (char *slash = steamExe; *slash; slash++)
{
if (*slash == '/')
{
*slash = '\\';
}
}
// change to the steam directory
strcpy(dir, steamExe);
char *delimiter = strrchr(dir, '\\');
if (delimiter)
{
*delimiter = 0;
_chdir(dir);
}
// exec steam.exe, in silent mode, with the launch app param
char *args[4] = { steamExe, "-silent", "-applaunch", NULL };
_spawnv(_P_NOWAIT, steamExe, args);
}
}
#endif // _WIN32

25
common/SteamAppStartup.h Normal file
View File

@ -0,0 +1,25 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: used by all .exe's that run under steam and out,
// so they can be launched indirectly by steam and launch steam themselves
//
//=============================================================================//
#ifndef STEAMAPPSTARTUP_H
#define STEAMAPPSTARTUP_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose: Call this first thing at startup
// Works out if the app is a steam app that is being ran outside of steam,
// and if so, launches steam and tells it to run us as a steam app
//
// if it returns true, then exit
// if it ruturns false, then continue with normal startup
//-----------------------------------------------------------------------------
bool ShouldLaunchAppViaSteam(const char *cmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName);
#endif // STEAMAPPSTARTUP_H

162
common/SteamBootStrapper.h Normal file
View File

@ -0,0 +1,162 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//*********** (C) Copyright 2000 Valve, L.L.C. 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.
//
//*****************************************************************************
//
// Contents:
//
//
//
// Authors:
//
// Target restrictions:
//
// Tool restrictions:
//
// Things to do:
//
//
//
//*****************************************************************************
#ifndef INCLUDED_STEAM_BOOTSTRAPPER_H
#define INCLUDED_STEAM_BOOTSTRAPPER_H
#if defined(_MSC_VER) && (_MSC_VER > 1000)
#pragma once
#endif
//*****************************************************************************
//
// 'Local' build control section.
//
//*****************************************************************************
#if (BUILD_MODE == BUILD_MODE_RELEASE_NORMAL) || (BUILD_MODE == BUILD_MODE_RELEASE_TEST)
#elif BUILD_MODE == BUILD_MODE_DEBUG_NORMAL
#else
// 'Safe' default settings. This allows new build modes to be added to the
// project without requiring the manual updating of all 'local build control'
// sections in every module and header file.
#endif
//*****************************************************************************
//
// Include files required by this header.
//
// Note: Do NOT place any 'using' directives or declarations in header files -
// put them at the top of the source files that require them.
// Use fully-qualified names in header files.
//
//*****************************************************************************
//*****************************************************************************
//
// Exported constants and macros.
// - Wrap these definitions in a namespace whenever possible
//
//*****************************************************************************
namespace
{
// constant definitions here
}
#define szSteamBootStrapperIconIdEnvVar "__STEAM_BOOTSTRAPPER_ICON_ID__"
//*****************************************************************************
//
// Exported scalar type and enumerated type definitions.
// - Wrap these definitions in a namespace whenever possible
//
//*****************************************************************************
namespace
{
// scalar and enumerated type definitions here
}
//*****************************************************************************
//
// Exported class, structure, and complex type definitions.
// - Wrap these definitions in a namespace whenever possible
//
//*****************************************************************************
namespace
{
// class, structure, and complex type definitions here
}
//*****************************************************************************
//
// Exported function prototypes
// - Wrap these definitions in a namespace whenever possible
// - declared extern here, and defined without storage class in the source file.
//
//*****************************************************************************
namespace
{
// function prototypes here
}
//*****************************************************************************
//
// Exported variable and data declarations
// - Wrap these definitions in a namespace whenever possible
// - declared extern here, and defined without storage class in the source file.
//
//*****************************************************************************
namespace
{
// variable and data declarations here
}
//*****************************************************************************
//
// Inline function definitions.
//
//*****************************************************************************
#endif

105
common/Steamlib.h Normal file
View File

@ -0,0 +1,105 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// Steam header file includes all definitions for Grid.lib
#ifndef INCLUDED_STEAMLIBAPI_H
#define INCLUDED_STEAMLIBAPI_H
#ifndef _WIN32 // Linux from here for temporary non-Steam server
#include "Steamlib_null.h"
#else // Win32 from here
#if defined(_MSC_VER) && (_MSC_VER > 1000)
#pragma once
#endif
#ifdef __cplusplus
extern "C"
{
#endif
extern int STEAM_Startup(void);
extern int STEAM_Mount(const char *szMountPath);
extern int STEAM_Unmount(void);
extern void STEAM_Shutdown(void);
extern FILE *STEAM_fopen(const char *filename, const char *options);
extern int STEAM_fclose(FILE *file);
extern unsigned int STEAM_fread(void *buffer, unsigned int rdsize, unsigned int count,FILE *file);
extern int STEAM_fgetc(FILE *file);
extern unsigned int STEAM_fwrite(void *buffer, unsigned int rdsize, unsigned int count,FILE *file);
extern int STEAM_fprintf( FILE *fp, const char *format, ... );
extern int STEAM_vfprintf( FILE *fp, const char *format, va_list argptr);
extern int STEAM_fseek(FILE *file, long offset, int method);
extern long STEAM_ftell(FILE *file);
extern int STEAM_stat(const char *path, struct _stat *buf);
extern int STEAM_feof( FILE *stream );
extern int STEAM_ferror( FILE *stream );
extern void STEAM_clearerr( FILE *stream );
extern void STEAM_strerror( FILE *stream, char *p, int maxlen );
extern void STEAM_rewind( FILE *stream );
extern int STEAM_fflush( FILE *stream );
extern int STEAM_flushall( void );
extern unsigned int STEAM_FileSize( FILE *file );
extern void STEAM_setbuf( FILE *stream, char *buffer);
extern int STEAM_setvbuf( FILE *stream, char *buffer, int mode, size_t size);
extern char *STEAM_fgets(char *string, int n, FILE *stream);
extern int STEAM_fputc(int c, FILE *stream);
extern int STEAM_fputs(const char *string, FILE *stream);
extern FILE *STEAM_tmpfile(void);
typedef enum // Filter elements returned by SteamFind{First,Next}
{
STEAMFindLocalOnly, // limit search to local filesystem
STEAMFindRemoteOnly, // limit search to remote repository
STEAMFindAll // do not limit search (duplicates allowed)
} STEAMFindFilter;
extern HANDLE STEAM_FindFirstFile(char *pszMatchName, STEAMFindFilter filter, WIN32_FIND_DATA *findInfo);
extern int STEAM_FindNextFile(HANDLE dir, WIN32_FIND_DATA *findInfo);
extern int STEAM_FindClose(HANDLE dir);
extern long STEAM_findfirst(char *pszMatchName, STEAMFindFilter filter, struct _finddata_t *fileinfo );
extern int STEAM_findnext(long dir, struct _finddata_t *fileinfo );
extern int STEAM_findclose(long dir);
extern HINSTANCE STEAM_LoadLibrary( const char *dllName );
extern void STEAM_GetLocalCopy( const char *fileName );
extern void STEAM_LogLevelLoadStarted( const char *name );
extern void STEAM_LogLevelLoadFinished( const char *name );
extern int STEAM_HintResourceNeed( const char *mapcycle, int forgetEverything );
extern int STEAM_PauseResourcePreloading(void);
extern int STEAM_ForgetAllResourceHints(void);
extern int STEAM_ResumeResourcePreloading(void);
extern int STEAM_BlockForResources( const char *hintlist );
extern void STEAM_UseDaemon(int enable);
extern unsigned int STEAM_FileSize( FILE *file );
extern void STEAM_TrackProgress(int enable);
extern STEAM_RegisterAppProgressCallback( void(*fpProgCallBack)(void), int freq );
extern STEAM_RegisterAppKeepAliveTicCallback( void(*fpKeepAliveTicCallBack)(char* scr_msg) );
extern void STEAM_UpdateProgress( void );
extern int STEAM_ProgressCounter(void);
extern void STEAM_GetInterfaceVersion( char *p, int maxlen );
extern int STEAM_FileIsAvailLocal( const char *file );
#ifdef __cplusplus
}
#endif
#endif // ndef _WIN32
#endif /* #ifndef INCLUDED_STEAMLIBAPI_H */

118
common/Steamlib_null.h Normal file
View File

@ -0,0 +1,118 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
// Passthrough/stubbed version of Steamlib.h/Steam.c for Linux non-Steam server
#ifndef STEAMLIB_NULL_H
#define STEAMLIB_NULL_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // for strlen()
#include <stdarg.h>
#include <dlfcn.h>
#if !defined ( _WIN32 )
#include <string.h>
#endif
typedef enum // Filter elements returned by SteamFind{First,Next}
{
STEAMFindLocalOnly, // limit search to local filesystem
STEAMFindRemoteOnly, // limit search to remote repository
STEAMFindAll // do not limit search (duplicates allowed)
} STEAMFindFilter;
// Direct drop-in replacements
#define STEAM_fopen fopen
#define STEAM_fclose fclose
#define STEAM_fread fread
#define STEAM_fwrite fwrite
#define STEAM_fprintf fprintf
#define STEAM_fseek fseek
#define STEAM_ftell ftell
#define STEAM_feof feof
#define STEAM_ferror ferror
#define STEAM_clearerr clearerr
#define STEAM_rewind rewind
#define STEAM_fflush fflush
#define STEAM_setvbuf setvbuf
static inline int STEAM_Mount( void ) { return 1; }
static inline void STEAM_Shutdown( void ) { }
static inline unsigned int STEAM_FileSize( FILE *file )
{
unsigned int iRet;
if ( !file )
{
iRet = 0;
}
else
{
int iPos;
iPos = ftell( file );
fseek ( file, 0, SEEK_END );
iRet = ftell( file );
fseek ( file, iPos, SEEK_SET );
}
return iRet;
}
static inline void STEAM_strerror( FILE *stream, char * p, int maxlen )
{
snprintf( p, maxlen, "Steam FS unavailable" );
}
static inline void STEAM_GetLocalCopy( const char * fileName ) { }
static inline void STEAM_LogLevelLoadStarted( const char * name ) { }
static inline void STEAM_LogLevelLoadFinished( const char * name ) { }
static inline int STEAM_HintResourceNeed( const char * mapcycle, int forgetEverything ) { return 1; }
static inline void STEAM_TrackProgress( int enable ) { }
static inline void STEAM_UpdateProgress( void ) { }
static inline void STEAM_RegisterAppProgressCallback( void( *fpProgCallBack )( void ), int freq ) { }
static inline void STEAM_RegisterAppKeepAliveTicCallback( void( *fpKeepAliveTicCallBack )( char * scr_msg ) ) { }
static inline void STEAM_GetInterfaceVersion( char * p, int maxlen )
{
snprintf( p, maxlen, "0.0.0.0" );
}
static inline long STEAM_LoadLibrary( char * pszFileName )
{
void * hDll;
char szCwd[ MAX_OSPATH ];
char szAbsoluteLib[ MAX_OSPATH ];
if ( !getcwd( szCwd, sizeof( szCwd ) ) )
return 0;
if ( szCwd[ strlen( szCwd ) -1 ] == '/' )
{
szCwd[ strlen( szCwd ) -1 ] = 0;
}
snprintf( szAbsoluteLib, sizeof( szAbsoluteLib ), "%s/%s", szCwd, pszFileName );
hDll = dlopen( szAbsoluteLib, RTLD_NOW );
return (long)hDll;
}
#endif // STEAMLIB_NULL_H

View File

@ -0,0 +1,95 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
/*******************************************************************************
**
** Contents:
**
** This file provides the public interface to the Steam service. This
** interface is described in the SDK documentation.
**
******************************************************************************/
#ifndef INCLUDED_VALIDATENEWVALVECDKEYCLIENT_H
#define INCLUDED_VALIDATENEWVALVECDKEYCLIENT_H
#if defined(_MSC_VER) && (_MSC_VER > 1000)
#pragma once
#endif
#ifndef INCLUDED_STEAM_COMMON_STEAMCOMMON_H
#include "steamcommon.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
// Note: this function expects the CDkey to contain dashes to split it into groups of 5 characters.
//
// e.g. 5WV2E-CDL82-89AQ4-ZZKH8-L27IB (note: this example is not a valid key)
//
ESteamError SteamWeakVerifyNewValveCDKey
(
const char * pszCDKeyFormattedForCDLabel,
uint * pReceiveGameCode,
uint * pReceiveSalesTerritoryCode,
uint * pReceiveUniqueSerialNumber
);
// This returns data ready to send to the validation server.
// If you want to store a CDKey in the registry, consider passing the
// output of this function through one of the functions below,
// to make life harder for registry-harvesting trojans.
//
// This also does a WeakVerify.
ESteamError SteamGetEncryptedNewValveCDKey
(
const char * pszCDKeyFormattedForCDLabel,
unsigned int ClientLocalIPAddr,
const void * pEncryptionKeyReceivedFromAppServer,
unsigned int uEncryptionKeyLength,
void * pOutputBuffer,
unsigned int uSizeOfOutputBuffer,
unsigned int * pReceiveSizeOfEncryptedNewValveCDKey
);
// This pair of functions encrypt and decrypt data using a key based on unique
// properties of this machine. The resulting encrypted data can only be (easily)
// decrypted on the same machine. Note: it is NOT impossible to decrypt the data
// elsewhere, just inconvenient.
ESteamError SteamEncryptDataForThisMachine
(
const char * pDataToEncrypt,
unsigned int uSizeOfDataToEncrypt,
void * pOutputBuffer,
unsigned int uSizeOfOutputBuffer,
unsigned int * pReceiveSizeOfEncryptedData
);
ESteamError SteamDecryptDataForThisMachine
(
const char * pDataToDecrypt,
unsigned int uSizeOfDataToDecrypt,
void * pOutputBuffer,
unsigned int uSizeOfOutputBuffer,
unsigned int * pReceiveSizeOfDecryptedData
);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef INCLUDED_STEAM_COMMON_STEAMCOMMON_H */

View File

@ -0,0 +1,173 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef VALVECDKEYGAMEANDTERRITORYCODES_H
#define VALVECDKEYGAMEANDTERRITORYCODES_H
#ifdef _WIN32
#pragma once
#endif
// imported from MainIntegration/Deliverables/Production/Client/Inc/NewValveCDKeyGenerator.h
// if the enums there change, this needs to change
//!! these need to be moved out into a seperate file in steam, so that src can use the directly published version
//
// GameCode
//
enum EGameCode
{
// DoD uses SteamInstanceId = 1
// DoD CD-key Steam IDs are displayed as VALVE_1:xxxxxxxx where xxxx is the SteamLocalUserId mentioned above.
// DoD CD-keys uses an odd scheme (invented in a rush) whereby the SteamLocalUserID is generated by hashing
// (MD5) the CD key parameters (Territory,GameCode,UniqueSerialNumber) and truncating the resulting hash for
// a reasonable display length (26 bits, i.e. eMaskLargestAcceptableLocalUserId above, which is about 8 decimal digits).
// **The generator must therefore discard any UniqueSerialNumbers that cause hashes to collide.**
// This means that when generating a new batch from a non-zero StartUniqueSerialNumber, the generator has
// to generate them all from 0 anyway to populate an array of 'hash has been used' flags -- it then only
// prints out new keys higher than the requested StartUniqueSerialNumber.
// IMPORTANT: this means that each match of N keys generated consumes MORE THAN N UniqueSerialNumbers --
// so each new batch MUST be started with the correct "Next StartUniqueSerialNumber" that was output
// at the end of the previous batch, or the new batch will overlap with the previous batch.
eDayOfDefeat = 0,
// CZ uses SteamInstanceId = 2 (**as will all future games using this system**)
// CZ CD-key SteamLocalUserIds have
// high32bits = ( GameCode << sc_uNumBitsSalesTerritory) | SalesTerritory
// low32bits = UniqueSerialNumber
// CZ CD-key Steam IDs will be displayed as VALVE_2:GameCode:UniqueSerialNumber
// (i.e. the DoD hashing scheme is *NOT* used).
eConditionZero = 1,
// CyberCafes receive all legacy and future products, under this one code.
// They have their own SalesTerritory codes too.
// If a CDKey has this game code OR a CyberCafe SalesTerritory then it is a 'cybercafe CDkey'.
eCyberCafeBundle = 2,
eHalfLife2 = 3,
eHalfLife2RetailCE = 4,
eHalfLife2Retail = 5,
};
//
// SalesTerritory
//
enum ESalesTerritory
{
// DoD first batch 80,000 keys **Next free 'StartUniqueSerialNumber' = 80032
// DoD second batch 30,000 keys **Next free 'StartUniqueSerialNumber' = 110081
// OLD KEY ... NOTE: this CZ first batch for USA (code 0) of 275,000 may also be distributed in Canada
// OLD KEY ... i.e. they should ideally have had code 11, but we didn't want to re-issue them.
// OLD KEY ConditionZero first batch 275,000 keys **Next free 'StartUniqueSerialNumber' = 275000
// NEW KEY These were moved to region 11 as suggested above (part of first batch of 379,000)
eUSA = 0,
// DoD first batch 7,500 keys **Next free 'StartUniqueSerialNumber' = 7500
eAustralia = 1,
// DoD first batch 15,000 keys **Next free 'StartUniqueSerialNumber' = 15000
eKorea = 2,
// DoD first batch 10,000 keys **Next free 'StartUniqueSerialNumber' = 10000
eTaiwan = 3,
// DoD first batch 5,000 keys **Next free 'StartUniqueSerialNumber' = 5000
eJapan = 4,
// DoD first batch 25,000 keys **Next free 'StartUniqueSerialNumber' = 25003
// ConditionZero first batch 99,000 keys **Next free 'StartUniqueSerialNumber' = 99000
eUK = 5,
// DoD first batch 15,000 keys **Next free 'StartUniqueSerialNumber' = 15002
// ConditionZero first batch 77,000 keys **Next free 'StartUniqueSerialNumber' = 77000
eFrance = 6,
// DoD first batch 3,000 keys **Next free 'StartUniqueSerialNumber' = 3000
// DoD second batch 5,000 keys **Next free 'StartUniqueSerialNumber' = 8002
// ConditionZero first batch 132,000 keys **Next free 'StartUniqueSerialNumber' = 132000
eGermany = 7,
// DoD first batch 3,000 keys **Next free 'StartUniqueSerialNumber' = 3000
// ConditionZero first batch 27,500 keys **Next free 'StartUniqueSerialNumber' = 27500
eSpain = 8,
// DoD first batch 3,000 keys **Next free 'StartUniqueSerialNumber' = 3000
// ConditionZero first batch 44,000 keys **Next free 'StartUniqueSerialNumber' = 44000
eItaly = 9,
// DoD first batch 65,000 keys **Next free 'StartUniqueSerialNumber' = 65039
// DoD second batch 20,000 keys **Next free 'StartUniqueSerialNumber' = 85058
eChina = 10,
// This is ALL 'American' ENGLISH-SPEAKING TERRITORIES (e.g. USA, Austrailia, Canada, NZ, but *NOT* UK).
// Vivendi track sales by language, rather that geographically.
// OLD KEY ... NOTE: CZ first batch for USA (code 0) of 275,000 will also be distributed in these territories
// OLD KEY ... i.e. they should ideally have had this code, but we didn't want to re-issue them.
// OLD KEY ConditionZero first batch 25,000 keys **Next free 'StartUniqueSerialNumber' = 25000
// OLD KEY ConditionZero second batch 79,000 keys **Next free 'StartUniqueSerialNumber' = 104000
// NEW KEY ConditionZero first batch 379,000 keys **Next free 'StartUniqueSerialNumber' =
eEnglish = 11,
// CyberCafe specific territories. If a CDKey has this game code OR a CyberCafe SalesTerritory then it is a 'cybercafe CDkey'.
// CyberCafeBundle first batch 15,000 keys **Next free 'StartUniqueSerialNumber' = 15000
eCyberCafeEurope = 12,
// CyberCafeBundle first batch 15,000 keys **Next free 'StartUniqueSerialNumber' = 15000
eCyberCafeNorthAndSouthAmerica = 13,
// CyberCafeBundle first batch 15,000 keys **Next free 'StartUniqueSerialNumber' = 15000
eCyberCafeKorea = 14,
// CyberCafeBundle first batch 15,000 keys **Next free 'StartUniqueSerialNumber' = 15000
eCyberCafeChinaTaiwan = 15,
// CyberCafeBundle first batch 15,000 keys **Next free 'StartUniqueSerialNumber' = 15000
eCyberCafeRestOfAsia = 16,
// ATI OEM
// *** After intranet security breach, only the first 40,000 of these keys are valid:
// OLD KEY HL2 first batch 250,000 keys
// *** After intranet security breach, these keys use a new MAC key:
// NEW KEY HL2 first batch start=40,000 210,000 keys
eATI_OEM = 17,
// ConditionZero first batch 5,500 keys **Next free 'StartUniqueSerialNumber' = 5500
eLatinAmerica = 18,
// ConditionZero first batch 16,500 keys **Next free 'StartUniqueSerialNumber' = 16500
eBrazil = 19,
// ConditionZero first batch 66,000 keys **Next free 'StartUniqueSerialNumber' = 66000
eNordic = 20,
// This a Vivendi code meaning "Belgium, Luxembourg, French speaking territories of Africa, French overseas departments, Netherlands, Quebec"
// ConditionZero first batch 40,700 keys **Next free 'StartUniqueSerialNumber' = 40700
eExportFrance = 21,
// This a Vivendi code meaning "Austria, Switzerland, Bulgaria, Czech Republic, Hungary, Lithuania, Poland, Romania, Russian Federation, Slovenia, Slovakia"
// ConditionZero first batch 16,500 keys **Next free 'StartUniqueSerialNumber' = 16500
eExportNorth = 22,
// This a Vivendi code meaning "Cyprus, Egypt, Greece, Israel, Lebanon, Malta, Turkey"
// ConditionZero first batch 40,700 keys **Next free 'StartUniqueSerialNumber' = 40700
eExportSouth = 23,
// MISSING ONES ARE ON MI (24..29)
// ATI Rebate
// HL2 first batch 100,000 keys
eATI_Rebate = 30,
// Used for internal and pre-release testing keys.
// DoD first batch 20 keys **Next free 'StartUniqueSerialNumber' = 20
// DoD second batch 150 keys **Next free 'StartUniqueSerialNumber' = 170
// DoD second batch 500 keys **Next free 'StartUniqueSerialNumber' = 670
// ConditionZero first batch 200 keys **Next free 'StartUniqueSerialNumber' = 200
// CyberCafeBundle first batch 100 keys **Next free 'StartUniqueSerialNumber' = 100
eInternal = 255
};
#endif // VALVECDKEYGAMEANDTERRITORYCODES_H

View File

@ -0,0 +1,108 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef BUGREPORTER_H
#define BUGREPORTER_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
abstract_class IBugReporter : public IBaseInterface
{
public:
// Initialize and login with default username/password for this computer (from resource/bugreporter.res)
virtual bool Init( CreateInterfaceFn engineFactory ) = 0;
virtual void Shutdown() = 0;
virtual bool IsPublicUI() = 0;
virtual char const *GetUserName() = 0;
virtual char const *GetUserName_Display() = 0;
virtual int GetNameCount() = 0;
virtual char const *GetName( int index ) = 0;
virtual int GetDisplayNameCount() = 0;
virtual char const *GetDisplayName( int index ) = 0;
virtual char const *GetDisplayNameForUserName( char const *username ) = 0;
virtual char const *GetUserNameForDisplayName( char const *display ) = 0;
virtual int GetSeverityCount() = 0;
virtual char const *GetSeverity( int index ) = 0;
virtual int GetPriorityCount() = 0;
virtual char const *GetPriority( int index ) = 0;
virtual int GetAreaCount() = 0;
virtual char const *GetArea( int index ) = 0;
virtual int GetAreaMapCount() = 0;
virtual char const *GetAreaMap( int index ) = 0;
virtual int GetMapNumberCount() = 0;
virtual char const *GetMapNumber( int index ) = 0;
virtual int GetReportTypeCount() = 0;
virtual char const *GetReportType( int index ) = 0;
virtual char const *GetRepositoryURL( void ) = 0;
virtual char const *GetSubmissionURL( void ) = 0;
virtual int GetLevelCount(int area) = 0;
virtual char const *GetLevel(int area, int index ) = 0;
// Submission API
virtual void StartNewBugReport() = 0;
virtual void CancelNewBugReport() = 0;
virtual bool CommitBugReport( int& bugSubmissionId ) = 0;
virtual void SetTitle( char const *title ) = 0;
virtual void SetDescription( char const *description ) = 0;
// NULL for current user
virtual void SetSubmitter( char const *username = 0 ) = 0;
virtual void SetOwner( char const *username ) = 0;
virtual void SetSeverity( char const *severity ) = 0;
virtual void SetPriority( char const *priority ) = 0;
virtual void SetArea( char const *area ) = 0;
virtual void SetMapNumber( char const *area ) = 0;
virtual void SetReportType( char const *reporttype ) = 0;
virtual void SetLevel( char const *levelnamne ) = 0;
virtual void SetPosition( char const *position ) = 0;
virtual void SetOrientation( char const *pitch_yaw_roll ) = 0;
virtual void SetBuildNumber( char const *build_num ) = 0;
virtual void SetScreenShot( char const *screenshot_unc_address ) = 0;
virtual void SetSaveGame( char const *savegame_unc_address ) = 0;
virtual void SetBSPName( char const *bsp_unc_address ) = 0;
virtual void SetVMFName( char const *vmf_unc_address ) = 0;
virtual void AddIncludedFile( char const *filename ) = 0;
virtual void ResetIncludedFiles() = 0;
virtual void SetZipAttachmentName( char const *zipfilename ) = 0;
virtual void SetDriverInfo( char const *info ) = 0;
virtual void SetMiscInfo( char const *info ) = 0;
virtual void SetCSERAddress( const struct netadr_s& adr ) = 0;
virtual void SetExeName( char const *exename ) = 0;
virtual void SetGameDirectory( char const *gamedir ) = 0;
virtual void SetRAM( int ram ) = 0;
virtual void SetCPU( int cpu ) = 0;
virtual void SetProcessor( char const *processor ) = 0;
virtual void SetDXVersion( unsigned int high, unsigned int low, unsigned int vendor, unsigned int device ) = 0;
virtual void SetOSVersion( char const *osversion ) = 0;
virtual void SetSteamUserID( void *steamid, int idsize ) = 0;
};
#define INTERFACEVERSION_BUGREPORTER "BugReporter004"
#endif // BUGREPORTER_H

View File

@ -0,0 +1,103 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Swap a compiled caption file.
//
// $NoKeywords: $
//=============================================================================//
#include "utlbuffer.h"
#include "byteswap.h"
#include "filesystem.h"
#include "tier2/fileutils.h"
#include "captioncompiler.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
BEGIN_BYTESWAP_DATADESC( CompiledCaptionHeader_t )
DEFINE_FIELD( magic, FIELD_INTEGER ),
DEFINE_FIELD( version, FIELD_INTEGER ),
DEFINE_FIELD( numblocks, FIELD_INTEGER ),
DEFINE_FIELD( blocksize, FIELD_INTEGER ),
DEFINE_FIELD( directorysize, FIELD_INTEGER ),
DEFINE_FIELD( dataoffset, FIELD_INTEGER ),
END_BYTESWAP_DATADESC()
BEGIN_BYTESWAP_DATADESC( CaptionLookup_t )
DEFINE_FIELD( hash, FIELD_INTEGER ),
DEFINE_FIELD( blockNum, FIELD_INTEGER ),
DEFINE_FIELD( offset, FIELD_SHORT ),
DEFINE_FIELD( length, FIELD_SHORT ),
END_BYTESWAP_DATADESC()
//-----------------------------------------------------------------------------
// Swap a compiled closecaption file
//-----------------------------------------------------------------------------
bool SwapClosecaptionFile( void *pData )
{
CByteswap swap;
swap.ActivateByteSwapping( true );
CompiledCaptionHeader_t *pHdr = (CompiledCaptionHeader_t*)pData;
if ( IsX360() )
{
// pre-swap file header
swap.SwapFieldsToTargetEndian( pHdr );
}
if ( pHdr->magic != COMPILED_CAPTION_FILEID || pHdr->version != COMPILED_CAPTION_VERSION )
{
// bad data
return false;
}
// lookup headers
pData = (byte*)pData + sizeof(CompiledCaptionHeader_t);
swap.SwapFieldsToTargetEndian( (CaptionLookup_t*)pData, pHdr->directorysize );
// unicode data
pData = (byte*)pHdr + pHdr->dataoffset;
swap.SwapBufferToTargetEndian( (wchar_t*)pData, (wchar_t*)pData, pHdr->numblocks * pHdr->blocksize / sizeof(wchar_t) );
if ( IsPC() )
{
// post-swap file header
swap.SwapFieldsToTargetEndian( pHdr );
}
return true;
}
#if defined( CLIENT_DLL )
//-----------------------------------------------------------------------------
// Callback for UpdateOrCreate - generates .360 file
//-----------------------------------------------------------------------------
static bool CaptionCreateCallback( const char *pSourceName, const char *pTargetName, const char *pPathID, void *pExtraData )
{
// Generate the file
CUtlBuffer buf;
bool bOk = g_pFullFileSystem->ReadFile( pSourceName, pPathID, buf );
if ( bOk )
{
bOk = SwapClosecaptionFile( buf.Base() );
if ( bOk )
{
bOk = g_pFullFileSystem->WriteFile( pTargetName, pPathID, buf );
}
else
{
Warning( "Failed to create %s\n", pTargetName );
}
}
return bOk;
}
//-----------------------------------------------------------------------------
// Calls utility function UpdateOrCreate
//-----------------------------------------------------------------------------
int UpdateOrCreateCaptionFile( const char *pSourceName, char *pTargetName, int maxLen, bool bForce )
{
return ::UpdateOrCreate( pSourceName, pTargetName, maxLen, "GAME", CaptionCreateCallback, bForce );
}
#endif

2219
common/crypto.cpp Normal file

File diff suppressed because it is too large Load Diff

281
common/crypto.h Normal file
View File

@ -0,0 +1,281 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: This module is for wrapping Crypto++ functions, including crypto++
// directly has nasty consequences polluting the global namespace, and
// conflicting with xdebug and locale stuff, so we only include it here
// and use this wrapper in the rest of our code.
//
// $NoKeywords: $
//=============================================================================
#ifndef CRYPTO_H
#define CRYPTO_H
#include <tier0/dbg.h> // for Assert & AssertMsg
#include "tier1/passwordhash.h"
#include "tier1/utlmemory.h"
#include <steam/steamtypes.h> // for Salt_t
extern void FreeListRNG();
const unsigned int k_cubSHA256Hash = 32;
typedef unsigned char SHA256Digest_t[ k_cubSHA256Hash ];
const int k_nSymmetricBlockSize = 16; // AES block size (128 bits)
const int k_nSymmetricKeyLen = 32; // length in bytes of keys used for symmetric encryption
const int k_nRSAKeyLenMax = 1024; // max length in bytes of keys used for RSA encryption (includes DER encoding)
const int k_nRSAKeyLenMaxEncoded = k_nRSAKeyLenMax*2; // max length in bytes of hex-encoded key (hex encoding exactly doubles size)
const int k_nRSAKeyBits = 1024; // length in bits of keys used for RSA encryption
const int k_cubRSAEncryptedBlockSize = 128;
const int k_cubRSAPlaintextBlockSize = 86 + 1; // assume plaintext is text, so add a byte for the trailing \0
const uint32 k_cubRSASignature = k_cubRSAEncryptedBlockSize;
// Simple buffer class to encapsulate output from crypto functions with unknown output size
class CCryptoOutBuffer
{
public:
CCryptoOutBuffer()
{
m_pubData = NULL;
m_cubData = 0;
}
~CCryptoOutBuffer()
{
if ( m_pubData )
delete[] m_pubData;
m_pubData = NULL;
m_cubData = 0;
}
void Set( uint8 *pubData, uint32 cubData )
{
if ( !pubData || !cubData )
return;
if ( m_pubData )
delete[] m_pubData;
m_pubData = new uint8[ cubData ];
memcpy( m_pubData, pubData, cubData );
m_cubData = cubData;
}
void Allocate( uint32 cubData )
{
if ( m_pubData )
delete[] m_pubData;
m_pubData = new uint8[ cubData ];
m_cubData = cubData;
}
void Trim( uint32 cubTrim )
{
Assert( cubTrim <= m_cubData );
m_cubData = cubTrim;
}
uint8 *PubData() { return m_pubData; }
uint32 CubData() { return m_cubData; }
private:
uint8 *m_pubData;
uint32 m_cubData;
};
#if !defined(_PS3)
class CCrypto
{
public:
static uint32 GetSymmetricEncryptedSize( uint32 cubPlaintextData );
// this method writes the encrypted IV, then the ciphertext
static bool SymmetricEncryptWithIV( const uint8 * pubPlaintextData, uint32 cubPlaintextData,
const uint8 * pIV, uint32 cubIV,
uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
const uint8 * pubKey, uint32 cubKey );
static bool SymmetricEncrypt( const uint8 * pubPlaintextData, uint32 cubPlaintextData,
uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
const uint8 * pubKey, uint32 cubKey );
// this method assumes there is no IV before the payload - dissimilar to SymmetricEncryptWithIV
static bool SymmetricDecryptWithIV( const uint8 * pubEncryptedData, uint32 cubEncryptedData,
const uint8 * pIV, uint32 cubIV,
uint8 * pubPlaintextData, uint32 * pcubPlaintextData,
const uint8 * pubKey, uint32 cubKey );
static bool SymmetricDecrypt( const uint8 * pubEncryptedData, uint32 cubEncryptedData,
uint8 * pubPlaintextData, uint32 * pcubPlaintextData,
const uint8 * pubKey, uint32 cubKey );
// symmetrically encrypt data with a text password. A SHA256 hash of the password
// is used as an AES encryption key (calls SymmetricEncrypt, above).
// An HMAC of the ciphertext is appended, for authentication.
static bool EncryptWithPasswordAndHMAC( const uint8 *pubPlaintextData, uint32 cubPlaintextData,
uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
const char *pchPassword );
// Same as above but uses an explicit IV. The format of the ciphertext is the same.
// Be sure you know what you're doing if you use this - a random IV is much more secure in general!
static bool EncryptWithPasswordAndHMACWithIV( const uint8 *pubPlaintextData, uint32 cubPlaintextData,
const uint8 * pIV, uint32 cubIV,
uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
const char *pchPassword );
// Symmetrically decrypt data with the given password (see above).
// If the HMAC does not match what we expect, then we know that either the password is
// incorrect or the message is corrupted.
static bool DecryptWithPasswordAndAuthenticate( const uint8 * pubEncryptedData, uint32 cubEncryptedData,
uint8 * pubPlaintextData, uint32 * pcubPlaintextData,
const char *pchPassword );
static bool RSAGenerateKeys( uint8 *pubPublicKey, uint32 *pcubPublicKey, uint8 *pubPrivateKey, uint32 *pcubPrivateKey );
static bool RSAEncrypt( const uint8 *pubPlaintextPlaintextData, const uint32 cubData, uint8 *pubEncryptedData,
uint32 *pcubEncryptedData, const uint8 *pubPublicKey, const uint32 cubPublicKey );
static bool RSADecrypt( const uint8 *pubEncryptedData, uint32 cubEncryptedData,
uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPrivateKey, const uint32 cubPrivateKey );
// decrypt using a public key, and no padding
static bool RSAPublicDecrypt_NoPadding( const uint8 *pubEncryptedData, uint32 cubEncryptedData,
uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPublicKey, const uint32 cubPublicKey );
static bool RSASign( const uint8 *pubData, const uint32 cubData,
uint8 *pubSignature, uint32 *pcubSignature,
const uint8 * pubPrivateKey, const uint32 cubPrivateKey );
static bool RSAVerifySignature( const uint8 *pubData, const uint32 cubData,
const uint8 *pubSignature, const uint32 cubSignature,
const uint8 *pubPublicKey, const uint32 cubPublicKey );
static bool RSASignSHA256( const uint8 *pubData, const uint32 cubData,
uint8 *pubSignature, uint32 *pcubSignature,
const uint8 * pubPrivateKey, const uint32 cubPrivateKey );
static bool RSAVerifySignatureSHA256( const uint8 *pubData, const uint32 cubData,
const uint8 *pubSignature, const uint32 cubSignature,
const uint8 *pubPublicKey, const uint32 cubPublicKey );
static bool HexEncode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
static bool HexDecode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
static uint32 Base64EncodeMaxOutput( uint32 cubData, const char *pszLineBreakOrNull );
static bool Base64Encode( const uint8 *pubData, uint32 cubData, char *pchEncodedData, uint32 cchEncodedData, bool bInsertLineBreaks = true ); // legacy, deprecated
static bool Base64Encode( const uint8 *pubData, uint32 cubData, char *pchEncodedData, uint32 *pcchEncodedData, const char *pszLineBreak = "\n" );
static uint32 Base64DecodeMaxOutput( uint32 cubData ) { return ( (cubData + 3 ) / 4) * 3 + 1; }
static bool Base64Decode( const char *pchEncodedData, uint8 *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true ); // legacy, deprecated
static bool Base64Decode( const char *pchEncodedData, uint32 cchEncodedData, uint8 *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true );
static bool GenerateSalt( Salt_t *pSalt );
static bool GenerateSHA1Digest( const uint8 *pubInput, const int cubInput, SHADigest_t *pOutDigest );
static bool GenerateSaltedSHA1Digest( const char *pchInput, const Salt_t *pSalt, SHADigest_t *pOutDigest );
static bool GenerateRandomBlock( uint8 *pubDest, int cubDest );
static bool GenerateHMAC( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHADigest_t *pOutputDigest );
static bool GenerateHMAC256( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHA256Digest_t *pOutputDigest );
static bool BGeneratePasswordHash( const char *pchInput, EPasswordHashAlg hashType, const Salt_t &Salt, PasswordHash_t &OutPasswordHash );
static bool BValidatePasswordHash( const char *pchInput, EPasswordHashAlg hashType, const PasswordHash_t &DigestStored, const Salt_t &Salt, PasswordHash_t *pDigestComputed );
static bool BGeneratePBKDF2Hash( const char *pchInput, const Salt_t &Salt, unsigned int rounds, PasswordHash_t &OutPasswordHash );
static bool BGenerateWrappedSHA1PasswordHash( const char *pchInput, const Salt_t &Salt, unsigned int rounds, PasswordHash_t &OutPasswordHash );
static bool BUpgradeOrWrapPasswordHash( PasswordHash_t &InPasswordHash, EPasswordHashAlg hashTypeIn, const Salt_t &Salt, PasswordHash_t &OutPasswordHash, EPasswordHashAlg &hashTypeOut );
static bool BGzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
static bool BGunzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
#ifdef DBGFLAG_VALIDATE
static void ValidateStatics( CValidator &validator, const char *pchName );
#endif
};
#else
// bugbug ps3 - stub until we implement from PS3 libs
class CCrypto
{
public:
// ps3 only
static bool Init();
static void Shutdown();
//shared
static uint32 GetSymmetricEncryptedSize( uint32 cubPlaintextData );
static bool SymmetricEncrypt( const uint8 * pubPlaintextData, uint32 cubPlaintextData, uint8 * pubEncryptedData, uint32 * pcubEncryptedData, const uint8 * pubKey, uint32 cubKey );
static bool SymmetricDecrypt( const uint8 * pubEncryptedData, uint32 cubEncryptedData, uint8 * pubPlaintextData, uint32 * pcubPlaintextData, const uint8 * pubKey, uint32 cubKey );
static bool RSAGenerateKeys( uint8 *pubPublicKey, uint32 *pcubPublicKey, uint8 *pubPrivateKey, uint32 *pcubPrivateKey ) { AssertMsg( false, "RSAGenerateKeys not implemented on PS3" ); return false; }
static bool RSAEncrypt( const uint8 *pubPlaintextPlaintextData, const uint32 cubData, uint8 *pubEncryptedData, uint32 *pcubEncryptedData, const uint8 *pubPublicKey, const uint32 cubPublicKey );
static bool RSADecrypt( const uint8 *pubEncryptedData, uint32 cubEncryptedData, uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPrivateKey, const uint32 cubPrivateKey );
static bool RSAPublicDecrypt_NoPadding( const uint8 *pubEncryptedData, uint32 cubEncryptedData, uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPublicKey, const uint32 cubPublicKey ) { AssertMsg( false, "RSAPublicDecrypt_NoPadding not implemented on PS3" ); return false; }
static bool RSASign( const uint8 *pubData, const uint32 cubData, uint8 *pubSignature, uint32 *pcubSignature, const uint8 * pubPrivateKey, const uint32 cubPrivateKey );
static bool RSAVerifySignature( const uint8 *pubData, const uint32 cubData, const uint8 *pubSignature, const uint32 cubSignature, const uint8 *pubPublicKey, const uint32 cubPublicKey );
static bool HexEncode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
static bool HexDecode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
static bool Base64Encode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData, bool bInsertLineBreaks = true ) { AssertMsg( false, "Base64Encode not implemented on PS3" ); return false; } // cellHttpUtilBase64Encoder()
static bool Base64Decode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true ) { AssertMsg( false, "Base64Decode not implemented on PS3" ); return false; } // cellHttpUtilBase64Decoder()
static bool GenerateSalt( Salt_t *pSalt );
static bool GenerateSHA1Digest( const uint8 *pubInput, const int cubInput, SHADigest_t *pOutDigest );
static bool GenerateSaltedSHA1Digest( const char *pchInput, const Salt_t *pSalt, SHADigest_t *pOutDigest ) { AssertMsg( false, "GenerateSaltedSHA1Digest not implemented on PS3" ); return false; }
static bool GenerateRandomBlock( uint8 *pubDest, int cubDest );
static bool GenerateHMAC( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHADigest_t *pOutputDigest ) { AssertMsg( false, "GenerateHMAC not implemented on PS3" ); return false; }
static bool GenerateHMAC256( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHA256Digest_t *pOutputDigest ) { AssertMsg( false, "GenerateHMAC256 not implemented on PS3" ); return false; }
static bool BGzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
static bool BGunzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
#ifdef DBGFLAG_VALIDATE
static void ValidateStatics( CValidator &validator, const char *pchName );
#endif
};
#endif //!_PS3
class CSimpleBitString;
//-----------------------------------------------------------------------------
// Purpose: Implement hex encoding / decoding using a custom lookup table.
// This is a class because the decoding is done via a generated
// reverse-lookup table, and to save time it's best to just create
// that table once.
//-----------------------------------------------------------------------------
class CCustomHexEncoder
{
public:
CCustomHexEncoder( const char *pchEncodingTable );
~CCustomHexEncoder();
bool Encode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
bool Decode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
private:
bool m_bValidEncoding;
uint8 m_rgubEncodingTable[16];
int m_rgnDecodingTable[256];
};
//-----------------------------------------------------------------------------
// Purpose: Implement base32 encoding / decoding using a custom lookup table.
// This is a class because the decoding is done via a generated
// reverse-lookup table, and to save time it's best to just create
// that table once.
//-----------------------------------------------------------------------------
class CCustomBase32Encoder
{
public:
CCustomBase32Encoder( const char *pchEncodingTable );
~CCustomBase32Encoder();
bool Encode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
bool Decode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
bool Encode( CSimpleBitString *pBitStringData, char *pchEncodedData, uint32 cchEncodedData );
bool Decode( const char *pchData, CSimpleBitString *pBitStringDecodedData );
private:
bool m_bValidEncoding;
uint8 m_rgubEncodingTable[32];
int m_rgnDecodingTable[256];
};
#endif // CRYPTO_H

View File

@ -0,0 +1,166 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef CSERSERVERPROTOCOL_ENGINE_H
#define CSERSERVERPROTOCOL_ENGINE_H
#ifdef _WIN32
#pragma once
#endif
// NOTE: These defined must match the ones in Steam's CSERServerProtocol.h!!!
#define C2M_REPORT_GAMESTATISTICS 'k'
#define C2M_REPORT_GAMESTATISTICS_PROTOCOL_VERSION_1 1
#define C2M_REPORT_GAMESTATISTICS_PROTOCOL_VERSION 2
typedef enum
{
GS_UNKNOWN = 0,
GS_NO_UPLOAD,
GS_UPLOAD_REQESTED,
// Must be last
GS_NUM_TYPES
} EGameStatsEnum;
// C2M_REPORT_GAMESTATISTICS details (OLD VERSION)
// u8(C2M_REPORT_GAMESTATISTICS_PROTOCOL_VERSION_1)
// u32(build_number)
// string( exename )
// string( gamedir )
// string( mapname )
// u32 requested upload data length
// C2M_REPORT_GAMESTATISTICS details (current version)
// u8(C2M_REPORT_GAMESTATISTICS_PROTOCOL_VERSION)
// u32(appID)
// u32 requested upload data length
#define M2C_ACKREPORT_GAMESTATISTICS 'l'
// M2C_ACKREPORT_GAMESTATISTICS details
// u8(protocol okay (bool))
// u8(GS_NO_UPLOAD or GS_UPLOAD_REQESTED )
// iff GS_UPLOAD_REQESTED then add:
// u32(harvester ip address)
// u16(harvester port #)
// u32(upload context id)
#define C2M_PHONEHOME 'm'
#define C2M_PHONEHOME_PROTOCOL_VERSION 3
// C2M_PHONEHOME
// u8( C2M_PHONEHOME_PROTOCOL_VERSION )
// u32( sessionid ) or 0 to request a new sessionid
// u16(encryptedlength)
// remainder = encrypteddata:
// u8 corruption id == 1
// string build unique id
// string computername
// string username
// string gamedir
// float( enginetimestamp )
// u8 messagetype:
// 1: engine startup
// 2: engine shutdown
// 3: map started + mapname
// 4: map finished + mapname
// string( mapname )
#define M2C_ACKPHONEHOME 'n'
// M2C_ACKPHONEHOME details
// u8(connection allowed (bool))
// u32(sessionid)
#define C2M_BUGREPORT 'o'
#define C2M_BUGREPORT_PROTOCOL_VERSION 3
// C2M_BUGREPORT details
// u8(C2M_BUGREPORT_PROTOCOL_VERSION)
// u16(encryptedlength)
// remainder=encrypteddata
// encrypted payload:
// byte corruptionid = 1
// u32(buildnumber)
// string(exename 64)
// string(gamedir 64)
// string(mapname 64)
// u32 RAM
// u32 CPU
// string(processor)
// u32 DXVerHigh
// u32 DXVerLow
// u32 DXVendorID
// u32 DXDeviceID
// string(OSVer)
// Version 2+:
// {
// reporttype(char 32)
// email(char 80)
// accountname(char 80)
// }
// Version 3+
// {
// userid( sizeof( TSteamGlobalUserID ) )
// }
// --- all versions
// string(title 128)
// u32(.zip file size, or 0 if none available)
// u32(text length > max 1024)
// text(descriptive text -- capped to text length bytes)
#define M2C_ACKBUGREPORT 'p'
typedef enum
{
BR_UNKNOWN = 0,
BR_NO_FILES,
BR_REQEST_FILES,
// Must be last
BR_NUM_TYPES
} EBugReportAckEnum;
// M2C_ACKBUGREPORT details
// u8(protocol okay (bool))
// u8(BR_NO_FILES or BR_REQEST_FILES )
// iff BR_REQEST_FILES then add:
// u32(harvester ip address)
// u16(harvester port #)
// u32(upload context id)
// Arbitrary encrypted data upload
#define C2M_UPLOADDATA 'q'
#define C2M_UPLOADDATA_PROTOCOL_VERSION 1
#define C2M_UPLOADDATA_DATA_VERSION 1
// C2M_BUGREPORT details
// u8(C2M_UPLOADDATA_PROTOCOL_VERSION)
// u16(encryptedlength)
// remainder=encrypteddata
// encrypted payload:
// byte(corruptionid)
// byte(protocolid) // C2M_UPLOADDATA_DATA_VERSION
// string(tablename 40)
// u8(numvalues)
// for each value:
// string(fieldname 32)
// string(value 128)
#define M2C_ACKUPLOADDATA 'r'
// M2C_ACKUPLOADDATA details
// u8(protocol okay (bool))
#endif // CSERSERVERPROTOCOL_ENGINE_H

117
common/cstringhash.h Normal file
View File

@ -0,0 +1,117 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CSTRINGHASH_H
#define CSTRINGHASH_H
#pragma once
#include "string.h"
#define STRING_HASH_TABLE_SIZE 701
template <class T> class CStringHash
{
public:
CStringHash()
{
memset( m_HashTable, 0, sizeof( StringHashNode_t * ) * STRING_HASH_TABLE_SIZE );
}
~CStringHash()
{
int i;
for( i = 0; i < STRING_HASH_TABLE_SIZE; i++ )
{
StringHashNode_t *curEntry;
curEntry = m_HashTable[i];
if( curEntry )
{
StringHashNode_t *next;
next = curEntry->next;
delete curEntry;
curEntry = next;
}
}
}
// return false if it already exists
// there can only be one entry for each string.
bool Insert( const char *string, T val )
{
unsigned int hashID = HashString( string );
StringHashNode_t *newEntry;
if( !m_HashTable[hashID] )
{
// first on at this hashID
// fixme: need to make the allocation function configurable.
newEntry = m_HashTable[hashID] = new StringHashNode_t;
newEntry->next = NULL;
}
else
{
StringHashNode_t *curEntry;
curEntry = m_HashTable[hashID];
while( curEntry )
{
if( stricmp( curEntry->string, string ) == 0 )
{
// replace the data at the current entry with the enw data.
curEntry->data = val;
return false;
}
curEntry = curEntry->next;
}
newEntry = new StringHashNode_t;
newEntry->next = m_HashTable[hashID];
m_HashTable[hashID] = newEntry;
}
int len = strlen( string ) + 1;
newEntry->string = new char[len];
Q_strncpy( newEntry->string, string, len );
newEntry->data = val;
return true;
}
T Find( const char *string )
{
int hashID = HashString( string );
StringHashNode_t *curEntry;
curEntry = m_HashTable[hashID];
while( curEntry )
{
if( stricmp( curEntry->string, string ) == 0 )
{
return curEntry->data;
}
curEntry = curEntry->next;
}
return NULL;
}
private:
unsigned int HashString( const char *string )
{
const char *s = string;
unsigned int result = 0;
while( *s )
{
result += tolower( ( int )*s ) * 6029;
result *= 5749;
s++;
}
return result % STRING_HASH_TABLE_SIZE;
}
typedef struct StringHashNode_s
{
char *string;
T data;
struct StringHashNode_s *next;
} StringHashNode_t;
StringHashNode_t *m_HashTable[STRING_HASH_TABLE_SIZE];
};
#endif // CSTRINGHASH_H

2119
common/curl/curl.h Normal file

File diff suppressed because it is too large Load Diff

583
common/curl/curlbuild.h Normal file
View File

@ -0,0 +1,583 @@
#ifndef __CURL_CURLBUILD_H
#define __CURL_CURLBUILD_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* ================================================================ */
/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
/* ================================================================ */
/*
* NOTE 1:
* -------
*
* See file include/curl/curlbuild.h.in, run configure, and forget
* that this file exists it is only used for non-configure systems.
* But you can keep reading if you want ;-)
*
*/
/* ================================================================ */
/* NOTES FOR NON-CONFIGURE SYSTEMS */
/* ================================================================ */
/*
* NOTE 1:
* -------
*
* Nothing in this file is intended to be modified or adjusted by the
* curl library user nor by the curl library builder.
*
* If you think that something actually needs to be changed, adjusted
* or fixed in this file, then, report it on the libcurl development
* mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
*
* Try to keep one section per platform, compiler and architecture,
* otherwise, if an existing section is reused for a different one and
* later on the original is adjusted, probably the piggybacking one can
* be adversely changed.
*
* In order to differentiate between platforms/compilers/architectures
* use only compiler built in predefined preprocessor symbols.
*
* This header file shall only export symbols which are 'curl' or 'CURL'
* prefixed, otherwise public name space would be polluted.
*
* NOTE 2:
* -------
*
* For any given platform/compiler curl_off_t must be typedef'ed to a
* 64-bit wide signed integral data type. The width of this data type
* must remain constant and independent of any possible large file
* support settings.
*
* As an exception to the above, curl_off_t shall be typedef'ed to a
* 32-bit wide signed integral data type if there is no 64-bit type.
*
* As a general rule, curl_off_t shall not be mapped to off_t. This
* rule shall only be violated if off_t is the only 64-bit data type
* available and the size of off_t is independent of large file support
* settings. Keep your build on the safe side avoiding an off_t gating.
* If you have a 64-bit off_t then take for sure that another 64-bit
* data type exists, dig deeper and you will find it.
*
* NOTE 3:
* -------
*
* Right now you might be staring at file include/curl/curlbuild.h.dist or
* at file include/curl/curlbuild.h, this is due to the following reason:
* file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h
* when the libcurl source code distribution archive file is created.
*
* File include/curl/curlbuild.h.dist is not included in the distribution
* archive. File include/curl/curlbuild.h is not present in the git tree.
*
* The distributed include/curl/curlbuild.h file is only intended to be used
* on systems which can not run the also distributed configure script.
*
* On systems capable of running the configure script, the configure process
* will overwrite the distributed include/curl/curlbuild.h file with one that
* is suitable and specific to the library being configured and built, which
* is generated from the include/curl/curlbuild.h.in template file.
*
* If you check out from git on a non-configure platform, you must run the
* appropriate buildconf* script to set up curlbuild.h and other local files.
*
*/
/* ================================================================ */
/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
/* ================================================================ */
#ifdef CURL_SIZEOF_LONG
# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
#endif
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
#endif
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
#endif
#ifdef CURL_TYPEOF_CURL_OFF_T
# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
#endif
#ifdef CURL_FORMAT_CURL_OFF_T
# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
#endif
#ifdef CURL_FORMAT_CURL_OFF_TU
# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
#endif
#ifdef CURL_FORMAT_OFF_T
# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
#endif
#ifdef CURL_SIZEOF_CURL_OFF_T
# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
#endif
#ifdef CURL_SUFFIX_CURL_OFF_T
# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
#endif
#ifdef CURL_SUFFIX_CURL_OFF_TU
# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
#endif
/* ================================================================ */
/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */
/* ================================================================ */
#if defined(__DJGPP__) || defined(__GO32__)
# if defined(__DJGPP__) && (__DJGPP__ > 1)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# else
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__SALFORDC__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__BORLANDC__)
# if (__BORLANDC__ < 0x520)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_FORMAT_OFF_T "%I64d"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__TURBOC__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__WATCOMC__)
# if defined(__386__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_FORMAT_OFF_T "%I64d"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__POCC__)
# if (__POCC__ < 280)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# elif defined(_MSC_VER)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_FORMAT_OFF_T "%I64d"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__LCC__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__SYMBIAN32__)
# if defined(__EABI__) /* Treat all ARM compilers equally */
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__CW32__)
# pragma longlong on
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__VC32__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__MWERKS__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(_WIN32_WCE)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_FORMAT_OFF_T "%I64d"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__MINGW32__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_FORMAT_OFF_T "%I64d"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__VMS)
# if defined(__VAX)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
#elif defined(__OS400__)
# if defined(__ILEC400__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(__MVS__)
# if defined(__IBMC__) || defined(__IBMCPP__)
# if defined(_ILP32)
# define CURL_SIZEOF_LONG 4
# elif defined(_LP64)
# define CURL_SIZEOF_LONG 8
# endif
# if defined(_LONG_LONG)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(__370__)
# if defined(__IBMC__) || defined(__IBMCPP__)
# if defined(_ILP32)
# define CURL_SIZEOF_LONG 4
# elif defined(_LP64)
# define CURL_SIZEOF_LONG 8
# endif
# if defined(_LONG_LONG)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(TPF)
# define CURL_SIZEOF_LONG 8
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
/* ===================================== */
/* KEEP MSVC THE PENULTIMATE ENTRY */
/* ===================================== */
#elif defined(_MSC_VER)
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_FORMAT_OFF_T "%I64d"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 4
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
/* ===================================== */
/* KEEP GENERIC GCC THE LAST ENTRY */
/* ===================================== */
#elif defined(__GNUC__)
# if defined(__i386__) || defined(__ppc__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__x86_64__) || defined(__ppc64__)
# define CURL_SIZEOF_LONG 8
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_SIZEOF_CURL_SOCKLEN_T 4
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#else
# error "Unknown non-configure build target!"
Error Compilation_aborted_Unknown_non_configure_build_target
#endif
/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
/* sys/types.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_TYPES_H
# include <sys/types.h>
#endif
/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
/* sys/socket.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_SOCKET_H
# include <sys/socket.h>
#endif
/* Data type definition of curl_socklen_t. */
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
#endif
/* Data type definition of curl_off_t. */
#ifdef CURL_TYPEOF_CURL_OFF_T
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
#endif
#endif /* __CURL_CURLBUILD_H */

Some files were not shown because too many files have changed in this diff Show More