This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

View File

@@ -0,0 +1,136 @@
// ----------------------------------------- //
// File generated by VPC //
// ----------------------------------------- //
Source file: F:\csgo_64\cstrike15_src\tier2\beamsegdraw.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\beamsegdraw.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\beamsegdraw.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Debug output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Release output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\defaultfilesystem.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\defaultfilesystem.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\defaultfilesystem.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\fileutils.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\fileutils.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\fileutils.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\interval.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\interval.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\interval.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\keybindings.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\keybindings.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\keybindings.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\public\map_utils.cpp
Debug output file: F:\csgo_64\cstrike15_src\public\map_utils.cpp
Release output file: F:\csgo_64\cstrike15_src\public\map_utils.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\public\materialsystem\MaterialSystemUtil.cpp
Debug output file: F:\csgo_64\cstrike15_src\public\materialsystem\MaterialSystemUtil.cpp
Release output file: F:\csgo_64\cstrike15_src\public\materialsystem\MaterialSystemUtil.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\meshutils.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\meshutils.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\meshutils.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\p4helpers.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\p4helpers.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\p4helpers.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\renderutils.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\renderutils.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\renderutils.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\resourceprecacher.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\resourceprecacher.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\resourceprecacher.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\riff.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\riff.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\riff.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\schemaclassbinding.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\schemaclassbinding.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\schemaclassbinding.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\socketcreator.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\socketcreator.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\socketcreator.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\soundutils.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\soundutils.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\soundutils.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\tier2.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\tier2.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\tier2.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\tier2_logging.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\tier2_logging.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\tier2_logging.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\tokenreader.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\tokenreader.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\tokenreader.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\util_init.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\util_init.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\util_init.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\utlstreambuffer.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\utlstreambuffer.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\utlstreambuffer.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\tier2\vconfig.cpp
Debug output file: F:\csgo_64\cstrike15_src\tier2\vconfig.cpp
Release output file: F:\csgo_64\cstrike15_src\tier2\vconfig.cpp
Containing unity file:
PCH file:

341
tier2/beamsegdraw.cpp Normal file
View File

@@ -0,0 +1,341 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "tier2/beamsegdraw.h"
#include "materialsystem/imaterialvar.h"
#include "convar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
//
// CBeamSegDraw implementation.
//
//-----------------------------------------------------------------------------
void CBeamSegDraw::Start( IMatRenderContext *pRenderContext, int nSegs, IMaterial *pMaterial, CMeshBuilder *pMeshBuilder, int nMeshVertCount )
{
m_pRenderContext = pRenderContext;
Assert( nSegs >= 2 );
m_nSegsDrawn = 0;
m_nTotalSegs = nSegs;
m_pRenderContext->GetWorldSpaceCameraPosition( &m_vecCameraPos );
if ( pMeshBuilder )
{
m_pMeshBuilder = pMeshBuilder;
m_nMeshVertCount = nMeshVertCount;
}
else
{
m_pMeshBuilder = NULL;
m_nMeshVertCount = 0;
IMesh *pMesh = m_pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial );
m_Mesh.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, (nSegs-1) * 2 );
}
}
inline void CBeamSegDraw::ComputeNormal( const Vector &vecCameraPos, const Vector &vStartPos, const Vector &vNextPos, Vector *pNormal )
{
// vTangentY = line vector for beam
Vector vTangentY;
VectorSubtract( vStartPos, vNextPos, vTangentY );
// vDirToBeam = vector from viewer origin to beam
Vector vDirToBeam;
VectorSubtract( vStartPos, vecCameraPos, vDirToBeam );
// Get a vector that is perpendicular to us and perpendicular to the beam.
// This is used to fatten the beam.
CrossProduct( vTangentY, vDirToBeam, *pNormal );
VectorNormalizeFast( *pNormal );
}
inline void CBeamSegDraw::SpecifySeg( const Vector &vecCameraPos, const Vector &vNormal )
{
// SUCKY: Need to do a fair amount more work to get the tangent owing to the averaged normal
Vector vDirToBeam, vTangentY;
VectorSubtract( m_Seg.m_vPos, vecCameraPos, vDirToBeam );
CrossProduct( vDirToBeam, vNormal, vTangentY );
VectorNormalizeFast( vTangentY );
// Build the endpoints.
Vector vPoint1, vPoint2;
VectorMA( m_Seg.m_vPos, m_Seg.m_flWidth*0.5f, vNormal, vPoint1 );
VectorMA( m_Seg.m_vPos, -m_Seg.m_flWidth*0.5f, vNormal, vPoint2 );
if ( m_pMeshBuilder )
{
// Specify the points.
m_pMeshBuilder->Position3fv( vPoint1.Base() );
m_pMeshBuilder->Color4ubv( (const unsigned char *) &m_Seg.m_color );
m_pMeshBuilder->TexCoord2f( 0, 0, m_Seg.m_flTexCoord );
m_pMeshBuilder->TexCoord2f( 1, 0, m_Seg.m_flTexCoord );
m_pMeshBuilder->TangentS3fv( vNormal.Base() );
m_pMeshBuilder->TangentT3fv( vTangentY.Base() );
m_pMeshBuilder->AdvanceVertex();
m_pMeshBuilder->Position3fv( vPoint2.Base() );
m_pMeshBuilder->Color4ubv( (const unsigned char *) &m_Seg.m_color );
m_pMeshBuilder->TexCoord2f( 0, 1, m_Seg.m_flTexCoord );
m_pMeshBuilder->TexCoord2f( 1, 1, m_Seg.m_flTexCoord );
m_pMeshBuilder->TangentS3fv( vNormal.Base() );
m_pMeshBuilder->TangentT3fv( vTangentY.Base() );
m_pMeshBuilder->AdvanceVertex();
if ( m_nSegsDrawn > 1 )
{
int nBase = ( ( m_nSegsDrawn - 2 ) * 2 ) + m_nMeshVertCount;
m_pMeshBuilder->FastIndex( nBase );
m_pMeshBuilder->FastIndex( nBase + 1 );
m_pMeshBuilder->FastIndex( nBase + 2 );
m_pMeshBuilder->FastIndex( nBase + 1 );
m_pMeshBuilder->FastIndex( nBase + 3 );
m_pMeshBuilder->FastIndex( nBase + 2 );
}
}
else
{
// Specify the points.
m_Mesh.Position3fv( vPoint1.Base() );
m_Mesh.Color4ubv( (const unsigned char *) &m_Seg.m_color );
m_Mesh.TexCoord2f( 0, 0, m_Seg.m_flTexCoord );
m_Mesh.TexCoord2f( 1, 0, m_Seg.m_flTexCoord );
m_Mesh.TangentS3fv( vNormal.Base() );
m_Mesh.TangentT3fv( vTangentY.Base() );
m_Mesh.AdvanceVertex();
m_Mesh.Position3fv( vPoint2.Base() );
m_Mesh.Color4ubv( (const unsigned char *) &m_Seg.m_color );
m_Mesh.TexCoord2f( 0, 1, m_Seg.m_flTexCoord );
m_Mesh.TexCoord2f( 1, 1, m_Seg.m_flTexCoord );
m_Mesh.TangentS3fv( vNormal.Base() );
m_Mesh.TangentT3fv( vTangentY.Base() );
m_Mesh.AdvanceVertex();
}
}
void CBeamSegDraw::NextSeg( BeamSeg_t *pSeg )
{
if ( m_nSegsDrawn > 0 )
{
// Get a vector that is perpendicular to us and perpendicular to the beam.
// This is used to fatten the beam.
Vector vNormal, vAveNormal;
ComputeNormal( m_vecCameraPos, m_Seg.m_vPos, pSeg->m_vPos, &vNormal );
if ( m_nSegsDrawn > 1 )
{
// Average this with the previous normal
VectorAdd( vNormal, m_vNormalLast, vAveNormal );
vAveNormal *= 0.5f;
VectorNormalizeFast( vAveNormal );
}
else
{
vAveNormal = vNormal;
}
m_vNormalLast = vNormal;
SpecifySeg( m_vecCameraPos, vAveNormal );
}
m_Seg = *pSeg;
++m_nSegsDrawn;
if( m_nSegsDrawn == m_nTotalSegs )
{
SpecifySeg( m_vecCameraPos, m_vNormalLast );
}
}
void CBeamSegDraw::LoadSIMDData( FourVectors * RESTRICT pV4StartPos, FourVectors * RESTRICT pV4EndPos, FourVectors * RESTRICT pV4HalfWidth, int nV4SegCount, const BeamSeg_t * pSegs )
{
const BeamSeg_t *RESTRICT pCurSeg = pSegs;
for ( int i = 0; i < nV4SegCount; ++i, pCurSeg+= 4 )
{
pV4StartPos[i].LoadAndSwizzleAligned( pCurSeg[0].m_vPos, pCurSeg[1].m_vPos, pCurSeg[2].m_vPos, pCurSeg[3].m_vPos );
pV4EndPos[i].LoadAndSwizzleAligned( pCurSeg[1].m_vPos, pCurSeg[2].m_vPos, pCurSeg[3].m_vPos, pCurSeg[4].m_vPos );
// load and broadcast the halfwidths
// if you load from values in memory (rather than computed values in registers),
// .Load is faster.
pV4HalfWidth[i].Load( pCurSeg[0].m_flWidth , pCurSeg[1].m_flWidth , pCurSeg[2].m_flWidth , pCurSeg[3].m_flWidth );
pV4HalfWidth[i] *= Four_PointFives;
}
}
void CBeamSegDraw::ComputeRenderInfo( BeamSegRenderInfo_t * pRenderInfo, const Vector &vecCameraPos, int nSegCount, const BeamSeg_t *pSrcSegs ) RESTRICT
{
int nPaddedSegCount = ( ( nSegCount + 3 ) >> 2 ) << 2;
// FIXME: Can we figure out a way of avoiding this extra copy?
// NOTE: We need an extra one since LoadSIMDData will load off the end
BeamSeg_t *pSegs = (BeamSeg_t*)stackalloc( ( nPaddedSegCount + 1 ) * sizeof(BeamSeg_t) );
memcpy( pSegs, pSrcSegs, nSegCount * sizeof(BeamSeg_t) );
int nEndSegCount = ( nPaddedSegCount - nSegCount + 1 );
BeamSeg_t endCap = pSrcSegs[nSegCount-1];
endCap.m_vPos += pSrcSegs[nSegCount-1].m_vPos - pSrcSegs[nSegCount-2].m_vPos;
for ( int i = 0; i < nEndSegCount; ++i )
{
memcpy( &pSegs[nSegCount+i], &endCap, sizeof(BeamSeg_t) );
}
FourVectors v4CameraPos;
v4CameraPos.LoadAndSwizzle( vecCameraPos );
int nV4SegCount = nPaddedSegCount >> 2;
FourVectors *pV4StartPos = (FourVectors*)stackalloc( nV4SegCount * sizeof(FourVectors) );
FourVectors *pV4EndPos = (FourVectors*)stackalloc( nV4SegCount * sizeof(FourVectors) );
FourVectors *pV4HalfWidth = (FourVectors*)stackalloc( nV4SegCount * sizeof(FourVectors) );
FourVectors *pV4AveNormals = (FourVectors*)stackalloc( ( nV4SegCount + 2 ) * sizeof(FourVectors) );
CBeamSegDraw::LoadSIMDData( pV4StartPos, pV4EndPos, pV4HalfWidth, nV4SegCount, pSegs );
fltx4 v4LMask = { 0.25f, 0.25f, 0.25f, 0.0f };
fltx4 v4LPrevMask = { 0.0f, 0.0f, 0.0f, 0.25f };
fltx4 v4RMask = { 0.0f, 0.25f, 0.25f, 0.25f };
fltx4 v4RNextMask = { 0.25f, 0.0f, 0.0f, 0.0f };
fltx4 v4AveFactor = { 0.5f, 0.5f, 0.5f, 0.5f };
// This is the only ones that need initial data are the first two
memset( pV4AveNormals, 0, 2 * sizeof(FourVectors) );
// Yes, that 1 is correct. We're going to write bogus crap on either end
FourVectors eps( FLT_EPSILON );
FourVectors *pV4CurAveNormal = &pV4AveNormals[1];
for ( int i = 0; i < nV4SegCount; ++i, ++pV4CurAveNormal )
{
// prefetch
PREFETCH360( pRenderInfo + (i << 2), 0 );
PREFETCH360( pRenderInfo + (i << 2) + 1, 0 );
FourVectors v4TangentY = pV4StartPos[i] - pV4EndPos[i];
FourVectors v4CameraToStart = pV4StartPos[i] - v4CameraPos;
FourVectors v4Normal = v4TangentY ^ v4CameraToStart;
v4Normal += eps;
v4Normal = VectorNormalizeFast( v4Normal );
FourVectors v4LNormal = RotateLeft( v4Normal );
FourVectors v4RNormal = RotateRight( v4Normal );
pV4CurAveNormal[0] = Madd( v4Normal, v4AveFactor, pV4CurAveNormal[0] );
pV4CurAveNormal[0] = Madd( v4LNormal, v4LMask, pV4CurAveNormal[0] );
pV4CurAveNormal[0] = Madd( v4RNormal, v4RMask, pV4CurAveNormal[0] );
pV4CurAveNormal[-1] = Madd( v4LNormal, v4LPrevMask, pV4CurAveNormal[-1] );
pV4CurAveNormal[1] = Mul( v4RNormal, v4RNextMask );
}
// FIXME: Do I need to fixup the endpoints, to clamp their normals to the unsmoothed value?
// Maybe I can get away with not doing that.
FourVectors *pV4Normals = &pV4AveNormals[1];
FourVectors *pV4TangentY = (FourVectors*)stackalloc( nV4SegCount * sizeof(FourVectors) );
FourVectors *pV4Point1 = (FourVectors*)stackalloc( nV4SegCount * sizeof(FourVectors) );
FourVectors *pV4Point2 = (FourVectors*)stackalloc( nV4SegCount * sizeof(FourVectors) );
for ( int i = 0; i < nV4SegCount; ++i )
{
// prefetch
// (write top half rows)
PREFETCH360( pRenderInfo + (i << 2) + 2, 0 );
PREFETCH360( pRenderInfo + (i << 2) + 3, 0 );
FourVectors v4Normal = VectorNormalizeFast( pV4Normals[i] );
FourVectors v4CameraToStart = pV4StartPos[i] - v4CameraPos;
FourVectors v4TangentY = v4CameraToStart ^ v4Normal;
pV4Normals[i] = v4Normal;
v4TangentY += eps;
pV4TangentY[i] = VectorNormalizeFast( v4TangentY );
FourVectors v4Offset = Mul( v4Normal, pV4HalfWidth[i] );
pV4Point1[i] = pV4StartPos[i] + v4Offset;
pV4Point2[i] = pV4StartPos[i] - v4Offset;
}
const BeamSeg_t * RESTRICT pSeg = pSrcSegs;
// The code below has a few load-hit-stores (due to the
// transform to vector for store). For an alternate
// pathway that does the same thing without the LHS,
// see changelist 588032. It was more complicated, but
// didn't profile to actually be any faster, so it
// was taken back out.
for ( int i = 0 ; i < nSegCount; ++i, ++pRenderInfo, ++pSeg )
{
int nIndex = ( i >> 2 );
int j = ( i & 0x3 );
pRenderInfo->m_vecCenter = pV4StartPos[nIndex].Vec( j );
pRenderInfo->m_vecPoint1 = pV4Point1[nIndex].Vec( j );
pRenderInfo->m_vecPoint2 = pV4Point2[nIndex].Vec( j );
pRenderInfo->m_vecTangentS = pV4Normals[nIndex].Vec( j );
pRenderInfo->m_vecTangentT = pV4TangentY[nIndex].Vec( j );
pRenderInfo->m_flTexCoord = pSeg->m_flTexCoord;
pRenderInfo->m_color = pSeg->m_color;
}
}
void CBeamSegDraw::End()
{
if ( m_pMeshBuilder )
{
m_pMeshBuilder = NULL;
return;
}
m_Mesh.End( false, true );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBeamSegDrawArbitrary::SetNormal( const Vector &normal )
{
m_vNormalLast = normal;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBeamSegDrawArbitrary::NextSeg( BeamSeg_t *pSeg )
{
if ( m_nSegsDrawn > 0 )
{
Vector segDir = ( m_PrevSeg.m_vPos - pSeg->m_vPos );
VectorNormalize( segDir );
Vector normal = CrossProduct( segDir, m_vNormalLast );
SpecifySeg( normal );
}
m_PrevSeg = m_Seg;
m_Seg = *pSeg;
++m_nSegsDrawn;
}
void CBeamSegDrawArbitrary::SpecifySeg( const Vector &vNormal )
{
// Build the endpoints.
Vector vPoint1, vPoint2;
Vector vDelta;
VectorMultiply( vNormal, m_Seg.m_flWidth*0.5f, vDelta );
VectorAdd( m_Seg.m_vPos, vDelta, vPoint1 );
VectorSubtract( m_Seg.m_vPos, vDelta, vPoint2 );
m_Mesh.Position3fv( vPoint1.Base() );
m_Mesh.Color4ub( m_Seg.m_color.r, m_Seg.m_color.g, m_Seg.m_color.b, m_Seg.m_color.a );
m_Mesh.TexCoord2f( 0, 0, m_Seg.m_flTexCoord );
m_Mesh.TexCoord2f( 1, 0, m_Seg.m_flTexCoord );
m_Mesh.AdvanceVertex();
m_Mesh.Position3fv( vPoint2.Base() );
m_Mesh.Color4ub( m_Seg.m_color.r, m_Seg.m_color.g, m_Seg.m_color.b, m_Seg.m_color.a );
m_Mesh.TexCoord2f( 0, 1, m_Seg.m_flTexCoord );
m_Mesh.TexCoord2f( 1, 1, m_Seg.m_flTexCoord );
m_Mesh.AdvanceVertex();
}

View File

@@ -0,0 +1,57 @@
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A higher level link library for general use in the game and tools.
//
//===========================================================================//
#include <tier0/platform.h>
#include <tier2/tier2.h>
#include <filesystem_init.h>
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
static CSysModule *g_pFullFileSystemModule = NULL;
void* DefaultCreateInterfaceFn(const char *pName, int *pReturnCode)
{
if ( pReturnCode )
{
*pReturnCode = 0;
}
return NULL;
}
void InitDefaultFileSystem( void )
{
AssertMsg( !g_pFullFileSystem, "Already set up the file system" );
if ( !Sys_LoadInterface( "filesystem_stdio", FILESYSTEM_INTERFACE_VERSION,
&g_pFullFileSystemModule, (void**)&g_pFullFileSystem ) )
{
exit(0);
}
if ( !g_pFullFileSystem->Connect( DefaultCreateInterfaceFn ) )
{
exit(0);
}
if ( g_pFullFileSystem->Init() != INIT_OK )
{
exit(0);
}
g_pFullFileSystem->RemoveAllSearchPaths();
g_pFullFileSystem->AddSearchPath( "", "LOCAL", PATH_ADD_TO_HEAD );
g_pFullFileSystem->AddSearchPath( "", "DEFAULT_WRITE_PATH", PATH_ADD_TO_HEAD );
}
void ShutdownDefaultFileSystem(void)
{
AssertMsg( g_pFullFileSystem, "File system not set up" );
g_pFullFileSystem->Shutdown();
g_pFullFileSystem->Disconnect();
Sys_UnloadModule( g_pFullFileSystemModule );
}

330
tier2/fileutils.cpp Normal file
View File

@@ -0,0 +1,330 @@
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Helper methods + classes for file access
//
//===========================================================================//
#include "tier2/fileutils.h"
#include "tier2/tier2.h"
#include "tier1/strtools.h"
#include "filesystem.h"
#include "tier0/icommandline.h"
#include "tier1/utlbuffer.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Builds a directory which is a subdirectory of the current mod
//-----------------------------------------------------------------------------
void GetModSubdirectory( const char *pSubDir, char *pBuf, int nBufLen )
{
// Compute starting directory
Assert( g_pFullFileSystem->GetSearchPath( "MOD", false, NULL, 0 ) < nBufLen );
g_pFullFileSystem->GetSearchPath( "MOD", false, pBuf, nBufLen );
char *pSemi = strchr( pBuf, ';' );
if ( pSemi )
{
*pSemi = 0;
}
Q_StripTrailingSlash( pBuf );
if ( pSubDir )
{
int nLen = Q_strlen( pSubDir );
Q_strncat( pBuf, "\\", nBufLen, 1 );
Q_strncat( pBuf, pSubDir, nBufLen, nLen );
}
Q_FixSlashes( pBuf );
}
//-----------------------------------------------------------------------------
// Builds a directory which is a subdirectory of the current mod's *content*
//-----------------------------------------------------------------------------
void GetModContentSubdirectory( const char *pSubDir, char *pBuf, int nBufLen )
{
char pTemp[ MAX_PATH ];
GetModSubdirectory( pSubDir, pTemp, sizeof(pTemp) );
ComputeModContentFilename( pTemp, pBuf, nBufLen );
}
//-----------------------------------------------------------------------------
// Generates a filename under the 'game' subdirectory given a subdirectory of 'content'
//-----------------------------------------------------------------------------
void ComputeModFilename( const char *pContentFileName, char *pBuf, size_t nBufLen )
{
char pRelativePath[ MAX_PATH ];
if ( !g_pFullFileSystem->FullPathToRelativePathEx( pContentFileName, "CONTENT", pRelativePath, sizeof(pRelativePath) ) )
{
Q_strncpy( pBuf, pContentFileName, nBufLen );
return;
}
char pGameRoot[ MAX_PATH ];
g_pFullFileSystem->GetSearchPath( "GAME", false, pGameRoot, sizeof(pGameRoot) );
char *pSemi = strchr( pGameRoot, ';' );
if ( pSemi )
{
*pSemi = 0;
}
Q_ComposeFileName( pGameRoot, pRelativePath, pBuf, nBufLen );
}
//-----------------------------------------------------------------------------
// Generates a filename under the 'content' subdirectory given a subdirectory of 'game'
//-----------------------------------------------------------------------------
void ComputeModContentFilename( const char *pGameFileName, char *pBuf, size_t nBufLen )
{
char pRelativePath[ MAX_PATH ];
if ( !g_pFullFileSystem->FullPathToRelativePathEx( pGameFileName, "GAME", pRelativePath, sizeof(pRelativePath) ) )
{
Q_strncpy( pBuf, pGameFileName, nBufLen );
return;
}
char pContentRoot[ MAX_PATH ];
g_pFullFileSystem->GetSearchPath( "CONTENT", false, pContentRoot, sizeof(pContentRoot) );
char *pSemi = strchr( pContentRoot, ';' );
if ( pSemi )
{
*pSemi = 0;
}
Q_ComposeFileName( pContentRoot, pRelativePath, pBuf, nBufLen );
}
//-----------------------------------------------------------------------------
// Purpose: Generates an Xbox 360 filename from a PC filename
//-----------------------------------------------------------------------------
char *CreatePlatformFilename( const char *pSourceName, char *pTargetName, int targetLen )
{
Q_StripExtension( pSourceName, pTargetName, targetLen );
int idx = Q_strlen( pTargetName );
// restore extension
Q_snprintf( pTargetName, targetLen, "%s" PLATFORM_EXT "%s", pTargetName, &pSourceName[idx] );
return pTargetName;
}
//-----------------------------------------------------------------------------
// Purpose: Generates a PC filename from a possible 360 name.
// Strips the .360. from filename.360.extension.
// Filenames might have multiple '.', need to be careful and only consider the
// last true extension. Complex filenames do occur:
// d:\foo\.\foo.dat
// d:\zip0.360.zip\foo.360.dat
// Returns source if no change needs to occur, othwerwise generates and
// returns target.
//-----------------------------------------------------------------------------
char *RestoreFilename( const char *pSourceName, char *pTargetName, int targetLen )
{
// find extension
// scan backward for '.', but not past a seperator
int end = V_strlen( pSourceName ) - 1;
while ( end > 0 && pSourceName[end] != '.' && !( pSourceName[end] == '\\' || pSourceName[end] == '/' ) )
{
--end;
}
if ( end >= 4 && pSourceName[end] == '.' && ( !V_strncmp( pSourceName + end - 4 , ".360", 4 ) || !V_strnicmp( pSourceName + end - 4 , ".ps3", 4 ) ) )
{
// cull the .360, leave the trailing extension
end -= 4;
int length = MIN( end + 1, targetLen );
V_strncpy( pTargetName, pSourceName, length );
V_strncat( pTargetName, pSourceName + end + 4, targetLen );
return pTargetName;
}
// source filename is as expected
return (char *)pSourceName;
}
//-----------------------------------------------------------------------------
// Generate an Xbox 360 file if it doesn't exist or is out of date. This function determines
// the source and target path and whether the file needs to be generated. The caller provides
// a callback function to do the actual creation of the 360 file. "pExtraData" is for the caller to
// pass the address of any data that the callback function may need to access. This function
// is ONLY to be called by caller's who expect to have 360 versions of their file.
//-----------------------------------------------------------------------------
int UpdateOrCreate( const char *pSourceName, char *pTargetName, int targetLen, const char *pPathID, CreateCallback_t pfnCreate, bool bForce, void *pExtraData )
{
if ( pTargetName )
{
// caller could supply source as PC or 360 name, we want the PC filename
char szFixedSourceName[MAX_PATH];
pSourceName = RestoreFilename( pSourceName, szFixedSourceName, sizeof( szFixedSourceName ) );
// caller wants us to provide 360 named version of source
CreatePlatformFilename( pSourceName, pTargetName, targetLen );
}
// no conversion are performed by the game at runtime anymore
// SMB access was removed by the XDK for Vista....
return UOC_NOT_CREATED;
}
//-----------------------------------------------------------------------------
// Returns the search path as a list of paths
//-----------------------------------------------------------------------------
void GetSearchPath( CUtlVector< CUtlString > &path, const char *pPathID )
{
int nMaxLen = g_pFullFileSystem->GetSearchPath( pPathID, false, NULL, 0 );
char *pBuf = (char*)stackalloc( nMaxLen );
g_pFullFileSystem->GetSearchPath( pPathID, false, pBuf, nMaxLen );
char *pSemi;
while ( NULL != ( pSemi = strchr( pBuf, ';' ) ) )
{
*pSemi = 0;
path.AddToTail( pBuf );
pBuf = pSemi + 1;
}
path.AddToTail( pBuf );
}
//-----------------------------------------------------------------------------
// Given file name in the current dir generate a full path to it.
//-----------------------------------------------------------------------------
bool GenerateFullPath( const char *pFileName, char const *pPathID, char *pBuf, int nBufLen )
{
if ( V_IsAbsolutePath( pFileName ) )
{
V_strncpy( pBuf, pFileName, nBufLen );
return true;
}
const char *pFullPath = g_pFullFileSystem->RelativePathToFullPath( pFileName, pPathID, pBuf, nBufLen );
if ( pFullPath && Q_IsAbsolutePath( pFullPath ) )
return true;
char pDir[ MAX_PATH ];
if ( !g_pFullFileSystem->GetCurrentDirectory( pDir, sizeof( pDir ) ) )
return false;
V_ComposeFileName( pDir, pFileName, pBuf, nBufLen );
V_RemoveDotSlashes( pBuf );
return true;
}
//-----------------------------------------------------------------------------
// Search start directory, recurse into sub directories collecting all files matching the target name.
//-----------------------------------------------------------------------------
void RecursiveFindFilesMatchingName( CUtlVector< CUtlString > *outFileList, const char* szStartDirectory, const char* szTargetFileName, const char *pathID )
{
char searchString[MAX_PATH];
Q_snprintf( searchString, sizeof( searchString ), "%s/*.*", szStartDirectory );
Q_FixSlashes( searchString );
FileFindHandle_t handle;
const char* curFile = g_pFullFileSystem->FindFirstEx( searchString, pathID, &handle );
while ( curFile )
{
if ( *curFile != '.' && g_pFullFileSystem->FindIsDirectory( handle ) )
{
char newSearchPath[MAX_PATH];
Q_snprintf( newSearchPath, sizeof( newSearchPath ), "%s/%s", szStartDirectory, curFile );
RecursiveFindFilesMatchingName( outFileList, newSearchPath, szTargetFileName, pathID );
}
else if ( V_StringMatchesPattern( curFile, szTargetFileName ) )
{
CUtlString outFile;
outFile.Format( "%s/%s", szStartDirectory, curFile );
Q_FixSlashes( outFile.Get() );
outFileList->AddToTail( outFile );
}
curFile = g_pFullFileSystem->FindNext( handle );
}
g_pFullFileSystem->FindClose( handle );
}
//-----------------------------------------------------------------------------
// Builds a list of all files under a directory with a particular extension
//-----------------------------------------------------------------------------
void AddFilesToList( CUtlVector< CUtlString > &list, const char *pDirectory, const char *pPathID, const char *pExtension )
{
char pSearchString[MAX_PATH];
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pDirectory );
bool bIsAbsolute = Q_IsAbsolutePath( pDirectory );
// get the list of files
FileFindHandle_t hFind;
const char *pFoundFile = g_pFullFileSystem->FindFirstEx( pSearchString, pPathID, &hFind );
// add all the items
CUtlVector< CUtlString > subDirs;
for ( ; pFoundFile; pFoundFile = g_pFullFileSystem->FindNext( hFind ) )
{
char pChildPath[MAX_PATH];
Q_snprintf( pChildPath, MAX_PATH, "%s\\%s", pDirectory, pFoundFile );
if ( g_pFullFileSystem->FindIsDirectory( hFind ) )
{
if ( Q_strnicmp( pFoundFile, ".", 2 ) && Q_strnicmp( pFoundFile, "..", 3 ) )
{
subDirs.AddToTail( pChildPath );
}
continue;
}
// Check the extension matches
if ( Q_stricmp( Q_GetFileExtension( pFoundFile ), pExtension ) )
continue;
char pFullPathBuf[MAX_PATH];
char *pFullPath = pFullPathBuf;
if ( !bIsAbsolute )
{
g_pFullFileSystem->RelativePathToFullPath( pChildPath, pPathID, pFullPathBuf, sizeof(pFullPathBuf) );
}
else
{
pFullPath = pChildPath;
}
V_strlower( pFullPath );
Q_FixSlashes( pFullPath );
list.AddToTail( pFullPath );
}
g_pFullFileSystem->FindClose( hFind );
int nCount = subDirs.Count();
for ( int i = 0; i < nCount; ++i )
{
AddFilesToList( list, subDirs[i], pPathID, pExtension );
}
}
void CBaseFile::ReadLines( CUtlStringList &lineList, int nMaxLineLength )
{
char *pLine = ( char * ) stackalloc( nMaxLineLength );
while( ReadLine( pLine, nMaxLineLength ) )
{
char *pEOL = strchr( pLine, '\n' ); // kill the \n
if ( pEOL )
*pEOL = 0;
lineList.CopyAndAddToTail( pLine );
}
}
void CBaseFile::ReadFile( CUtlBuffer &fileData )
{
int nFileSize = Size();
fileData.EnsureCapacity( Size() );
int nSize = Read( fileData.Base(), nFileSize );
fileData.SeekPut( CUtlBuffer::SEEK_HEAD, nSize );
}

59
tier2/interval.cpp Normal file
View File

@@ -0,0 +1,59 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "tier0/platform.h"
#include "tier2/interval.h"
#include "tier1/strtools.h"
#include "vstdlib/random.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pString -
// Output : interval_t
//-----------------------------------------------------------------------------
interval_t ReadInterval( const char *pString )
{
interval_t tmp;
tmp.start = 0;
tmp.range = 0;
char tempString[128];
Q_strncpy( tempString, pString, sizeof(tempString) );
char *token = strtok( tempString, "," );
if ( token )
{
tmp.start = atof( token );
token = strtok( NULL, "," );
if ( token )
{
tmp.range = atof( token ) - tmp.start;
}
}
return tmp;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &interval -
// Output : float
//-----------------------------------------------------------------------------
float RandomInterval( const interval_t &interval )
{
float out = interval.start;
if ( interval.range != 0 )
{
out += RandomFloat( 0, interval.range );
}
return out;
}

143
tier2/keybindings.cpp Normal file
View File

@@ -0,0 +1,143 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#include "tier2/keybindings.h"
#include "tier2/tier2.h"
#include "inputsystem/iinputsystem.h"
#include "tier1/utlbuffer.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Set a key binding
//-----------------------------------------------------------------------------
void CKeyBindings::SetBinding( ButtonCode_t code, const char *pBinding )
{
if ( code == BUTTON_CODE_INVALID || code == KEY_NONE )
return;
// free old bindings
if ( !m_KeyInfo[code].IsEmpty() )
{
// Exactly the same, don't re-bind and fragment memory
if ( !Q_stricmp( m_KeyInfo[code], pBinding ) )
return;
}
// allocate memory for new binding
m_KeyInfo[code] = pBinding;
}
void CKeyBindings::SetBinding( const char *pButtonName, const char *pBinding )
{
ButtonCode_t code = g_pInputSystem->StringToButtonCode( pButtonName );
SetBinding( code, pBinding );
}
void CKeyBindings::Unbind( ButtonCode_t code )
{
if ( code != KEY_NONE && code != BUTTON_CODE_INVALID )
{
m_KeyInfo[code] = "";
}
}
void CKeyBindings::Unbind( const char *pButtonName )
{
ButtonCode_t code = g_pInputSystem->StringToButtonCode( pButtonName );
Unbind( code );
}
void CKeyBindings::UnbindAll()
{
for ( int i = 0; i < BUTTON_CODE_LAST; i++ )
{
m_KeyInfo[i] = "";
}
}
//-----------------------------------------------------------------------------
// Count number of lines of bindings we'll be writing
//-----------------------------------------------------------------------------
int CKeyBindings::GetBindingCount( ) const
{
int nCount = 0;
for ( int i = 0; i < BUTTON_CODE_LAST; i++ )
{
if ( m_KeyInfo[i].Length() )
{
nCount++;
}
}
return nCount;
}
//-----------------------------------------------------------------------------
// Writes lines containing "bind key value"
//-----------------------------------------------------------------------------
void CKeyBindings::WriteBindings( CUtlBuffer &buf )
{
for ( int i = 0; i < BUTTON_CODE_LAST; i++ )
{
if ( m_KeyInfo[i].Length() )
{
const char *pButtonCode = g_pInputSystem->ButtonCodeToString( (ButtonCode_t)i );
buf.Printf( "bind \"%s\" \"%s\"\n", pButtonCode, m_KeyInfo[i].Get() );
}
}
}
//-----------------------------------------------------------------------------
// Returns the keyname to which a binding string is bound. E.g., if
// TAB is bound to +use then searching for +use will return "TAB"
//-----------------------------------------------------------------------------
const char *CKeyBindings::ButtonNameForBinding( const char *pBinding )
{
const char *pBind = pBinding;
if ( pBinding[0] == '+' )
{
++pBind;
}
for ( int i = 0; i < BUTTON_CODE_LAST; i++ )
{
if ( !m_KeyInfo[i].Length() )
continue;
if ( m_KeyInfo[i][0] == '+' )
{
if ( !Q_stricmp( &m_KeyInfo[i][1], pBind ) )
return g_pInputSystem->ButtonCodeToString( (ButtonCode_t)i );
}
else
{
if ( !Q_stricmp( m_KeyInfo[i], pBind ) )
return g_pInputSystem->ButtonCodeToString( (ButtonCode_t)i );
}
}
return NULL;
}
const char *CKeyBindings::GetBindingForButton( ButtonCode_t code )
{
if ( m_KeyInfo[code].IsEmpty() )
return NULL;
return m_KeyInfo[ code ];
}

141
tier2/meshutils.cpp Normal file
View File

@@ -0,0 +1,141 @@
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A set of utilities to render standard shapes
//
//===========================================================================//
#include "tier2/meshutils.h"
#include "tier0/platform.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Helper methods to create various standard index buffer types
//-----------------------------------------------------------------------------
void GenerateSequentialIndexBuffer( unsigned short* pIndices, int nIndexCount, int nFirstVertex )
{
if ( !pIndices )
return;
// Format the sequential buffer
for ( int i = 0; i < nIndexCount; ++i )
{
pIndices[i] = (unsigned short)( i + nFirstVertex );
}
}
void GenerateQuadIndexBuffer( unsigned short *pIndices, int nIndexCount, int nFirstVertex )
{
if ( !pIndices )
return;
// Format the quad buffer
int i;
int numQuads = nIndexCount / 6;
unsigned short baseVertex = (unsigned short)nFirstVertex;
if ( ( (size_t)pIndices & 0x3 ) == 0 )
{
// Fast version, requires aligned indices
int *pWrite = (int*)pIndices;
int nWrite = ( baseVertex << 16 ) | baseVertex;
for ( i = 0; i < numQuads; ++i )
{
// Have to deal with endian-ness
if ( IsX360() || IsPS3() )
{
// this avoids compiler write reodering and prevents the write-combined out-of-order penalty
// _WriteBarrier won't compile here, and volatile is ignored
// the compiler otherwise scrambles these writes
*pWrite++ = nWrite + 1;
*pWrite++ = nWrite + ( 2 << 16 );
*pWrite++ = nWrite + ( 2 << 16 ) + 3;
}
else
{
pWrite[0] = nWrite + ( 1 << 16 );
pWrite[1] = nWrite + 2;
pWrite[2] = nWrite + ( 3 << 16 ) + 2;
pWrite += 3;
}
nWrite += ( 4 << 16 ) | 4;
}
}
else
{
for ( i = 0; i < numQuads; ++i )
{
pIndices[0] = baseVertex;
pIndices[1] = baseVertex + 1;
pIndices[2] = baseVertex + 2;
// Triangle 2
pIndices[3] = baseVertex;
pIndices[4] = baseVertex + 2;
pIndices[5] = baseVertex + 3;
baseVertex += 4;
pIndices += 6;
}
}
}
void GeneratePolygonIndexBuffer( unsigned short* pIndices, int nIndexCount, int nFirstVertex )
{
if ( !pIndices )
return;
int i, baseVertex;
int numPolygons = nIndexCount / 3;
baseVertex = nFirstVertex;
for ( i = 0; i < numPolygons; ++i)
{
// Triangle 1
pIndices[0] = (unsigned short)( nFirstVertex );
pIndices[1] = (unsigned short)( nFirstVertex + i + 1 );
pIndices[2] = (unsigned short)( nFirstVertex + i + 2 );
pIndices += 3;
}
}
void GenerateLineStripIndexBuffer( unsigned short* pIndices, int nIndexCount, int nFirstVertex )
{
if ( !pIndices )
return;
int i, baseVertex;
int numLines = nIndexCount / 2;
baseVertex = nFirstVertex;
for ( i = 0; i < numLines; ++i)
{
pIndices[0] = (unsigned short)( nFirstVertex + i );
pIndices[1] = (unsigned short)( nFirstVertex + i + 1 );
pIndices += 2;
}
}
void GenerateLineLoopIndexBuffer( unsigned short* pIndices, int nIndexCount, int nFirstVertex )
{
if ( !pIndices )
{
return;
}
int i, baseVertex;
int numLines = nIndexCount / 2;
baseVertex = nFirstVertex;
pIndices[0] = (unsigned short)( nFirstVertex + numLines - 1 );
pIndices[1] = (unsigned short)( nFirstVertex );
pIndices += 2;
for ( i = 1; i < numLines; ++i)
{
pIndices[0] = (unsigned short)( nFirstVertex + i - 1 );
pIndices[1] = (unsigned short)( nFirstVertex + i );
pIndices += 2;
}
}

126
tier2/p4helpers.cpp Normal file
View File

@@ -0,0 +1,126 @@
//====== Copyright c 1996-2007, Valve Corporation, All rights reserved. =======//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "p4helpers.h"
#include "tier2/tier2.h"
#include "p4lib/ip4.h"
#ifdef PLATFORM_WINDOWS_PC
#include <Windows.h>
#endif // PLATFORM_WINDOWS_PC
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//////////////////////////////////////////////////////////////////////////
//
// CP4File implementation
//
//////////////////////////////////////////////////////////////////////////
CP4File::CP4File( char const *szFilename )
{
#ifdef PLATFORM_WINDOWS_PC
// On windows, get the pathname of the file on disk first before using that as a perforce path
// this avoids invalid Adds(). Have to go through GetShortPathName and then GetLongPathName from
// the short path name
TCHAR szShortPathName[ MAX_PATH ] = TEXT( "" );
const DWORD shortRetVal = GetShortPathName( szFilename, szShortPathName, ARRAYSIZE( szShortPathName ) );
if ( shortRetVal > 0 && shortRetVal <= ARRAYSIZE( szShortPathName ) )
{
TCHAR szLongPathName[ MAX_PATH ] = TEXT( "" );
const DWORD longRetVal = GetLongPathName( szShortPathName, szLongPathName, ARRAYSIZE( szLongPathName ) );
if ( longRetVal > 0 && longRetVal <= ARRAYSIZE( szLongPathName ) )
{
m_sFilename = szLongPathName;
return;
}
}
#endif // PLATFORM_WINDOWS_PC
m_sFilename = szFilename;
}
CP4File::~CP4File()
{
}
bool CP4File::Edit( void )
{
if ( !p4 )
return true;
return p4->OpenFileForEdit( m_sFilename.String() );
}
bool CP4File::Add( void )
{
if ( !p4 )
return true;
return p4->OpenFileForAdd( m_sFilename.String() );
}
// Is the file in perforce?
bool CP4File::IsFileInPerforce()
{
if ( !p4 )
return false;
return p4->IsFileInPerforce( m_sFilename.String() );
}
//////////////////////////////////////////////////////////////////////////
//
// CP4Factory implementation
//
//////////////////////////////////////////////////////////////////////////
CP4Factory::CP4Factory()
{
}
CP4Factory::~CP4Factory()
{
}
bool CP4Factory::SetDummyMode( bool bDummyMode )
{
bool bOld = m_bDummyMode;
m_bDummyMode = bDummyMode;
return bOld;
}
void CP4Factory::SetOpenFileChangeList( const char *szChangeListName )
{
if ( !m_bDummyMode && p4 )
p4->SetOpenFileChangeList( szChangeListName );
}
CP4File *CP4Factory::AccessFile( char const *szFilename ) const
{
if ( !m_bDummyMode )
return new CP4File( szFilename );
else
return new CP4File_Dummy( szFilename );
}
// Default p4 factory
static CP4Factory s_static_p4_factory;
CP4Factory *g_p4factory = &s_static_p4_factory; // NULL before the factory constructs

1166
tier2/renderutils.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A higher level link library for general use in the game and tools.
//
//===========================================================================//
#include <tier2/tier2.h>
#include "resourceprecacher.h"
#include "datacache/iprecachesystem.h"
CBaseResourcePrecacher *CBaseResourcePrecacher::sm_pFirst[PRECACHE_SYSTEM_COUNT] = { 0 };
//-----------------------------------------------------------------------------
// Registers all resource precachers (created by PRECACHE_ macros) with precache system
//-----------------------------------------------------------------------------
void CBaseResourcePrecacher::RegisterAll()
{
for ( int iSystem = 0; iSystem < PRECACHE_SYSTEM_COUNT; iSystem++ )
{
g_pPrecacheSystem->Register( sm_pFirst[iSystem], (PrecacheSystem_t) iSystem );
}
}

508
tier2/riff.cpp Normal file
View File

@@ -0,0 +1,508 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// Avoid these warnings:
#pragma warning(disable : 4512) // warning C4512: 'InFileRIFF' : assignment operator could not be generated
#pragma warning(disable : 4514) // warning C4514: 'RIFFName' : unreferenced inline function has been removed
#include "riff.h"
#include <stdio.h>
#include <string.h>
#include "tier0/dbg.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#if 0
//-----------------------------------------------------------------------------
// Purpose: Test code that implements the interface on stdio
//-----------------------------------------------------------------------------
class StdIOReadBinary : public IFileReadBinary
{
public:
int open( const char *pFileName )
{
return (int)fopen( pFileName, "rb" );
}
int read( void *pOutput, int size, int file )
{
FILE *fp = (FILE *)file;
return fread( pOutput, size, 1, fp );
}
void seek( int file, int pos )
{
fseek( (FILE *)file, pos, SEEK_SET );
}
unsigned int tell( int file )
{
return ftell( (FILE *)file );
}
unsigned int size( int file )
{
FILE *fp = (FILE *)file;
if ( !fp )
return 0;
unsigned int pos = ftell( fp );
fseek( fp, 0, SEEK_END );
unsigned int size = ftell( fp );
fseek( fp, pos, SEEK_SET );
return size;
}
void close( int file )
{
FILE *fp = (FILE *)file;
fclose( fp );
}
};
#endif
#define RIFF_ID MAKEID('R','I','F','F')
//-----------------------------------------------------------------------------
// Purpose: Opens a RIFF file using the given I/O mechanism
// Input : *pFileName
// &io - I/O interface
//-----------------------------------------------------------------------------
InFileRIFF::InFileRIFF( const char *pFileName, IFileReadBinary &io ) : m_io(io)
{
m_file = m_io.open( pFileName );
int riff = 0;
if ( !m_file )
{
m_riffSize = 0;
m_riffName = 0;
m_nFileSize = 0;
return;
}
m_nFileSize = m_io.size( m_file );
riff = ReadInt();
if ( riff != RIFF_ID )
{
printf( "Not a RIFF File [%s]\n", pFileName );
m_riffSize = 0;
}
else
{
// we store size as size of all chunks
// subtract off the RIFF form type (e.g. 'WAVE', 4 bytes)
m_riffSize = ReadInt() - 4;
m_riffName = ReadInt();
// HACKHACK: LWV files don't obey the RIFF format!!!
// Do this or miss the linguistic chunks at the end. Lame!
// subtract off 12 bytes for (RIFF, size, WAVE)
m_riffSize = m_nFileSize - 12;
}
}
//-----------------------------------------------------------------------------
// Purpose: Close the file
//-----------------------------------------------------------------------------
InFileRIFF::~InFileRIFF( void )
{
m_io.close( m_file );
}
//-----------------------------------------------------------------------------
// Purpose: read a 4-byte int out of the stream
// Output : int = read value, default is zero
//-----------------------------------------------------------------------------
int InFileRIFF::ReadInt( void )
{
int tmp = 0;
m_io.read( &tmp, sizeof(int), m_file );
tmp = LittleLong( tmp );
return tmp;
}
//-----------------------------------------------------------------------------
// Purpose: Read a block of binary data
// Input : *pOutput - pointer to destination memory
// dataSize - size of block to read
// Output : int - number of bytes read
//-----------------------------------------------------------------------------
int InFileRIFF::ReadData( void *pOutput, int dataSize )
{
int count = m_io.read( pOutput, dataSize, m_file );
return count;
}
//-----------------------------------------------------------------------------
// Purpose: Gets the file position
// Output : int (bytes from start of file)
//-----------------------------------------------------------------------------
int InFileRIFF::PositionGet( void )
{
return m_io.tell( m_file );
}
//-----------------------------------------------------------------------------
// Purpose: Seek to file position
// Input : position - bytes from start of file
//-----------------------------------------------------------------------------
void InFileRIFF::PositionSet( int position )
{
m_io.seek( m_file, position );
}
//-----------------------------------------------------------------------------
// Purpose: Used to write a RIFF format file
//-----------------------------------------------------------------------------
OutFileRIFF::OutFileRIFF( const char *pFileName, IFileWriteBinary &io ) : m_io( io )
{
m_file = m_io.create( pFileName );
if ( !m_file )
return;
int riff = RIFF_ID;
m_io.write( &riff, 4, m_file );
m_riffSize = 0;
m_nNamePos = m_io.tell( m_file );
// Save room for the size and name now
WriteInt( 0 );
// Write out the name
WriteInt( RIFF_WAVE );
m_bUseIncorrectLISETLength = false;
m_nLISETSize = 0;
}
OutFileRIFF::~OutFileRIFF( void )
{
if ( !IsValid() )
return;
unsigned int size = m_io.tell( m_file ) -8;
m_io.seek( m_file, m_nNamePos );
if ( m_bUseIncorrectLISETLength )
{
size = m_nLISETSize - 8;
}
WriteInt( size );
m_io.close( m_file );
}
void OutFileRIFF::HasLISETData( int position )
{
m_bUseIncorrectLISETLength = true;
m_nLISETSize = position;
}
bool OutFileRIFF::WriteInt( int number )
{
if ( !IsValid() )
return false;
m_io.write( &number, sizeof( int ), m_file );
return true;
}
bool OutFileRIFF::WriteData( void *pOutput, int dataSize )
{
if ( !IsValid() )
return false;
m_io.write( pOutput, dataSize, m_file );
return true;
}
int OutFileRIFF::PositionGet( void )
{
if ( !IsValid() )
return 0;
return m_io.tell( m_file );
}
void OutFileRIFF::PositionSet( int position )
{
if ( !IsValid() )
return;
m_io.seek( m_file, position );
}
//-----------------------------------------------------------------------------
// Purpose: Create an iterator for the given file
// Input : &riff - riff file
// size - size of file or sub-chunk
//-----------------------------------------------------------------------------
IterateRIFF::IterateRIFF( InFileRIFF &riff, int size )
: m_riff(riff), m_size(size)
{
if ( !m_riff.RIFFSize() )
{
// bad file, just be an empty iterator
ChunkClear();
return;
}
// get the position and parse a chunk
m_start = riff.PositionGet();
ChunkSetup();
}
//-----------------------------------------------------------------------------
// Purpose: Set up a sub-chunk iterator
// Input : &parent - parent iterator
//-----------------------------------------------------------------------------
IterateRIFF::IterateRIFF( IterateRIFF &parent )
: m_riff(parent.m_riff), m_size(parent.ChunkSize())
{
m_start = parent.ChunkFilePosition();
ChunkSetup();
}
//-----------------------------------------------------------------------------
// Purpose: Parse the chunk at the current file position
// This object will iterate over the sub-chunks of this chunk.
// This makes for easy hierarchical parsing
//-----------------------------------------------------------------------------
void IterateRIFF::ChunkSetup( void )
{
m_chunkPosition = m_riff.PositionGet();
m_chunkName = m_riff.ReadInt();
m_chunkSize = m_riff.ReadInt();
}
//-----------------------------------------------------------------------------
// Purpose: clear chunk setup, ChunkAvailable will return false
//-----------------------------------------------------------------------------
void IterateRIFF::ChunkClear( void )
{
m_chunkSize = -1;
}
//-----------------------------------------------------------------------------
// Purpose: If there are chunks left to read beyond this one, return true
//-----------------------------------------------------------------------------
bool IterateRIFF::ChunkAvailable( void )
{
if ( m_chunkSize != -1 && m_chunkSize < 0x10000000 )
return true;
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Go to the next chunk in the file, return true if there is one.
//-----------------------------------------------------------------------------
bool IterateRIFF::ChunkNext( void )
{
if ( !ChunkAvailable() )
return false;
int nextPos = m_chunkPosition + 8 + m_chunkSize;
// chunks are aligned
nextPos += m_chunkSize & 1;
if ( nextPos >= (m_start + m_size) )
{
ChunkClear();
return false;
}
m_riff.PositionSet( nextPos );
ChunkSetup();
return ChunkAvailable();
}
//-----------------------------------------------------------------------------
// Purpose: get the chunk FOURCC as an int
// Output : unsigned int
//-----------------------------------------------------------------------------
unsigned int IterateRIFF::ChunkName( void )
{
return m_chunkName;
}
//-----------------------------------------------------------------------------
// Purpose: get the size of this chunk
// Output : unsigned int
//-----------------------------------------------------------------------------
unsigned int IterateRIFF::ChunkSize( void )
{
return m_chunkSize;
}
//-----------------------------------------------------------------------------
// Purpose: Read the entire chunk into a buffer
// Input : *pOutput - dest buffer
// Output : int bytes read
//-----------------------------------------------------------------------------
int IterateRIFF::ChunkRead( void *pOutput )
{
return m_riff.ReadData( pOutput, ChunkSize() );
}
//-----------------------------------------------------------------------------
// Purpose: Read a partial chunk (updates file position for subsequent partial reads).
// Input : *pOutput - dest buffer
// dataSize - partial size
// Output : int - bytes read
//-----------------------------------------------------------------------------
int IterateRIFF::ChunkReadPartial( void *pOutput, int dataSize )
{
return m_riff.ReadData( pOutput, dataSize );
}
//-----------------------------------------------------------------------------
// Purpose: Read a 4-byte int
// Output : int - read int
//-----------------------------------------------------------------------------
int IterateRIFF::ChunkReadInt( void )
{
return m_riff.ReadInt();
}
//-----------------------------------------------------------------------------
// Purpose: Used to iterate over an InFileRIFF
//-----------------------------------------------------------------------------
IterateOutputRIFF::IterateOutputRIFF( OutFileRIFF &riff )
: m_riff( riff )
{
if ( !m_riff.IsValid() )
return;
m_start = m_riff.PositionGet();
m_chunkPosition = m_start;
m_chunkStart = -1;
}
IterateOutputRIFF::IterateOutputRIFF( IterateOutputRIFF &parent )
: m_riff(parent.m_riff)
{
m_start = parent.ChunkFilePosition();
m_chunkPosition = m_start;
m_chunkStart = -1;
}
void IterateOutputRIFF::ChunkWrite( unsigned int chunkname, void *pOutput, int size )
{
m_chunkPosition = m_riff.PositionGet();
m_chunkName = chunkname;
m_chunkSize = size;
m_riff.WriteInt( chunkname );
m_riff.WriteInt( size );
m_riff.WriteData( pOutput, size );
m_chunkPosition = m_riff.PositionGet();
m_chunkPosition += m_chunkPosition & 1;
m_riff.PositionSet( m_chunkPosition );
m_chunkStart = -1;
}
void IterateOutputRIFF::ChunkWriteInt( int number )
{
m_riff.WriteInt( number );
}
void IterateOutputRIFF::ChunkWriteData( void *pOutput, int size )
{
m_riff.WriteData( pOutput, size );
}
void IterateOutputRIFF::ChunkFinish( void )
{
Assert( m_chunkStart != -1 );
m_chunkPosition = m_riff.PositionGet();
int size = m_chunkPosition - m_chunkStart - 8;
m_chunkPosition += m_chunkPosition & 1;
m_riff.PositionSet( m_chunkStart + sizeof( int ) );
m_riff.WriteInt( size );
m_riff.PositionSet( m_chunkPosition );
m_chunkStart = -1;
}
void IterateOutputRIFF::ChunkStart( unsigned int chunkname )
{
Assert( m_chunkStart == -1 );
m_chunkStart = m_riff.PositionGet();
m_riff.WriteInt( chunkname );
m_riff.WriteInt( 0 );
}
void IterateOutputRIFF::ChunkSetPosition( int position )
{
m_riff.PositionSet( position );
}
unsigned int IterateOutputRIFF::ChunkGetPosition( void )
{
return m_riff.PositionGet();
}
void IterateOutputRIFF::CopyChunkData( IterateRIFF& input )
{
if ( input.ChunkSize() > 0 )
{
char *buffer = new char[ input.ChunkSize() ];
Assert( buffer );
input.ChunkRead( buffer );
// Don't copy/write the name or size, just the data itself
ChunkWriteData( buffer, input.ChunkSize() );
delete[] buffer;
}
}
void IterateOutputRIFF::SetLISETData( int position )
{
m_riff.HasLISETData( position );
}

View File

@@ -0,0 +1,34 @@
//===== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#include "tier2/tier2.h"
#include "resourcefile/schema.h"
#include "resourcesystem/iresourcesystem.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
CSchemaClassBindingBase *CSchemaClassBindingBase::sm_pClassBindingList;
void CSchemaClassBindingBase::Install()
{
for ( CSchemaClassBindingBase *pBinding = sm_pClassBindingList; pBinding; pBinding = pBinding->m_pNextBinding )
{
g_pResourceSystem->InstallSchemaClassBinding( pBinding );
}
}
const CResourceStructIntrospection *CSchemaClassBindingBase::GetIntrospection() const
{
if ( m_pIntrospection == NULL )
{
m_pIntrospection = g_pResourceSystem->FindStructIntrospection( m_pClassName );
}
return m_pIntrospection;
}

466
tier2/socketcreator.cpp Normal file
View File

@@ -0,0 +1,466 @@
//====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Utility class to help in socket creation. Works for clients + servers
//
//===========================================================================//
#include "tier0/platform.h"
#if defined(_WIN32)
#if !defined(_X360)
#include <winsock.h>
#endif
#undef SetPort // winsock screws with the SetPort string... *sigh*
#define socklen_t int
#define MSG_NOSIGNAL 0
#elif defined(PLATFORM_POSIX)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <errno.h>
#ifdef OSX
#define MSG_NOSIGNAL 0
#endif
#ifdef _PS3
// NOTE: this socket creator doesn't work on PS3
// here's a compile-hack:
#define EWOULDBLOCK EAGAIN
#else
#include <sys/ioctl.h>
#endif
#define closesocket close
#define WSAGetLastError() errno
#define ioctlsocket ioctl
#endif
#include <tier0/dbg.h>
#include "socketcreator.h"
//#include "server.h"
#if defined( _X360 )
#include "xbox/xbox_win32stubs.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
/*
====================
NET_ErrorString
====================
*/
const char *NET_ErrorString (int code)
{
#if defined( _WIN32 )
switch (code)
{
case WSAEINTR: return "WSAEINTR";
case WSAEBADF: return "WSAEBADF";
case WSAEACCES: return "WSAEACCES";
case WSAEDISCON: return "WSAEDISCON";
case WSAEFAULT: return "WSAEFAULT";
case WSAEINVAL: return "WSAEINVAL";
case WSAEMFILE: return "WSAEMFILE";
case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK";
case WSAEINPROGRESS: return "WSAEINPROGRESS";
case WSAEALREADY: return "WSAEALREADY";
case WSAENOTSOCK: return "WSAENOTSOCK";
case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ";
case WSAEMSGSIZE: return "WSAEMSGSIZE";
case WSAEPROTOTYPE: return "WSAEPROTOTYPE";
case WSAENOPROTOOPT: return "WSAENOPROTOOPT";
case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT";
case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT";
case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP";
case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT";
case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT";
case WSAEADDRINUSE: return "WSAEADDRINUSE";
case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL";
case WSAENETDOWN: return "WSAENETDOWN";
case WSAENETUNREACH: return "WSAENETUNREACH";
case WSAENETRESET: return "WSAENETRESET";
case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR";
case WSAECONNRESET: return "WSAECONNRESET";
case WSAENOBUFS: return "WSAENOBUFS";
case WSAEISCONN: return "WSAEISCONN";
case WSAENOTCONN: return "WSAENOTCONN";
case WSAESHUTDOWN: return "WSAESHUTDOWN";
case WSAETOOMANYREFS: return "WSAETOOMANYREFS";
case WSAETIMEDOUT: return "WSAETIMEDOUT";
case WSAECONNREFUSED: return "WSAECONNREFUSED";
case WSAELOOP: return "WSAELOOP";
case WSAENAMETOOLONG: return "WSAENAMETOOLONG";
case WSAEHOSTDOWN: return "WSAEHOSTDOWN";
case WSASYSNOTREADY: return "WSASYSNOTREADY";
case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED";
case WSANOTINITIALISED: return "WSANOTINITIALISED";
case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND";
case WSATRY_AGAIN: return "WSATRY_AGAIN";
case WSANO_RECOVERY: return "WSANO_RECOVERY";
case WSANO_DATA: return "WSANO_DATA";
default: return "UNKNOWN ERROR";
}
#else
return strerror( code );
#endif
}
bool SocketWouldBlock()
{
#ifdef _WIN32
return (WSAGetLastError() == WSAEWOULDBLOCK);
#elif defined(POSIX)
return (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS);
#else
Assert( false ); // Not implemented for this platform
return false;
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CSocketCreator::CSocketCreator( ISocketCreatorListener *pListener )
{
m_hListenSocket = -1;
m_pListener = pListener;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CSocketCreator::~CSocketCreator()
{
Disconnect();
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the listening socket is created and listening
//-----------------------------------------------------------------------------
bool CSocketCreator::IsListening() const
{
return m_hListenSocket != -1;
}
//-----------------------------------------------------------------------------
// Purpose: Bind to a TCP port and accept incoming connections
//-----------------------------------------------------------------------------
bool CSocketCreator::CreateListenSocket( const netadr_t &netAdr, bool bListenOnAllInterfaces )
{
CloseListenSocket();
#if PLATFORM_PS3
Assert( 0 );
return false;
#else
m_ListenAddress = netAdr;
m_hListenSocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( m_hListenSocket == -1 )
{
Warning( "Socket unable to create socket (%s)\n", NET_ErrorString( WSAGetLastError() ) );
return false;
}
if ( !ConfigureSocket( m_hListenSocket ) )
{
CloseListenSocket();
return false;
}
struct sockaddr_in s;
m_ListenAddress.ToSockadr( (struct sockaddr *)&s );
if ( bListenOnAllInterfaces )
s.sin_addr.s_addr = INADDR_ANY;
int ret = bind( m_hListenSocket, (struct sockaddr *)&s, sizeof(struct sockaddr_in) );
if ( ret == -1 )
{
Warning( "Socket bind failed (%s)\n", NET_ErrorString( WSAGetLastError() ) );
CloseListenSocket();
return false;
}
ret = listen( m_hListenSocket, SOCKET_TCP_MAX_ACCEPTS );
if ( ret == -1 )
{
Warning( "Socket listen failed (%s)\n", NET_ErrorString( WSAGetLastError() ) );
CloseListenSocket();
return false;
}
return true;
#endif
}
//-----------------------------------------------------------------------------
// Configures a socket for use
//-----------------------------------------------------------------------------
bool CSocketCreator::ConfigureSocket( int sock )
{
#if PLATFORM_PS3
Assert( 0 );
return false;
#else
// disable NAGLE (rcon cmds are small in size)
int nodelay = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&nodelay, sizeof(nodelay));
nodelay = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&nodelay, sizeof(nodelay));
int opt = 1, ret;
ret = ioctlsocket( sock, FIONBIO, (unsigned long*)&opt ); // non-blocking
if ( ret == -1 )
{
Warning( "Socket accept ioctl(FIONBIO) failed (%i)\n", WSAGetLastError() );
return false;
}
return true;
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Handle a new connection
//-----------------------------------------------------------------------------
void CSocketCreator::ProcessAccept()
{
#if PLATFORM_PS3
Assert( 0 );
return;
#else
int newSocket;
sockaddr sa;
int nLengthAddr = sizeof(sa);
newSocket = accept( m_hListenSocket, &sa, (socklen_t *)&nLengthAddr );
if ( newSocket == -1 )
{
if ( !SocketWouldBlock()
#ifdef POSIX
&& errno != EINTR
#endif
)
{
Warning ("Socket ProcessAccept Error: %s\n", NET_ErrorString( WSAGetLastError() ) );
}
return;
}
if ( !ConfigureSocket( newSocket ) )
{
closesocket( newSocket );
return;
}
netadr_t adr;
adr.SetFromSockadr( &sa );
if ( m_pListener && !m_pListener->ShouldAcceptSocket( newSocket, adr ) )
{
closesocket( newSocket );
return;
}
// new connection TCP request, put in accepted queue
int nIndex = m_hAcceptedSockets.AddToTail();
AcceptedSocket_t *pNewEntry = &m_hAcceptedSockets[nIndex];
pNewEntry->m_hSocket = newSocket;
pNewEntry->m_Address = adr;
pNewEntry->m_pData = NULL;
void* pData = NULL;
if ( m_pListener )
{
m_pListener->OnSocketAccepted( newSocket, adr, &pData );
}
pNewEntry->m_pData = pData;
#endif
}
//-----------------------------------------------------------------------------
// Purpose: connect to the remote server
//-----------------------------------------------------------------------------
int CSocketCreator::ConnectSocket( const netadr_t &netAdr, bool bSingleSocket )
{
#if PLATFORM_PS3
Assert( 0 );
return -1;
#else
if ( bSingleSocket )
{
CloseAllAcceptedSockets();
}
SocketHandle_t hSocket = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( hSocket == -1 )
{
Warning( "Unable to create socket (%s)\n", NET_ErrorString( WSAGetLastError() ) );
return -1;
}
int opt = 1, ret;
ret = ioctlsocket( hSocket, FIONBIO, (unsigned long*)&opt ); // non-blocking
if ( ret == -1 )
{
Warning( "Socket ioctl(FIONBIO) failed (%s)\n", NET_ErrorString( WSAGetLastError() ) );
closesocket( hSocket );
return -1;
}
// disable NAGLE (rcon cmds are small in size)
int nodelay = 1;
setsockopt( hSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&nodelay, sizeof(nodelay) );
struct sockaddr_in s;
netAdr.ToSockadr( (struct sockaddr *)&s );
ret = connect( hSocket, (struct sockaddr *)&s, sizeof(s));
if ( ret == -1 )
{
if ( !SocketWouldBlock() )
{
Warning( "Socket connection failed (%s)\n", NET_ErrorString( WSAGetLastError() ) );
closesocket( hSocket );
return -1;
}
fd_set writefds;
struct timeval tv;
tv.tv_usec = 0;
tv.tv_sec = 1;
FD_ZERO( &writefds );
FD_SET( static_cast<u_int>( hSocket ), &writefds );
if ( select ( hSocket + 1, NULL, &writefds, NULL, &tv ) < 1 ) // block for at most 1 second
{
closesocket( hSocket ); // took too long to connect to, give up
return -1;
}
}
if ( m_pListener && !m_pListener->ShouldAcceptSocket( hSocket, netAdr ) )
{
closesocket( hSocket );
return -1;
}
// new connection TCP request, put in accepted queue
void *pData = NULL;
int nIndex = m_hAcceptedSockets.AddToTail();
AcceptedSocket_t *pNewEntry = &m_hAcceptedSockets[nIndex];
pNewEntry->m_hSocket = hSocket;
pNewEntry->m_Address = netAdr;
pNewEntry->m_pData = NULL;
if ( m_pListener )
{
m_pListener->OnSocketAccepted( hSocket, netAdr, &pData );
}
pNewEntry->m_pData = pData;
return nIndex;
#endif
}
//-----------------------------------------------------------------------------
// Purpose: close an open rcon connection
//-----------------------------------------------------------------------------
void CSocketCreator::CloseListenSocket()
{
#if PLATFORM_PS3
Assert( 0 );
return;
#else
if ( m_hListenSocket != -1 )
{
closesocket( m_hListenSocket );
m_hListenSocket = -1;
}
#endif
}
void CSocketCreator::CloseAcceptedSocket( int nIndex )
{
#if PLATFORM_PS3
Assert( 0 );
return;
#else
if ( nIndex >= m_hAcceptedSockets.Count() )
return;
AcceptedSocket_t& connected = m_hAcceptedSockets[nIndex];
if ( m_pListener )
{
m_pListener->OnSocketClosed( connected.m_hSocket, connected.m_Address, connected.m_pData );
}
closesocket( connected.m_hSocket );
m_hAcceptedSockets.Remove( nIndex );
#endif
}
void CSocketCreator::CloseAllAcceptedSockets()
{
#if PLATFORM_PS3
Warning( "CSocketCreator::CloseAllAcceptedSockets is UNIMPLEMENTED.\n" );
return;
#else
int nCount = m_hAcceptedSockets.Count();
for ( int i = 0; i < nCount; ++i )
{
AcceptedSocket_t& connected = m_hAcceptedSockets[i];
if ( m_pListener )
{
m_pListener->OnSocketClosed( connected.m_hSocket, connected.m_Address, connected.m_pData );
}
closesocket( connected.m_hSocket );
}
m_hAcceptedSockets.RemoveAll();
#endif
}
void CSocketCreator::Disconnect()
{
CloseListenSocket();
CloseAllAcceptedSockets();
}
//-----------------------------------------------------------------------------
// Purpose: accept new connections and walk open sockets and handle any incoming data
//-----------------------------------------------------------------------------
void CSocketCreator::RunFrame()
{
if ( IsListening() )
{
ProcessAccept(); // handle any new connection requests
}
}
//-----------------------------------------------------------------------------
// Returns socket info
//-----------------------------------------------------------------------------
int CSocketCreator::GetAcceptedSocketCount() const
{
return m_hAcceptedSockets.Count();
}
SocketHandle_t CSocketCreator::GetAcceptedSocketHandle( int nIndex ) const
{
return m_hAcceptedSockets[nIndex].m_hSocket;
}
const netadr_t& CSocketCreator::GetAcceptedSocketAddress( int nIndex ) const
{
return m_hAcceptedSockets[nIndex].m_Address;
}
void* CSocketCreator::GetAcceptedSocketData( int nIndex )
{
return m_hAcceptedSockets[nIndex].m_pData;
}

241
tier2/soundutils.cpp Normal file
View File

@@ -0,0 +1,241 @@
//===== Copyright 2005-2009, Valve Corporation, All rights reserved. ======//
//
// Purpose: Helper methods + classes for sound
//
//===========================================================================//
#include "tier2/soundutils.h"
#include "tier2/riff.h"
#include "tier2/tier2.h"
#include "filesystem.h"
#ifdef IS_WINDOWS_PC
#include <windows.h> // WAVEFORMATEX, WAVEFORMAT and ADPCM WAVEFORMAT!!!
#include <mmreg.h>
#else
#ifdef _X360
#include "xbox/xbox_win32stubs.h" // WAVEFORMATEX, WAVEFORMAT and ADPCM WAVEFORMAT!!!
#endif
#endif
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// RIFF reader/writers that use the file system
//-----------------------------------------------------------------------------
class CFSIOReadBinary : public IFileReadBinary
{
public:
// inherited from IFileReadBinary
virtual FileHandle_t open( const char *pFileName );
virtual int read( void *pOutput, int size, FileHandle_t file );
virtual void seek( FileHandle_t file, int pos );
virtual unsigned int tell( FileHandle_t file );
virtual unsigned int size( FileHandle_t file );
virtual void close( FileHandle_t file );
};
class CFSIOWriteBinary : public IFileWriteBinary
{
public:
virtual FileHandle_t create( const char *pFileName );
virtual int write( void *pData, int size, FileHandle_t file );
virtual void close( FileHandle_t file );
virtual void seek( FileHandle_t file, int pos );
virtual unsigned int tell( FileHandle_t file );
};
//-----------------------------------------------------------------------------
// Singletons
//-----------------------------------------------------------------------------
static CFSIOReadBinary s_FSIoIn;
static CFSIOWriteBinary s_FSIoOut;
IFileReadBinary *g_pFSIOReadBinary = &s_FSIoIn;
IFileWriteBinary *g_pFSIOWriteBinary = &s_FSIoOut;
//-----------------------------------------------------------------------------
// RIFF reader that use the file system
//-----------------------------------------------------------------------------
FileHandle_t CFSIOReadBinary::open( const char *pFileName )
{
return g_pFullFileSystem->Open( pFileName, "rb" );
}
int CFSIOReadBinary::read( void *pOutput, int size, FileHandle_t file )
{
if ( !file )
return 0;
return g_pFullFileSystem->Read( pOutput, size, file );
}
void CFSIOReadBinary::seek( FileHandle_t file, int pos )
{
if ( !file )
return;
g_pFullFileSystem->Seek( file, pos, FILESYSTEM_SEEK_HEAD );
}
unsigned int CFSIOReadBinary::tell( FileHandle_t file )
{
if ( !file )
return 0;
return g_pFullFileSystem->Tell( file );
}
unsigned int CFSIOReadBinary::size( FileHandle_t file )
{
if ( !file )
return 0;
return g_pFullFileSystem->Size( file );
}
void CFSIOReadBinary::close( FileHandle_t file )
{
if ( !file )
return;
g_pFullFileSystem->Close( file );
}
//-----------------------------------------------------------------------------
// RIFF writer that use the file system
//-----------------------------------------------------------------------------
FileHandle_t CFSIOWriteBinary::create( const char *pFileName )
{
g_pFullFileSystem->SetFileWritable( pFileName, true );
return g_pFullFileSystem->Open( pFileName, "wb" );
}
int CFSIOWriteBinary::write( void *pData, int size, FileHandle_t file )
{
return g_pFullFileSystem->Write( pData, size, file );
}
void CFSIOWriteBinary::close( FileHandle_t file )
{
g_pFullFileSystem->Close( file );
}
void CFSIOWriteBinary::seek( FileHandle_t file, int pos )
{
g_pFullFileSystem->Seek( file, pos, FILESYSTEM_SEEK_HEAD );
}
unsigned int CFSIOWriteBinary::tell( FileHandle_t file )
{
return g_pFullFileSystem->Tell( file );
}
#ifndef POSIX
//-----------------------------------------------------------------------------
// Returns the duration of a wav file
//-----------------------------------------------------------------------------
float GetWavSoundDuration( const char *pWavFile )
{
InFileRIFF riff( pWavFile, *g_pFSIOReadBinary );
// UNDONE: Don't use printf to handle errors
if ( riff.RIFFName() != RIFF_WAVE )
return 0.0f;
int nDataSize = 0;
// set up the iterator for the whole file (root RIFF is a chunk)
IterateRIFF walk( riff, riff.RIFFSize() );
// This chunk must be first as it contains the wave's format
// break out when we've parsed it
char pFormatBuffer[ 1024 ];
int nFormatSize;
bool bFound = false;
for ( ; walk.ChunkAvailable( ); walk.ChunkNext() )
{
switch ( walk.ChunkName() )
{
case WAVE_FMT:
bFound = true;
if ( walk.ChunkSize() > sizeof(pFormatBuffer) )
{
Warning( "oops, format tag too big!!!" );
return 0.0f;
}
nFormatSize = walk.ChunkSize();
walk.ChunkRead( pFormatBuffer );
break;
case WAVE_DATA:
nDataSize += walk.ChunkSize();
break;
}
}
if ( !bFound )
return 0.0f;
const WAVEFORMATEX *pHeader = (const WAVEFORMATEX *)pFormatBuffer;
int format = pHeader->wFormatTag;
int nBits = pHeader->wBitsPerSample;
int nRate = pHeader->nSamplesPerSec;
int nChannels = pHeader->nChannels;
int nSampleSize = ( nBits * nChannels ) / 8;
// this can never be zero -- other functions divide by this.
// This should never happen, but avoid crashing
if ( nSampleSize <= 0 )
{
nSampleSize = 1;
}
int nSampleCount = 0;
float flTrueSampleSize = nSampleSize;
if ( format == WAVE_FORMAT_ADPCM )
{
nSampleSize = 1;
ADPCMWAVEFORMAT *pFormat = (ADPCMWAVEFORMAT *)pFormatBuffer;
int blockSize = ((pFormat->wSamplesPerBlock - 2) * pFormat->wfx.nChannels ) / 2;
blockSize += 7 * pFormat->wfx.nChannels;
int blockCount = nSampleCount / blockSize;
int blockRem = nSampleCount % blockSize;
// total samples in complete blocks
nSampleCount = blockCount * pFormat->wSamplesPerBlock;
// add remaining in a short block
if ( blockRem )
{
nSampleCount += pFormat->wSamplesPerBlock - (((blockSize - blockRem) * 2) / nChannels);
}
flTrueSampleSize = 0.5f;
}
else
{
nSampleCount = nDataSize / nSampleSize;
}
float flDuration = (float)nSampleCount / (float)nRate;
return flDuration;
}
#endif

85
tier2/tier2.cpp Normal file
View File

@@ -0,0 +1,85 @@
//===== Copyright (c) 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A higher level link library for general use in the game and tools.
//
//=============================================================================//
#include <tier2/tier2.h>
#include "tier0/dbg.h"
#include "tier2/resourceprecacher.h"
#include "resourcesystem/iresourcesystem.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// These tier2 libraries must be set by any users of this library.
// They can be set by calling ConnectTier2Libraries or InitDefaultFileSystem.
// It is hoped that setting this, and using this library will be the common mechanism for
// allowing link libraries to access tier2 library interfaces
//-----------------------------------------------------------------------------
// Fade data.
FadeData_t g_aFadeData[FADE_MODE_COUNT] =
{
// PixelMin PixelMax Width DistScale FadeMode_t
#ifdef CSTRIKE15
// Ensure fade settings are consistent across CPU levels in CS:GO.
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_NONE
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_LOW
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_MED
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_HIGH
#else
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_NONE
{ 10.0f, 15.0f, 800.0f, 1.0f }, // FADE_MODE_LOW
{ 5.0f, 10.0f, 1024.0f, 1.0f }, // FADE_MODE_MED
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_HIGH
#endif
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_360
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_PS3
{ 0.0f, 0.0f, 1280.0f, 1.0f }, // FADE_MODE_LEVEL
};
//-----------------------------------------------------------------------------
// Used by the resource system for fast resource frame counter
//-----------------------------------------------------------------------------
uint32 g_nResourceFrameCount;
static bool s_bResourceFCRegistered;
static bool s_bPrecachesRegistered;
//-----------------------------------------------------------------------------
// Call this to connect to all tier 2 libraries.
// It's up to the caller to check the globals it cares about to see if ones are missing
//-----------------------------------------------------------------------------
void ConnectTier2Libraries( CreateInterfaceFn *pFactoryList, int nFactoryCount )
{
if ( g_pPrecacheSystem && !s_bPrecachesRegistered )
{
// Make all the PRECACHE_ macros register w/precache system now that it's connected
CBaseResourcePrecacher::RegisterAll();
s_bPrecachesRegistered = true;
}
if ( g_pResourceSystem && !s_bResourceFCRegistered )
{
g_pResourceSystem->RegisterFrameCounter( &g_nResourceFrameCount );
s_bResourceFCRegistered = true;
CSchemaClassBindingBase::Install();
}
}
void DisconnectTier2Libraries()
{
if ( g_pResourceSystem && s_bResourceFCRegistered )
{
g_pResourceSystem->UnregisterFrameCounter( &g_nResourceFrameCount );
s_bResourceFCRegistered = false;
}
}

63
tier2/tier2.vpc Normal file
View File

@@ -0,0 +1,63 @@
//-----------------------------------------------------------------------------
// TIER2.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$macro SRCDIR ".."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE;$SRCDIR\public\tier2"
}
}
$Project "tier2"
{
$Folder "Source Files"
{
$File "beamsegdraw.cpp"
$File "defaultfilesystem.cpp"
$file "fileutils.cpp"
$File "keybindings.cpp"
$File "$SRCDIR\public\map_utils.cpp"
$File "$SRCDIR\public\materialsystem\MaterialSystemUtil.cpp"
$File "meshutils.cpp"
$File "p4helpers.cpp"
$File "renderutils.cpp"
$File "riff.cpp"
$File "soundutils.cpp"
$File "tier2.cpp"
$File "tier2_logging.cpp"
$File "tokenreader.cpp"
$File "util_init.cpp"
$File "utlstreambuffer.cpp"
$File "vconfig.cpp"
$File "schemaclassbinding.cpp"
$File "socketcreator.cpp"
$File "resourceprecacher.cpp"
$File "interval.cpp"
}
$Folder "Public Header Files"
{
$File "$SRCDIR\public\tier2\beamsegdraw.h"
$File "$SRCDIR\public\tier2\fileutils.h"
$File "$SRCDIR\public\tier2\meshutils.h"
$File "$SRCDIR\public\tier2\keybindings.h"
$File "$SRCDIR\public\tier2\renderutils.h"
$File "$SRCDIR\public\tier2\riff.h"
$File "$SRCDIR\public\tier2\socketcreator.h"
$File "$SRCDIR\public\tier2\soundutils.h"
$File "$SRCDIR\public\tier2\tier2.h"
$File "$SRCDIR\public\tier2\tier2_logging.h"
$File "$SRCDIR\public\tier2\tokenreader.h"
$File "$SRCDIR\public\tier2\utlstreambuffer.h"
$File "$SRCDIR\public\tier2\resourceprecacher.h"
$File "$SRCDIR\public\tier2\interval.h"
}
}

13
tier2/tier2.vpc.vpc_cache Normal file
View File

@@ -0,0 +1,13 @@
"vpc_cache"
{
"CacheVersion" "1"
"win32"
{
"CRCFile" "tier2.vcxproj.vpc_crc"
"OutputFiles"
{
"0" "tier2.vcxproj"
"1" "tier2.vcxproj.filters"
}
}
}

123
tier2/tier2_logging.cpp Normal file
View File

@@ -0,0 +1,123 @@
//============ Copyright (c) Valve Corporation, All rights reserved. ============
//
// Tier2 logging helpers.
//
//===============================================================================
#include "tier2_logging.h"
#include "filesystem.h"
#include "interfaces/interfaces.h"
CFileLoggingListener::CFileLoggingListener()
{
for ( int i = 0; i < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT; ++ i )
{
m_OpenFiles[i].Reset();
}
for ( int i = 0; i < MAX_LOGGING_CHANNEL_COUNT; ++ i )
{
m_FileIndices[i] = INVALID_LOGGING_FILE_HANDLE;
}
}
CFileLoggingListener::~CFileLoggingListener()
{
for ( int i = 0; i < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT; ++ i )
{
if ( m_OpenFiles[i].IsOpen() )
{
g_pFullFileSystem->Close( m_OpenFiles[i].m_FileHandle );
m_OpenFiles[i].Reset();
}
}
}
LoggingFileHandle_t CFileLoggingListener::BeginLoggingToFile( const char *pFilename, const char *pOptions, const char *pPathID /* = NULL */ )
{
int fileHandle = GetUnusedFileInfo();
if ( fileHandle != INVALID_LOGGING_FILE_HANDLE )
{
m_OpenFiles[fileHandle].m_FileHandle = g_pFullFileSystem->Open( pFilename, pOptions, pPathID );
}
return fileHandle;
}
void CFileLoggingListener::EndLoggingToFile( LoggingFileHandle_t fileHandle )
{
Assert( fileHandle >= 0 && fileHandle < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT );
/* if the file had any channels associated with it, disassociate them. */
if ( fileHandle != INVALID_LOGGING_FILE_HANDLE )
{
for ( int i = 0 ; i < MAX_LOGGING_CHANNEL_COUNT ; ++i )
{
if ( m_FileIndices[i] == fileHandle )
UnassignLogChannel( i );
}
}
g_pFullFileSystem->Close( m_OpenFiles[fileHandle].m_FileHandle );
m_OpenFiles[fileHandle].Reset();
}
void CFileLoggingListener::AssignLogChannel( LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle )
{
Assert( loggingFileHandle >= 0 && loggingFileHandle < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT );
Assert( m_OpenFiles[loggingFileHandle].IsOpen() );
Assert( channelID >= 0 && channelID < MAX_LOGGING_CHANNEL_COUNT );
m_FileIndices[channelID] = loggingFileHandle;
}
void CFileLoggingListener::UnassignLogChannel( LoggingChannelID_t channelID )
{
Assert( channelID >= 0 && channelID < MAX_LOGGING_CHANNEL_COUNT );
m_FileIndices[channelID] = INVALID_LOGGING_FILE_HANDLE;
}
void CFileLoggingListener::AssignAllLogChannels( LoggingFileHandle_t loggingFileHandle )
{
Assert( loggingFileHandle >= 0 && loggingFileHandle < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT );
Assert( m_OpenFiles[loggingFileHandle].IsOpen() );
for ( int i = 0; i < MAX_LOGGING_CHANNEL_COUNT; ++ i )
{
m_FileIndices[i] = loggingFileHandle;
}
}
void CFileLoggingListener::UnassignAllLogChannels()
{
for ( int i = 0; i < MAX_LOGGING_CHANNEL_COUNT; ++ i )
{
m_FileIndices[i] = INVALID_LOGGING_FILE_HANDLE;
}
}
void CFileLoggingListener::Log( const LoggingContext_t *pContext, const char *pMessage )
{
if ( ( pContext->m_Flags & LCF_CONSOLE_ONLY ) != 0 )
{
return;
}
Assert( pContext->m_ChannelID >= 0 && pContext->m_ChannelID < MAX_LOGGING_CHANNEL_COUNT );
int nFileIndex = m_FileIndices[pContext->m_ChannelID];
if ( nFileIndex >= 0 && nFileIndex < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT )
{
// Shouldn't be trying to log to a closed file.
Assert( m_OpenFiles[nFileIndex].IsOpen() );
g_pFullFileSystem->Write( pMessage, Q_strlen( pMessage ), m_OpenFiles[nFileIndex].m_FileHandle );
g_pFullFileSystem->Flush( m_OpenFiles[nFileIndex].m_FileHandle );
}
}
int CFileLoggingListener::GetUnusedFileInfo() const
{
for ( int i = 0; i < MAX_SIMULTANEOUS_LOGGING_FILE_COUNT; ++ i )
{
if ( !m_OpenFiles[i].IsOpen() )
{
return i;
}
}
return INVALID_LOGGING_FILE_HANDLE;
}

472
tier2/tokenreader.cpp Normal file
View File

@@ -0,0 +1,472 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "tokenreader.h"
#include "tier0/platform.h"
#include "tier1/strtools.h"
#include "tier0/dbg.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
TokenReader::TokenReader(void)
{
m_szFilename[0] = '\0';
m_nLine = 1;
m_nErrorCount = 0;
m_bStuffed = false;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pszFilename -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool TokenReader::Open(const char *pszFilename)
{
m_file.Open( pszFilename, NULL, CUtlBuffer::READ_ONLY );
Q_strncpy(m_szFilename, pszFilename, sizeof( m_szFilename ) );
m_nLine = 1;
m_nErrorCount = 0;
m_bStuffed = false;
return m_file.IsOpen();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void TokenReader::Close()
{
m_file.Close();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *error -
// Output : const char
//-----------------------------------------------------------------------------
const char *TokenReader::Error(char *error, ...)
{
static char szErrorBuf[256];
Q_snprintf(szErrorBuf, sizeof( szErrorBuf ), "File %s, line %d: ", m_szFilename, m_nLine);
Q_strncat(szErrorBuf, error, sizeof( szErrorBuf ), COPY_ALL_CHARACTERS );
m_nErrorCount++;
return(szErrorBuf);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszStore -
// nSize -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
trtoken_t TokenReader::GetString(char *pszStore, int nSize)
{
if (nSize <= 0)
{
return TOKENERROR;
}
char szBuf[1024];
//
// Until we reach the end of this string or run out of room in
// the destination buffer...
//
while (true)
{
//
// Fetch the next batch of text from the file.
//
int writePos = 0;
const char *pToken = NULL;
while ( NULL != (pToken = (const char *)m_file.PeekGet( sizeof(char), 0 )) )
{
if ( pToken[0] == '\"' )
break;
if ( writePos < (sizeof(szBuf)-1) )
{
szBuf[writePos++] = m_file.GetChar();
}
}
szBuf[writePos] = 0;
pToken = (const char *)m_file.PeekGet( sizeof(char), 0 );
if (!pToken)
return TOKENEOF;
//
// Transfer the text to the destination buffer.
//
char *pszSrc = szBuf;
while ((*pszSrc != '\0') && (nSize > 1))
{
if (*pszSrc == '\n')
{
//
// Newline encountered before closing quote -- unterminated string.
//
*pszStore = '\0';
return TOKENSTRINGTOOLONG;
}
else if (*pszSrc != '\\')
{
*pszStore = *pszSrc;
pszSrc++;
}
else
{
//
// Backslash sequence - replace with the appropriate character.
//
pszSrc++;
if (*pszSrc == 'n')
{
*pszStore = '\n';
}
pszSrc++;
}
pszStore++;
nSize--;
}
if (*pszSrc != '\0')
{
//
// Ran out of room in the destination buffer.
// terminate the string, and exit.
//
*pszStore = '\0';
return TOKENSTRINGTOOLONG;
}
//
// Check for closing quote.
//
if (pToken[0] == '\"')
{
//
// Eat the close quote and any whitespace.
//
m_file.GetChar();
bool bCombineStrings = SkipWhiteSpace();
//
// Combine consecutive quoted strings if the combine strings character was
// encountered between the two strings.
//
pToken = (const char *)m_file.PeekGet( sizeof(char), 0 );
if (bCombineStrings && pToken && (pToken[0] == '\"'))
{
//
// Eat the open quote and keep parsing this string.
//
m_file.GetChar();
}
else
{
//
// Done with this string, terminate the string and exit.
//
*pszStore = '\0';
return STRING;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns the next token, allocating enough memory to store the token
// plus a terminating NULL.
// Input : pszStore - Pointer to a string that will be allocated.
// Output : Returns the type of token that was read, or TOKENERROR.
//-----------------------------------------------------------------------------
trtoken_t TokenReader::NextTokenDynamic(char **ppszStore)
{
char szTempBuffer[8192];
trtoken_t eType = NextToken(szTempBuffer, sizeof(szTempBuffer));
int len = Q_strlen(szTempBuffer) + 1;
*ppszStore = new char [len];
Assert( *ppszStore );
Q_strncpy(*ppszStore, szTempBuffer, len );
return(eType);
}
//-----------------------------------------------------------------------------
// Purpose: Returns the next token.
// Input : pszStore - Pointer to a string that will receive the token.
// Output : Returns the type of token that was read, or TOKENERROR.
//-----------------------------------------------------------------------------
trtoken_t TokenReader::NextToken(char *pszStore, int nSize)
{
char *pStart = pszStore;
//
// If they stuffed a token, return that token.
//
if (m_bStuffed)
{
m_bStuffed = false;
Q_strncpy( pszStore, m_szStuffed, nSize );
return m_eStuffed;
}
SkipWhiteSpace();
if ( !m_file.PeekGet(1,0) )
return TOKENEOF;
char ch = *(const char *)m_file.PeekGet( sizeof(char), 0 );
//
// Look for all the valid operators.
//
switch (ch)
{
case '@':
case ',':
case '!':
case '+':
case '&':
case '*':
case '$':
case '.':
case '=':
case ':':
case '[':
case ']':
case '(':
case ')':
case '{':
case '}':
case '\\':
{
pszStore[0] = ch;
pszStore[1] = 0;
m_file.GetChar(); // used char
return OPERATOR;
}
}
//
// Look for the start of a quoted string.
//
if (ch == '\"')
{
m_file.GetChar(); // used char
return GetString(pszStore, nSize);
}
//
// Integers consist of numbers with an optional leading minus sign.
//
if (V_isdigit(ch) || (ch == '-'))
{
do
{
if ( (pszStore - pStart + 1) < nSize )
{
m_file.GetChar(); // used char
*pszStore = ch;
pszStore++;
}
ch = *(const char *)m_file.PeekGet( sizeof(char), 0 );
if (ch == '-')
{
m_file.GetChar(); // used char
return TOKENERROR;
}
} while (V_isdigit(ch));
//
// No identifier characters are allowed contiguous with numbers.
//
if (V_isalpha(ch) || (ch == '_'))
{
m_file.GetChar(); // used char
return TOKENERROR;
}
*pszStore = '\0';
return INTEGER;
}
//
// Identifiers consist of a consecutive string of alphanumeric
// characters and underscores.
//
while ( V_isalpha(ch) || V_isdigit(ch) || (ch == '_') )
{
if ( (pszStore - pStart + 1) < nSize )
{
m_file.GetChar(); // used char
*pszStore = ch;
pszStore++;
}
ch = *(const char *)m_file.PeekGet( sizeof(char), 0 );
}
*pszStore = '\0';
return IDENT;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : ttype -
// *pszToken -
//-----------------------------------------------------------------------------
void TokenReader::IgnoreTill(trtoken_t ttype, const char *pszToken)
{
trtoken_t _ttype;
char szBuf[1024];
while(1)
{
_ttype = NextToken(szBuf, sizeof(szBuf));
if(_ttype == TOKENEOF)
return;
if(_ttype == ttype)
{
if(IsToken(pszToken, szBuf))
{
Stuff(ttype, pszToken);
return;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : ttype -
// pszToken -
//-----------------------------------------------------------------------------
void TokenReader::Stuff(trtoken_t eType, const char *pszToken)
{
m_eStuffed = eType;
Q_strncpy(m_szStuffed, pszToken, sizeof( m_szStuffed ) );
m_bStuffed = true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : ttype -
// pszToken -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool TokenReader::Expecting(trtoken_t ttype, const char *pszToken)
{
char szBuf[1024];
if (NextToken(szBuf, sizeof(szBuf)) != ttype || !IsToken(pszToken, szBuf))
{
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszStore -
// Output :
//-----------------------------------------------------------------------------
trtoken_t TokenReader::PeekTokenType(char *pszStore, int maxlen )
{
if (!m_bStuffed)
{
m_eStuffed = NextToken(m_szStuffed, sizeof(m_szStuffed));
m_bStuffed = true;
}
if (pszStore)
{
Q_strncpy(pszStore, m_szStuffed, maxlen );
}
return(m_eStuffed);
}
//-----------------------------------------------------------------------------
// Purpose: Gets the next non-whitespace character from the file.
// Input : ch - Receives the character.
// Output : Returns true if the whitespace contained the combine strings
// character '+', which is used to merge consecutive quoted strings.
//-----------------------------------------------------------------------------
bool TokenReader::SkipWhiteSpace(void)
{
bool bCombineStrings = false;
while ( m_file.PeekGet(1,0) )
{
char ch = *(const char *)m_file.PeekGet( sizeof(char), 0 );
// whitespace, skip
if ((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == 0))
{
m_file.GetChar();
continue;
}
// string continuation
if (ch == '+')
{
m_file.GetChar();
bCombineStrings = true;
continue;
}
// newline, count and advance
if (ch == '\n')
{
m_file.GetChar();
m_nLine++;
continue;
}
// Deal with c++ style comments
const char *pPeek = (const char *)m_file.PeekGet( 2 * sizeof(char), 0 );
if ( pPeek && ( pPeek[0] == '/' ) && ( pPeek[1] == '/' ) )
{
// read complete line
for ( char c = m_file.GetChar(); m_file.IsValid(); c = m_file.GetChar() )
{
if ( c == '\n' )
break;
}
m_nLine++;
continue;
}
break;
}
return bCombineStrings;
}

55
tier2/util_init.cpp Normal file
View File

@@ -0,0 +1,55 @@
//========= Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: perform initialization needed in most command line programs
//
//===================================================================================-=//
#include <tier0/platform.h>
#include <tier2/tier2.h>
#include <mathlib/mathlib.h>
#include <tier0/icommandline.h>
#include "tier0/memalloc.h"
#include "tier0/progressbar.h"
#include "tier1/strtools.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
static void PrintFReportHandler(char const *job_name, int total_units_to_do, int n_units_completed)
{
static bool work_in_progress=false;
static char LastJobName[1024];
if ( Q_strncmp( LastJobName, job_name, sizeof( LastJobName ) ) )
{
if ( work_in_progress )
printf("..done\n");
Q_strncpy( LastJobName, job_name, sizeof( LastJobName ) );
}
if ( (total_units_to_do > 0 ) && (total_units_to_do >= n_units_completed) )
{
int percent_done=(100*n_units_completed)/total_units_to_do;
printf("\r%s : %d%%",LastJobName, percent_done );
work_in_progress = true;
}
else
{
printf("%s\n",LastJobName);
work_in_progress = false;
}
}
void InitCommandLineProgram( int &argc, char ** &argv )
{
MathLib_Init( 1,1,1,0,false,true,true,true);
CommandLine()->CreateCmdLine( argc, argv );
InitDefaultFileSystem();
InstallProgressReportHandler( PrintFReportHandler );
// handle -allowdebug transparently
if ( ( argc > 1 ) && ( !strcmp( argv[1], "-allowdebug" ) ) )
{
argv++; // messes up argv[0]
argc--;
}
}

418
tier2/utlstreambuffer.cpp Normal file
View File

@@ -0,0 +1,418 @@
//====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======//
//
// Purpose:
//
// $NoKeywords: $
//
// Serialization/unserialization buffer
//=============================================================================//
#include "tier2/utlstreambuffer.h"
#include "tier2/tier2.h"
#include "filesystem.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// default stream chunk size
//-----------------------------------------------------------------------------
enum
{
DEFAULT_STREAM_CHUNK_SIZE = 16 * 1024
};
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CUtlStreamBuffer::CUtlStreamBuffer( ) : BaseClass( DEFAULT_STREAM_CHUNK_SIZE, DEFAULT_STREAM_CHUNK_SIZE, 0 )
{
SetUtlBufferOverflowFuncs( &CUtlStreamBuffer::StreamGetOverflow, &CUtlStreamBuffer::StreamPutOverflow );
m_hFileHandle = FILESYSTEM_INVALID_HANDLE;
m_pFileName = NULL;
m_pPath = NULL;
}
CUtlStreamBuffer::CUtlStreamBuffer( const char *pFileName, const char *pPath, int nFlags, bool bDelayOpen, int nOpenFileFlags ) :
BaseClass( DEFAULT_STREAM_CHUNK_SIZE, DEFAULT_STREAM_CHUNK_SIZE, nFlags )
{
if ( nFlags & TEXT_BUFFER )
{
Warning( "CUtlStreamBuffer does not support TEXT_BUFFER's use CUtlBuffer\n" );
Assert( 0 );
m_Error |= FILE_OPEN_ERROR;
return;
}
SetUtlBufferOverflowFuncs( &CUtlStreamBuffer::StreamGetOverflow, &CUtlStreamBuffer::StreamPutOverflow );
if ( bDelayOpen )
{
int nFileNameLen = Q_strlen( pFileName );
m_pFileName = new char[ nFileNameLen + 1 ];
Q_strcpy( m_pFileName, pFileName );
if ( pPath )
{
int nPathLen = Q_strlen( pPath );
m_pPath = new char[ nPathLen + 1 ];
Q_strcpy( m_pPath, pPath );
}
else
{
m_pPath = new char[ 1 ];
m_pPath[0] = 0;
}
m_nOpenFileFlags = nOpenFileFlags;
m_hFileHandle = FILESYSTEM_INVALID_HANDLE;
}
else
{
m_pFileName = NULL;
m_pPath = NULL;
m_nOpenFileFlags = 0;
m_hFileHandle = OpenFile( pFileName, pPath, nOpenFileFlags );
if ( m_hFileHandle == FILESYSTEM_INVALID_HANDLE )
{
m_Error |= FILE_OPEN_ERROR;
return;
}
}
if ( IsReadOnly() )
{
// NOTE: MaxPut may not actually be this exact size for text files;
// it could be slightly less owing to the /r/n -> /n conversion
m_nMaxPut = g_pFullFileSystem->Size( m_hFileHandle );
// Read in the first bytes of the file
if ( Size() > 0 )
{
int nSizeToRead = MIN( Size(), m_nMaxPut );
ReadBytesFromFile( nSizeToRead, 0 );
}
}
}
void CUtlStreamBuffer::Close()
{
if ( !IsReadOnly() )
{
// Write the final bytes
int nBytesToWrite = TellPut() - m_nOffset;
if ( nBytesToWrite > 0 )
{
if ( ( m_hFileHandle == FILESYSTEM_INVALID_HANDLE ) && m_pFileName )
{
m_hFileHandle = OpenFile( m_pFileName, m_pPath, m_nOpenFileFlags );
}
if ( m_hFileHandle != FILESYSTEM_INVALID_HANDLE )
{
if ( g_pFullFileSystem )
g_pFullFileSystem->Write( Base(), nBytesToWrite, m_hFileHandle );
}
}
}
if ( m_hFileHandle != FILESYSTEM_INVALID_HANDLE )
{
if ( g_pFullFileSystem )
g_pFullFileSystem->Close( m_hFileHandle );
m_hFileHandle = FILESYSTEM_INVALID_HANDLE;
}
if ( m_pFileName )
{
delete[] m_pFileName;
m_pFileName = NULL;
}
if ( m_pPath )
{
delete[] m_pPath;
m_pPath = NULL;
}
m_Error = 0;
}
CUtlStreamBuffer::~CUtlStreamBuffer()
{
Close();
}
//-----------------------------------------------------------------------------
// Open the file. normally done in constructor
//-----------------------------------------------------------------------------
void CUtlStreamBuffer::Open( const char *pFileName, const char *pPath, int nFlags, int nOpenFileFlags )
{
if ( IsOpen() )
{
Close();
}
m_Get = 0;
m_Put = 0;
m_nTab = 0;
m_nOffset = 0;
m_Flags = nFlags;
m_hFileHandle = OpenFile( pFileName, pPath, nOpenFileFlags );
if ( m_hFileHandle == FILESYSTEM_INVALID_HANDLE )
{
m_Error |= FILE_OPEN_ERROR;
return;
}
if ( IsReadOnly() )
{
// NOTE: MaxPut may not actually be this exact size for text files;
// it could be slightly less owing to the /r/n -> /n conversion
m_nMaxPut = g_pFullFileSystem->Size( m_hFileHandle );
// Read in the first bytes of the file
if ( Size() > 0 )
{
int nSizeToRead = MIN( Size(), m_nMaxPut );
ReadBytesFromFile( nSizeToRead, 0 );
}
}
else
{
if ( m_Memory.NumAllocated() != 0 )
{
m_nMaxPut = -1;
AddNullTermination( m_Put );
}
else
{
m_nMaxPut = 0;
}
}
}
//-----------------------------------------------------------------------------
// Is the file open?
//-----------------------------------------------------------------------------
bool CUtlStreamBuffer::IsOpen() const
{
if ( m_hFileHandle != FILESYSTEM_INVALID_HANDLE )
return true;
// Delayed open case
return ( m_pFileName != 0 );
}
//-----------------------------------------------------------------------------
// Grow allocation size to fit requested size
//-----------------------------------------------------------------------------
void CUtlStreamBuffer::GrowAllocatedSize( int nSize )
{
int nNewSize = Size();
if ( nNewSize < nSize + 1 )
{
while ( nNewSize < nSize + 1 )
{
nNewSize += DEFAULT_STREAM_CHUNK_SIZE;
}
m_Memory.Grow( nNewSize - Size() );
}
}
//-----------------------------------------------------------------------------
// Commit some of the stream to disk when we overflow.
//-----------------------------------------------------------------------------
bool CUtlStreamBuffer::StreamPutOverflow( int nSize )
{
if ( !IsValid() || IsReadOnly() )
return false;
// Make sure the allocated size is at least as big as the requested size
if ( nSize > 0 )
{
GrowAllocatedSize( nSize + 2 );
}
// m_nOffset represents the location in the virtual buffer of m_Memory[0].
// Compute the number of bytes that we've buffered up in memory so that we know what to write to disk.
int nBytesToWrite = TellPut() - m_nOffset;
if ( ( nBytesToWrite > 0 ) || ( nSize < 0 ) )
{
if ( m_hFileHandle == FILESYSTEM_INVALID_HANDLE )
{
m_hFileHandle = OpenFile( m_pFileName, m_pPath, m_nOpenFileFlags );
}
}
// Write out the data that we have buffered if we have any.
if ( nBytesToWrite > 0 )
{
int nBytesWritten = g_pFullFileSystem->Write( Base(), nBytesToWrite, m_hFileHandle );
if ( nBytesWritten != nBytesToWrite )
return false;
// Set the offset to the current Put location to indicate that the buffer is now empty.
m_nOffset = TellPut();
}
if ( nSize < 0 )
{
m_nOffset = -nSize-1;
g_pFullFileSystem->Seek( m_hFileHandle, m_nOffset, FILESYSTEM_SEEK_HEAD );
}
return true;
}
//-----------------------------------------------------------------------------
// Commit some of the stream to disk upon requests
//-----------------------------------------------------------------------------
bool CUtlStreamBuffer::TryFlushToFile( int nFlushToFileBytes )
{
if ( !IsValid() || IsReadOnly() || ( m_Error & PUT_OVERFLOW ) )
return false;
// m_nOffset represents the location in the virtual buffer of m_Memory[0].
// Compute the number of bytes that we've buffered up in memory so that we know what to write to disk.
int nBytesToWrite = TellPut() - m_nOffset;
if ( nFlushToFileBytes < nBytesToWrite )
nBytesToWrite = nFlushToFileBytes; // cannot write more than what we have, but can flush beginning of buffer up to certain amount
if ( nBytesToWrite <= 0 )
return true; // nothing buffered to write
if ( m_hFileHandle == FILESYSTEM_INVALID_HANDLE )
{
m_hFileHandle = OpenFile( m_pFileName, m_pPath, m_nOpenFileFlags );
}
// Write out the data that we have buffered if we have any.
int nBytesWritten = g_pFullFileSystem->Write( Base(), nBytesToWrite, m_hFileHandle );
if ( nBytesWritten != nBytesToWrite )
{
m_Error |= PUT_OVERFLOW; // Flag the buffer the same way as if put overflow callback failed
return false; // Let caller know about file IO failure
}
// Move the uncommitted data over and advance the offset up by as many bytes
memmove( Base(), ( const char* ) Base() + nBytesWritten, ( TellPut() - m_nOffset ) - nBytesWritten + 1 ); // + 1 byte for null termination character
m_nOffset += nBytesWritten;
return true;
}
//-----------------------------------------------------------------------------
// Reads bytes from the file; fixes up maxput if necessary and null terminates
//-----------------------------------------------------------------------------
int CUtlStreamBuffer::ReadBytesFromFile( int nBytesToRead, int nReadOffset )
{
if ( m_hFileHandle == FILESYSTEM_INVALID_HANDLE )
{
if ( !m_pFileName )
{
Warning( "File has not been opened!\n" );
Assert(0);
return 0;
}
m_hFileHandle = OpenFile( m_pFileName, m_pPath, m_nOpenFileFlags );
if ( m_hFileHandle == FILESYSTEM_INVALID_HANDLE )
{
Error( "Unable to read file %s!\n", m_pFileName );
return 0;
}
if ( m_nOffset != 0 )
{
g_pFullFileSystem->Seek( m_hFileHandle, m_nOffset, FILESYSTEM_SEEK_HEAD );
}
}
char *pReadPoint = (char*)Base() + nReadOffset;
int nBytesRead = g_pFullFileSystem->Read( pReadPoint, nBytesToRead, m_hFileHandle );
if ( nBytesRead != nBytesToRead )
{
// Since max put is a guess at the start,
// we need to shrink it based on the actual # read
if ( m_nMaxPut > TellGet() + nReadOffset + nBytesRead )
{
m_nMaxPut = TellGet() + nReadOffset + nBytesRead;
}
}
if ( nReadOffset + nBytesRead < Size() )
{
// This is necessary to deal with auto-NULL terminiation
pReadPoint[nBytesRead] = 0;
}
return nBytesRead;
}
//-----------------------------------------------------------------------------
// Load up more of the stream when we overflow
//-----------------------------------------------------------------------------
bool CUtlStreamBuffer::StreamGetOverflow( int nSize )
{
if ( !IsValid() || !IsReadOnly() )
return false;
// Shift the unread bytes down
// NOTE: Can't use the partial overlap path if we're seeking. We'll
// get negative sizes passed in if we're seeking.
int nUnreadBytes;
bool bHasPartialOverlap = ( nSize >= 0 ) && ( TellGet() >= m_nOffset ) && ( TellGet() <= m_nOffset + Size() );
if ( bHasPartialOverlap )
{
nUnreadBytes = Size() - ( TellGet() - m_nOffset );
if ( ( TellGet() != m_nOffset ) && ( nUnreadBytes > 0 ) )
{
memmove( Base(), (const char*)Base() + TellGet() - m_nOffset, nUnreadBytes );
}
}
else
{
m_nOffset = TellGet();
g_pFullFileSystem->Seek( m_hFileHandle, m_nOffset, FILESYSTEM_SEEK_HEAD );
nUnreadBytes = 0;
}
// Make sure the allocated size is at least as big as the requested size
if ( nSize > 0 )
{
GrowAllocatedSize( nSize );
}
int nBytesToRead = Size() - nUnreadBytes;
int nBytesRead = ReadBytesFromFile( nBytesToRead, nUnreadBytes );
if ( nBytesRead == 0 )
return false;
m_nOffset = TellGet();
return ( nBytesRead + nUnreadBytes >= nSize );
}
//-----------------------------------------------------------------------------
// open file unless already failed to open
//-----------------------------------------------------------------------------
FileHandle_t CUtlStreamBuffer::OpenFile( const char *pFileName, const char *pPath, int nOpenFileFlags )
{
if ( m_Error & FILE_OPEN_ERROR )
return FILESYSTEM_INVALID_HANDLE;
char options[ 3 ] = "xx";
options[ 0 ] = IsReadOnly() ? 'r' : 'w';
options[ 1 ] = IsText() && !ContainsCRLF() ? 't' : 'b';
return g_pFullFileSystem->OpenEx( pFileName, options, nOpenFileFlags, pPath );
}

152
tier2/vconfig.cpp Normal file
View File

@@ -0,0 +1,152 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Utilities for setting vproject settings
//
//===========================================================================//
#ifdef _WIN32
#if !defined( _X360 )
#include <windows.h>
#endif
#include <direct.h>
#include <io.h> // _chmod
#include <process.h>
#endif
#if defined( _X360 )
#include "xbox/xbox_win32stubs.h"
#endif
#include "vconfig.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
#ifdef _WIN32
//-----------------------------------------------------------------------------
// Purpose: Returns the string value of a registry key
// Input : *pName - name of the subKey to read
// *pReturn - string buffer to receive read string
// size - size of specified buffer
//-----------------------------------------------------------------------------
bool GetVConfigRegistrySetting( const char *pName, char *pReturn, int size )
{
// Open the key
HKEY hregkey;
// Changed to HKEY_CURRENT_USER from HKEY_LOCAL_MACHINE
if ( RegOpenKeyEx( HKEY_CURRENT_USER, VPROJECT_REG_KEY, 0, KEY_QUERY_VALUE, &hregkey ) != ERROR_SUCCESS )
return false;
// Get the value
DWORD dwSize = size;
if ( RegQueryValueEx( hregkey, pName, NULL, NULL,(LPBYTE) pReturn, &dwSize ) != ERROR_SUCCESS )
return false;
// Close the key
RegCloseKey( hregkey );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Sends a global system message to alert programs to a changed environment variable
//-----------------------------------------------------------------------------
void NotifyVConfigRegistrySettingChanged( void )
{
DWORD_PTR dwReturnValue = 0;
// Propagate changes so that environment variables takes immediate effect!
SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue );
}
//-----------------------------------------------------------------------------
// Purpose: Set the registry entry to a string value, under the given subKey
// Input : *pName - name of the subKey to set
// *pValue - string value
//-----------------------------------------------------------------------------
void SetVConfigRegistrySetting( const char *pName, const char *pValue, bool bNotify )
{
HKEY hregkey;
// Changed to HKEY_CURRENT_USER from HKEY_LOCAL_MACHINE
// Open the key
if ( RegCreateKeyEx(
HKEY_CURRENT_USER, // base key
VPROJECT_REG_KEY, // subkey
0, // reserved
0, // lpClass
0, // options
(REGSAM)KEY_ALL_ACCESS, // access desired
NULL, // security attributes
&hregkey, // result
NULL // tells if it created the key or not (which we don't care)
) != ERROR_SUCCESS )
{
return;
}
// Set the value to the string passed in
int nType = strchr( pValue, '%' ) ? REG_EXPAND_SZ : REG_SZ;
RegSetValueEx( hregkey, pName, 0, nType, (const unsigned char *)pValue, (int) strlen(pValue) );
// Notify other programs
if ( bNotify )
{
NotifyVConfigRegistrySettingChanged();
}
// Close the key
RegCloseKey( hregkey );
}
//-----------------------------------------------------------------------------
// Purpose: Removes the obsolete user keyvalue
// Input : *pName - name of the subKey to set
// *pValue - string value
//-----------------------------------------------------------------------------
bool RemoveObsoleteVConfigRegistrySetting( const char *pValueName, char *pOldValue, int size )
{
// Open the key
HKEY hregkey;
if ( RegOpenKeyEx( HKEY_CURRENT_USER, "Environment", 0, (REGSAM)KEY_ALL_ACCESS, &hregkey ) != ERROR_SUCCESS )
return false;
// Return the old state if they've requested it
if ( pOldValue != NULL )
{
DWORD dwSize = size;
// Get the value
if ( RegQueryValueEx( hregkey, pValueName, NULL, NULL,(LPBYTE) pOldValue, &dwSize ) != ERROR_SUCCESS )
return false;
}
// Remove the value
if ( RegDeleteValue( hregkey, pValueName ) != ERROR_SUCCESS )
return false;
// Close the key
RegCloseKey( hregkey );
// Notify other programs
NotifyVConfigRegistrySettingChanged();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Take a user-defined environment variable and swap it out for the internally used one
//-----------------------------------------------------------------------------
bool ConvertObsoleteVConfigRegistrySetting( const char *pValueName )
{
char szValue[MAX_PATH];
if ( RemoveObsoleteVConfigRegistrySetting( pValueName, szValue, sizeof( szValue ) ) )
{
// Set it up the correct way
SetVConfigRegistrySetting( pValueName, szValue );
return true;
}
return false;
}
#endif

2
tier2/vsi.nul Normal file
View File

@@ -0,0 +1,2 @@
SN Visual Studio Integration
IMPORTANT: Do not remove the custom build step for this file