mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 03:56:10 +08:00
Added most recent version of unmodified HL2 SDK for Episode 1 engine
This commit is contained in:
2157
tier1/KeyValues.cpp
Normal file
2157
tier1/KeyValues.cpp
Normal file
File diff suppressed because it is too large
Load Diff
304
tier1/NetAdr.cpp
Normal file
304
tier1/NetAdr.cpp
Normal file
@ -0,0 +1,304 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// NetAdr.cpp: implementation of the CNetAdr class.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "xbox/xbox_platform.h"
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
#include "tier0/dbg.h"
|
||||
#include "netadr.h"
|
||||
#include "vstdlib/strtools.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock.h>
|
||||
typedef int socklen_t;
|
||||
#elif !defined(_XBOX)
|
||||
#include <netinet/in.h> // ntohs()
|
||||
#include <netdb.h> // gethostbyname()
|
||||
#include <sys/socket.h> // getsockname()
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool netadr_t::CompareAdr (const netadr_t &a, bool onlyBase) const
|
||||
{
|
||||
if ( a.type != type )
|
||||
return false;
|
||||
|
||||
if ( type == NA_LOOPBACK )
|
||||
return true;
|
||||
|
||||
if ( type == NA_BROADCAST )
|
||||
return true;
|
||||
|
||||
if ( type == NA_IP )
|
||||
{
|
||||
if ( !onlyBase && (port != a.port) )
|
||||
return false;
|
||||
|
||||
if ( a.ip[0] == ip[0] && a.ip[1] == ip[1] && a.ip[2] == ip[2] && a.ip[3] == ip[3] )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool netadr_t::CompareClassBAdr (const netadr_t &a) const
|
||||
{
|
||||
if ( a.type != type )
|
||||
return false;
|
||||
|
||||
if ( type == NA_LOOPBACK )
|
||||
return true;
|
||||
|
||||
if ( type == NA_IP )
|
||||
{
|
||||
if (a.ip[0] == ip[0] && a.ip[1] == ip[1] )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// reserved addresses are not routeable, so they can all be used in a LAN game
|
||||
bool netadr_t::IsReservedAdr () const
|
||||
{
|
||||
if ( type == NA_LOOPBACK )
|
||||
return true;
|
||||
|
||||
if ( type == NA_IP )
|
||||
{
|
||||
if ( (ip[0] == 10) || // 10.x.x.x is reserved
|
||||
(ip[0] == 127) || // 127.x.x.x
|
||||
(ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) || // 172.16.x.x - 172.31.x.x
|
||||
(ip[0] == 192 && ip[1] >= 168) ) // 192.168.x.x
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * netadr_t::ToString(bool baseOnly) const
|
||||
{
|
||||
static char s[64];
|
||||
|
||||
Q_strncpy (s, "unknown", sizeof( s ) );
|
||||
|
||||
if (type == NA_LOOPBACK)
|
||||
{
|
||||
Q_strncpy (s, "loopback", sizeof( s ) );
|
||||
}
|
||||
else if (type == NA_BROADCAST)
|
||||
{
|
||||
Q_strncpy (s, "broadcast", sizeof( s ) );
|
||||
}
|
||||
else if (type == NA_IP)
|
||||
{
|
||||
if ( baseOnly)
|
||||
{
|
||||
Q_snprintf (s, sizeof( s ), "%i.%i.%i.%i", ip[0], ip[1], ip[2], ip[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef _XBOX
|
||||
Q_snprintf (s, sizeof( s ), "%i.%i.%i.%i:%i", ip[0], ip[1], ip[2], ip[3], ntohs(port));
|
||||
#else
|
||||
Q_snprintf (s, sizeof( s ), "%i.%i.%i.%i:%i", ip[0], ip[1], ip[2], ip[3], port);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool netadr_t::IsLocalhost() const
|
||||
{
|
||||
// are we 127.0.0.1 ?
|
||||
return (ip[0] == 127) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 1);
|
||||
}
|
||||
|
||||
bool netadr_t::IsLoopback() const
|
||||
{
|
||||
// are we useding engine loopback buffers
|
||||
return type == NA_LOOPBACK;
|
||||
}
|
||||
|
||||
void netadr_t::Clear()
|
||||
{
|
||||
ip[0] = ip[1] = ip[2] = ip[3] = 0;
|
||||
port = 0;
|
||||
type = NA_NULL;
|
||||
}
|
||||
|
||||
void netadr_t::SetIP(uint8 b1, uint8 b2, uint8 b3, uint8 b4)
|
||||
{
|
||||
ip[0] = b1;
|
||||
ip[1] = b2;
|
||||
ip[2] = b3;
|
||||
ip[3] = b4;
|
||||
}
|
||||
|
||||
void netadr_t::SetIP(uint unIP)
|
||||
{
|
||||
*((uint*)ip) = BigLong( unIP );
|
||||
}
|
||||
|
||||
void netadr_t::SetType(netadrtype_t newtype)
|
||||
{
|
||||
type = newtype;
|
||||
}
|
||||
|
||||
netadrtype_t netadr_t::GetType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
unsigned short netadr_t::GetPort() const
|
||||
{
|
||||
return BigShort( port );
|
||||
}
|
||||
|
||||
unsigned int netadr_t::GetIP() const
|
||||
{
|
||||
return *(unsigned int *)&ip;;
|
||||
}
|
||||
|
||||
void netadr_t::ToSockadr (struct sockaddr * s) const
|
||||
{
|
||||
Q_memset ( s, 0, sizeof(struct sockaddr));
|
||||
|
||||
if (type == NA_BROADCAST)
|
||||
{
|
||||
((struct sockaddr_in*)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in*)s)->sin_port = port;
|
||||
((struct sockaddr_in*)s)->sin_addr.s_addr = INADDR_BROADCAST;
|
||||
}
|
||||
else if (type == NA_IP)
|
||||
{
|
||||
((struct sockaddr_in*)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in*)s)->sin_addr.s_addr = *(int *)&ip;
|
||||
((struct sockaddr_in*)s)->sin_port = port;
|
||||
}
|
||||
else if (type == NA_LOOPBACK )
|
||||
{
|
||||
((struct sockaddr_in*)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in*)s)->sin_port = port;
|
||||
((struct sockaddr_in*)s)->sin_addr.s_addr = INADDR_LOOPBACK ;
|
||||
}
|
||||
}
|
||||
|
||||
bool netadr_t::SetFromSockadr(const struct sockaddr * s)
|
||||
{
|
||||
if (s->sa_family == AF_INET)
|
||||
{
|
||||
type = NA_IP;
|
||||
*(int *)&ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
|
||||
port = ((struct sockaddr_in *)s)->sin_port;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool netadr_t::IsValid() const
|
||||
{
|
||||
return ( (port !=0 ) && (type != NA_NULL) &&
|
||||
( ip[0] != 0 || ip[1] != 0 || ip[2] != 0 || ip[3] != 0 ) );
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef SetPort // get around stupid WINSPOOL.H macro
|
||||
#endif
|
||||
|
||||
void netadr_t::SetPort(unsigned short newport)
|
||||
{
|
||||
port = BigShort( newport );
|
||||
}
|
||||
|
||||
void netadr_t::SetFromString( const char *pch, bool bUseDNS )
|
||||
{
|
||||
Clear();
|
||||
type = NA_IP;
|
||||
|
||||
Assert( pch ); // invalid to call this with NULL pointer; fix your code bug!
|
||||
if ( !pch ) // but let's not crash
|
||||
return;
|
||||
|
||||
|
||||
if ( pch[0] >= '0' && pch[0] <= '9' && strchr( pch, '.' ) )
|
||||
{
|
||||
int n1, n2, n3, n4, n5;
|
||||
int nRes = sscanf( pch, "%d.%d.%d.%d:%d", &n1, &n2, &n3, &n4, &n5 );
|
||||
if ( nRes >= 4 )
|
||||
{
|
||||
SetIP( n1, n2, n3, n4 );
|
||||
}
|
||||
|
||||
if ( nRes == 5 )
|
||||
{
|
||||
SetPort( ( uint16 ) n5 );
|
||||
}
|
||||
}
|
||||
else if ( bUseDNS )
|
||||
{
|
||||
char szHostName[ 256 ];
|
||||
Q_strncpy( szHostName, pch, sizeof(szHostName) );
|
||||
char *pchColon = strchr( szHostName, ':' );
|
||||
if ( pchColon )
|
||||
{
|
||||
*pchColon = 0;
|
||||
}
|
||||
|
||||
// DNS it
|
||||
struct hostent *h = gethostbyname( szHostName );
|
||||
if ( !h )
|
||||
return;
|
||||
|
||||
SetIP( ntohl( *(int *)h->h_addr_list[0] ) );
|
||||
|
||||
if ( pchColon )
|
||||
{
|
||||
SetPort( atoi( ++pchColon ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool netadr_t::operator<(const netadr_t &netadr) const
|
||||
{
|
||||
if ( *((uint *)netadr.ip) < *((uint *)ip) )
|
||||
return true;
|
||||
else if ( *((uint *)netadr.ip) > *((uint *)ip) )
|
||||
return false;
|
||||
return ( netadr.port < port );
|
||||
}
|
||||
|
||||
|
||||
void netadr_t::SetFromSocket( int hSocket )
|
||||
{
|
||||
Clear();
|
||||
type = NA_IP;
|
||||
|
||||
struct sockaddr address;
|
||||
int namelen = sizeof(address);
|
||||
if ( getsockname( hSocket, (struct sockaddr *)&address, (int *)&namelen) == 0 )
|
||||
{
|
||||
SetFromSockadr( &address );
|
||||
}
|
||||
}
|
960
tier1/bitbuf.cpp
Normal file
960
tier1/bitbuf.cpp
Normal file
@ -0,0 +1,960 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "bitbuf.h"
|
||||
#include "coordsize.h"
|
||||
#include "vector.h"
|
||||
#include "mathlib.h"
|
||||
#include "vstdlib/strtools.h"
|
||||
|
||||
|
||||
// FIXME: Can't use this until we get multithreaded allocations in tier0 working for tools
|
||||
// This is used by VVIS and fails to link
|
||||
// NOTE: This must be the last file included!!!
|
||||
//#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
// mandatory ... wary of above comment and isolating, tier0 is built as MT though
|
||||
#include "tier0/memdbgon.h"
|
||||
#endif
|
||||
|
||||
static BitBufErrorHandler g_BitBufErrorHandler = 0;
|
||||
|
||||
|
||||
void InternalBitBufErrorHandler( BitBufErrorType errorType, const char *pDebugName )
|
||||
{
|
||||
if ( g_BitBufErrorHandler )
|
||||
g_BitBufErrorHandler( errorType, pDebugName );
|
||||
}
|
||||
|
||||
|
||||
void SetBitBufErrorHandler( BitBufErrorHandler fn )
|
||||
{
|
||||
g_BitBufErrorHandler = fn;
|
||||
}
|
||||
|
||||
|
||||
// #define BB_PROFILING
|
||||
|
||||
|
||||
// Precalculated bit masks for WriteUBitLong. Using these tables instead of
|
||||
// doing the calculations gives a 33% speedup in WriteUBitLong.
|
||||
unsigned long g_BitWriteMasks[32][33];
|
||||
|
||||
// (1 << i) - 1
|
||||
unsigned long g_ExtraMasks[32];
|
||||
|
||||
class CBitWriteMasksInit
|
||||
{
|
||||
public:
|
||||
CBitWriteMasksInit()
|
||||
{
|
||||
for( unsigned int startbit=0; startbit < 32; startbit++ )
|
||||
{
|
||||
for( unsigned int nBitsLeft=0; nBitsLeft < 33; nBitsLeft++ )
|
||||
{
|
||||
unsigned int endbit = startbit + nBitsLeft;
|
||||
g_BitWriteMasks[startbit][nBitsLeft] = (1 << startbit) - 1;
|
||||
if(endbit < 32)
|
||||
g_BitWriteMasks[startbit][nBitsLeft] |= ~((1 << endbit) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
for ( unsigned int maskBit=0; maskBit < 32; maskBit++ )
|
||||
g_ExtraMasks[maskBit] = (1 << maskBit) - 1;
|
||||
}
|
||||
};
|
||||
CBitWriteMasksInit g_BitWriteMasksInit;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
// bf_write
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
|
||||
bf_write::bf_write()
|
||||
{
|
||||
m_pData = NULL;
|
||||
m_nDataBytes = 0;
|
||||
m_nDataBits = -1; // set to -1 so we generate overflow on any operation
|
||||
m_iCurBit = 0;
|
||||
m_bOverflow = false;
|
||||
m_bAssertOnOverflow = true;
|
||||
m_pDebugName = NULL;
|
||||
}
|
||||
|
||||
bf_write::bf_write( const char *pDebugName, void *pData, int nBytes, int nBits )
|
||||
{
|
||||
m_bAssertOnOverflow = true;
|
||||
m_pDebugName = pDebugName;
|
||||
StartWriting( pData, nBytes, 0, nBits );
|
||||
}
|
||||
|
||||
bf_write::bf_write( void *pData, int nBytes, int nBits )
|
||||
{
|
||||
m_bAssertOnOverflow = true;
|
||||
StartWriting( pData, nBytes, 0, nBits );
|
||||
}
|
||||
|
||||
void bf_write::StartWriting( void *pData, int nBytes, int iStartBit, int nBits )
|
||||
{
|
||||
// Make sure it's dword aligned and padded.
|
||||
Assert( (nBytes % 4) == 0 );
|
||||
Assert(((unsigned long)pData & 3) == 0);
|
||||
|
||||
m_pData = (unsigned char*)pData;
|
||||
m_nDataBytes = nBytes;
|
||||
|
||||
if ( nBits == -1 )
|
||||
{
|
||||
m_nDataBits = nBytes << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( nBits <= nBytes*8 );
|
||||
m_nDataBits = nBits;
|
||||
}
|
||||
|
||||
m_iCurBit = iStartBit;
|
||||
m_bOverflow = false;
|
||||
}
|
||||
|
||||
void bf_write::Reset()
|
||||
{
|
||||
m_iCurBit = 0;
|
||||
m_bOverflow = false;
|
||||
}
|
||||
|
||||
|
||||
void bf_write::SetAssertOnOverflow( bool bAssert )
|
||||
{
|
||||
m_bAssertOnOverflow = bAssert;
|
||||
}
|
||||
|
||||
|
||||
const char* bf_write::GetDebugName()
|
||||
{
|
||||
return m_pDebugName;
|
||||
}
|
||||
|
||||
|
||||
void bf_write::SetDebugName( const char *pDebugName )
|
||||
{
|
||||
m_pDebugName = pDebugName;
|
||||
}
|
||||
|
||||
|
||||
void bf_write::SeekToBit( int bitPos )
|
||||
{
|
||||
m_iCurBit = bitPos;
|
||||
}
|
||||
|
||||
|
||||
// Sign bit comes first
|
||||
void bf_write::WriteSBitLong( int data, int numbits )
|
||||
{
|
||||
// Do we have a valid # of bits to encode with?
|
||||
Assert( numbits >= 1 );
|
||||
|
||||
// Note: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
|
||||
// (Some old code writes direct integers right into the buffer).
|
||||
if(data < 0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if( numbits < 32 )
|
||||
{
|
||||
// Make sure it doesn't overflow.
|
||||
|
||||
if( data < 0 )
|
||||
{
|
||||
Assert( data >= -(1 << (numbits-1)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( data < (1 << (numbits-1)) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
WriteUBitLong( (unsigned int)(0x80000000 + data), numbits - 1, false );
|
||||
WriteOneBit( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteUBitLong((unsigned int)data, numbits - 1);
|
||||
WriteOneBit( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
// writes an unsigned integer with variable bit length
|
||||
void bf_write::WriteUBitVar( unsigned int data )
|
||||
{
|
||||
unsigned int bits = 0;
|
||||
unsigned int base = 0;
|
||||
|
||||
while (data > (base<<1))
|
||||
{
|
||||
bits++;
|
||||
base = (1<<bits)-1;
|
||||
}
|
||||
|
||||
// how many bits do we use
|
||||
if ( bits > 0)
|
||||
WriteUBitLong( 0, bits );
|
||||
|
||||
// end marker
|
||||
WriteOneBit( 1 );
|
||||
|
||||
// write the value
|
||||
if ( bits > 0)
|
||||
WriteUBitLong( data - base , bits );
|
||||
}
|
||||
|
||||
void bf_write::WriteBitLong(unsigned int data, int numbits, bool bSigned)
|
||||
{
|
||||
if(bSigned)
|
||||
WriteSBitLong((int)data, numbits);
|
||||
else
|
||||
WriteUBitLong(data, numbits);
|
||||
}
|
||||
|
||||
bool bf_write::WriteBits(const void *pInData, int nBits)
|
||||
{
|
||||
#if defined( BB_PROFILING )
|
||||
VPROF( "bf_write::WriteBits" );
|
||||
#endif
|
||||
|
||||
unsigned char *pOut = (unsigned char*)pInData;
|
||||
int nBitsLeft = nBits;
|
||||
|
||||
if((m_iCurBit+nBits) > m_nDataBits)
|
||||
{
|
||||
SetOverflowFlag();
|
||||
CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get output dword-aligned.
|
||||
while(((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8)
|
||||
{
|
||||
|
||||
WriteUBitLong( *pOut, 8, false );
|
||||
++pOut;
|
||||
nBitsLeft -= 8;
|
||||
}
|
||||
|
||||
// check if we can use fast memcpy if m_iCurBit is byte aligned
|
||||
if ( (nBitsLeft >= 32) && (m_iCurBit & 7) == 0 )
|
||||
{
|
||||
int numbytes = (nBitsLeft >> 3);
|
||||
int numbits = numbytes << 3;
|
||||
|
||||
// Bounds checking..
|
||||
// TODO: May not need this check anymore
|
||||
if((m_iCurBit+numbits) > m_nDataBits)
|
||||
{
|
||||
m_iCurBit = m_nDataBits;
|
||||
SetOverflowFlag();
|
||||
CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() );
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_memcpy( m_pData+(m_iCurBit>>3), pOut, numbytes );
|
||||
pOut += numbytes;
|
||||
nBitsLeft -= numbits;
|
||||
m_iCurBit += numbits;
|
||||
}
|
||||
|
||||
// Read dwords.
|
||||
while(nBitsLeft >= 32)
|
||||
{
|
||||
WriteUBitLong( *((unsigned long*)pOut), 32, false );
|
||||
pOut += sizeof(unsigned long);
|
||||
nBitsLeft -= 32;
|
||||
}
|
||||
|
||||
// Read the remaining bytes.
|
||||
while(nBitsLeft >= 8)
|
||||
{
|
||||
WriteUBitLong( *pOut, 8, false );
|
||||
++pOut;
|
||||
nBitsLeft -= 8;
|
||||
}
|
||||
|
||||
// Read the remaining bits.
|
||||
if(nBitsLeft)
|
||||
{
|
||||
WriteUBitLong( *pOut, nBitsLeft, false );
|
||||
}
|
||||
|
||||
return !IsOverflowed();
|
||||
}
|
||||
|
||||
|
||||
bool bf_write::WriteBitsFromBuffer( bf_read *pIn, int nBits )
|
||||
{
|
||||
// This could be optimized a little by
|
||||
while ( nBits > 32 )
|
||||
{
|
||||
WriteUBitLong( pIn->ReadUBitLong( 32 ), 32 );
|
||||
nBits -= 32;
|
||||
}
|
||||
|
||||
WriteUBitLong( pIn->ReadUBitLong( nBits ), nBits );
|
||||
return !IsOverflowed() && !pIn->IsOverflowed();
|
||||
}
|
||||
|
||||
|
||||
void bf_write::WriteBitAngle( float fAngle, int numbits )
|
||||
{
|
||||
int d;
|
||||
unsigned int mask;
|
||||
unsigned int shift;
|
||||
|
||||
shift = (1<<numbits);
|
||||
mask = shift - 1;
|
||||
|
||||
d = (int)( (fAngle / 360.0) * shift );
|
||||
d &= mask;
|
||||
|
||||
WriteUBitLong((unsigned int)d, numbits);
|
||||
}
|
||||
|
||||
void bf_write::WriteBitCoord (const float f)
|
||||
{
|
||||
#if defined( BB_PROFILING )
|
||||
VPROF( "bf_write::WriteBitCoord" );
|
||||
#endif
|
||||
int signbit = (f <= -COORD_RESOLUTION);
|
||||
int intval = (int)abs(f);
|
||||
int fractval = abs((int)(f*COORD_DENOMINATOR)) & (COORD_DENOMINATOR-1);
|
||||
|
||||
|
||||
// Send the bit flags that indicate whether we have an integer part and/or a fraction part.
|
||||
WriteOneBit( intval );
|
||||
WriteOneBit( fractval );
|
||||
|
||||
if ( intval || fractval )
|
||||
{
|
||||
// Send the sign bit
|
||||
WriteOneBit( signbit );
|
||||
|
||||
// Send the integer if we have one.
|
||||
if ( intval )
|
||||
{
|
||||
// Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
|
||||
intval--;
|
||||
WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS );
|
||||
}
|
||||
|
||||
// Send the fraction if we have one
|
||||
if ( fractval )
|
||||
{
|
||||
WriteUBitLong( (unsigned int)fractval, COORD_FRACTIONAL_BITS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bf_write::WriteBitFloat(float val)
|
||||
{
|
||||
long intVal;
|
||||
|
||||
Assert(sizeof(long) == sizeof(float));
|
||||
Assert(sizeof(float) == 4);
|
||||
|
||||
intVal = *((long*)&val);
|
||||
WriteUBitLong( intVal, 32 );
|
||||
}
|
||||
|
||||
void bf_write::WriteBitVec3Coord( const Vector& fa )
|
||||
{
|
||||
int xflag, yflag, zflag;
|
||||
|
||||
xflag = (fa[0] >= COORD_RESOLUTION) || (fa[0] <= -COORD_RESOLUTION);
|
||||
yflag = (fa[1] >= COORD_RESOLUTION) || (fa[1] <= -COORD_RESOLUTION);
|
||||
zflag = (fa[2] >= COORD_RESOLUTION) || (fa[2] <= -COORD_RESOLUTION);
|
||||
|
||||
WriteOneBit( xflag );
|
||||
WriteOneBit( yflag );
|
||||
WriteOneBit( zflag );
|
||||
|
||||
if ( xflag )
|
||||
WriteBitCoord( fa[0] );
|
||||
if ( yflag )
|
||||
WriteBitCoord( fa[1] );
|
||||
if ( zflag )
|
||||
WriteBitCoord( fa[2] );
|
||||
}
|
||||
|
||||
void bf_write::WriteBitNormal( float f )
|
||||
{
|
||||
int signbit = (f <= -NORMAL_RESOLUTION);
|
||||
|
||||
// NOTE: Since +/-1 are valid values for a normal, I'm going to encode that as all ones
|
||||
unsigned int fractval = abs( (int)(f*NORMAL_DENOMINATOR) );
|
||||
|
||||
// clamp..
|
||||
if (fractval > NORMAL_DENOMINATOR)
|
||||
fractval = NORMAL_DENOMINATOR;
|
||||
|
||||
// Send the sign bit
|
||||
WriteOneBit( signbit );
|
||||
|
||||
// Send the fractional component
|
||||
WriteUBitLong( fractval, NORMAL_FRACTIONAL_BITS );
|
||||
}
|
||||
|
||||
void bf_write::WriteBitVec3Normal( const Vector& fa )
|
||||
{
|
||||
int xflag, yflag;
|
||||
|
||||
xflag = (fa[0] >= NORMAL_RESOLUTION) || (fa[0] <= -NORMAL_RESOLUTION);
|
||||
yflag = (fa[1] >= NORMAL_RESOLUTION) || (fa[1] <= -NORMAL_RESOLUTION);
|
||||
|
||||
WriteOneBit( xflag );
|
||||
WriteOneBit( yflag );
|
||||
|
||||
if ( xflag )
|
||||
WriteBitNormal( fa[0] );
|
||||
if ( yflag )
|
||||
WriteBitNormal( fa[1] );
|
||||
|
||||
// Write z sign bit
|
||||
int signbit = (fa[2] <= -NORMAL_RESOLUTION);
|
||||
WriteOneBit( signbit );
|
||||
}
|
||||
|
||||
void bf_write::WriteBitAngles( const QAngle& fa )
|
||||
{
|
||||
// FIXME:
|
||||
Vector tmp( fa.x, fa.y, fa.z );
|
||||
WriteBitVec3Coord( tmp );
|
||||
}
|
||||
|
||||
void bf_write::WriteChar(int val)
|
||||
{
|
||||
WriteSBitLong(val, sizeof(char) << 3);
|
||||
}
|
||||
|
||||
void bf_write::WriteByte(int val)
|
||||
{
|
||||
WriteUBitLong(val, sizeof(unsigned char) << 3);
|
||||
}
|
||||
|
||||
void bf_write::WriteShort(int val)
|
||||
{
|
||||
WriteSBitLong(val, sizeof(short) << 3);
|
||||
}
|
||||
|
||||
void bf_write::WriteWord(int val)
|
||||
{
|
||||
WriteUBitLong(val, sizeof(unsigned short) << 3);
|
||||
}
|
||||
|
||||
void bf_write::WriteLong(long val)
|
||||
{
|
||||
WriteSBitLong(val, sizeof(long) << 3);
|
||||
}
|
||||
|
||||
void bf_write::WriteFloat(float val)
|
||||
{
|
||||
WriteBits(&val, sizeof(val) << 3);
|
||||
}
|
||||
|
||||
bool bf_write::WriteBytes( const void *pBuf, int nBytes )
|
||||
{
|
||||
return WriteBits(pBuf, nBytes << 3);
|
||||
}
|
||||
|
||||
bool bf_write::WriteString(const char *pStr)
|
||||
{
|
||||
if(pStr)
|
||||
{
|
||||
do
|
||||
{
|
||||
WriteChar( *pStr );
|
||||
++pStr;
|
||||
} while( *(pStr-1) != 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteChar( 0 );
|
||||
}
|
||||
|
||||
return !IsOverflowed();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
// bf_read
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
|
||||
bf_read::bf_read()
|
||||
{
|
||||
m_pData = NULL;
|
||||
m_nDataBytes = 0;
|
||||
m_nDataBits = -1; // set to -1 so we overflow on any operation
|
||||
m_iCurBit = 0;
|
||||
m_bOverflow = false;
|
||||
m_bAssertOnOverflow = true;
|
||||
m_pDebugName = NULL;
|
||||
}
|
||||
|
||||
bf_read::bf_read( const void *pData, int nBytes, int nBits )
|
||||
{
|
||||
m_bAssertOnOverflow = true;
|
||||
StartReading( pData, nBytes, 0, nBits );
|
||||
}
|
||||
|
||||
bf_read::bf_read( const char *pDebugName, const void *pData, int nBytes, int nBits )
|
||||
{
|
||||
m_bAssertOnOverflow = true;
|
||||
m_pDebugName = pDebugName;
|
||||
StartReading( pData, nBytes, 0, nBits );
|
||||
}
|
||||
|
||||
void bf_read::StartReading( const void *pData, int nBytes, int iStartBit, int nBits )
|
||||
{
|
||||
// Make sure we're dword aligned.
|
||||
Assert(((unsigned long)pData & 3) == 0);
|
||||
|
||||
m_pData = (unsigned char*)pData;
|
||||
m_nDataBytes = nBytes;
|
||||
|
||||
if ( nBits == -1 )
|
||||
{
|
||||
m_nDataBits = m_nDataBytes << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( nBits <= nBytes*8 );
|
||||
m_nDataBits = nBits;
|
||||
}
|
||||
|
||||
m_iCurBit = iStartBit;
|
||||
m_bOverflow = false;
|
||||
}
|
||||
|
||||
void bf_read::Reset()
|
||||
{
|
||||
m_iCurBit = 0;
|
||||
m_bOverflow = false;
|
||||
}
|
||||
|
||||
void bf_read::SetAssertOnOverflow( bool bAssert )
|
||||
{
|
||||
m_bAssertOnOverflow = bAssert;
|
||||
}
|
||||
|
||||
const char* bf_read::GetDebugName()
|
||||
{
|
||||
return m_pDebugName;
|
||||
}
|
||||
|
||||
void bf_read::SetDebugName( const char *pName )
|
||||
{
|
||||
m_pDebugName = pName;
|
||||
}
|
||||
|
||||
unsigned int bf_read::CheckReadUBitLong(int numbits)
|
||||
{
|
||||
// Ok, just read bits out.
|
||||
int i, nBitValue;
|
||||
unsigned int r = 0;
|
||||
|
||||
for(i=0; i < numbits; i++)
|
||||
{
|
||||
nBitValue = ReadOneBitNoCheck();
|
||||
r |= nBitValue << i;
|
||||
}
|
||||
m_iCurBit -= numbits;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool bf_read::ReadBits(void *pOutData, int nBits)
|
||||
{
|
||||
#if defined( BB_PROFILING )
|
||||
VPROF( "bf_write::ReadBits" );
|
||||
#endif
|
||||
|
||||
unsigned char *pOut = (unsigned char*)pOutData;
|
||||
int nBitsLeft = nBits;
|
||||
|
||||
|
||||
// Get output dword-aligned.
|
||||
while(((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8)
|
||||
{
|
||||
*pOut = (unsigned char)ReadUBitLong(8);
|
||||
++pOut;
|
||||
nBitsLeft -= 8;
|
||||
}
|
||||
|
||||
// Read dwords.
|
||||
while(nBitsLeft >= 32)
|
||||
{
|
||||
*((unsigned long*)pOut) = ReadUBitLong(32);
|
||||
pOut += sizeof(unsigned long);
|
||||
nBitsLeft -= 32;
|
||||
}
|
||||
|
||||
// Read the remaining bytes.
|
||||
while(nBitsLeft >= 8)
|
||||
{
|
||||
*pOut = ReadUBitLong(8);
|
||||
++pOut;
|
||||
nBitsLeft -= 8;
|
||||
}
|
||||
|
||||
// Read the remaining bits.
|
||||
if(nBitsLeft)
|
||||
{
|
||||
*pOut = ReadUBitLong(nBitsLeft);
|
||||
}
|
||||
|
||||
return !IsOverflowed();
|
||||
}
|
||||
|
||||
float bf_read::ReadBitAngle( int numbits )
|
||||
{
|
||||
float fReturn;
|
||||
int i;
|
||||
float shift;
|
||||
|
||||
shift = (float)( 1 << numbits );
|
||||
|
||||
i = ReadUBitLong( numbits );
|
||||
fReturn = (float)i * (360.0 / shift);
|
||||
|
||||
return fReturn;
|
||||
}
|
||||
|
||||
unsigned int bf_read::PeekUBitLong( int numbits )
|
||||
{
|
||||
unsigned int r;
|
||||
int i, nBitValue;
|
||||
#ifdef BIT_VERBOSE
|
||||
int nShifts = numbits;
|
||||
#endif
|
||||
|
||||
bf_read savebf;
|
||||
|
||||
savebf = *this; // Save current state info
|
||||
|
||||
r = 0;
|
||||
for(i=0; i < numbits; i++)
|
||||
{
|
||||
nBitValue = ReadOneBit();
|
||||
|
||||
// Append to current stream
|
||||
if ( nBitValue )
|
||||
{
|
||||
r |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
*this = savebf;
|
||||
|
||||
#ifdef BIT_VERBOSE
|
||||
Con_Printf( "PeekBitLong: %i %i\n", nShifts, (unsigned int)r );
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Append numbits least significant bits from data to the current bit stream
|
||||
int bf_read::ReadSBitLong( int numbits )
|
||||
{
|
||||
int r, sign;
|
||||
|
||||
r = ReadUBitLong(numbits - 1);
|
||||
|
||||
// Note: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
|
||||
// (Some old code writes direct integers right into the buffer).
|
||||
sign = ReadOneBit();
|
||||
if(sign)
|
||||
r = -((1 << (numbits-1)) - r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
unsigned int bf_read::ReadUBitVar()
|
||||
{
|
||||
int bits = 0; // how many bits are used to encode delta offset
|
||||
|
||||
// how many bits do we use
|
||||
while ( ReadOneBit() == 0 )
|
||||
bits++;
|
||||
|
||||
unsigned int data = (1<<bits)-1;
|
||||
|
||||
// read the value
|
||||
if ( bits > 0)
|
||||
data += ReadUBitLong( bits );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
unsigned int bf_read::ReadBitLong(int numbits, bool bSigned)
|
||||
{
|
||||
if(bSigned)
|
||||
return (unsigned int)ReadSBitLong(numbits);
|
||||
else
|
||||
return ReadUBitLong(numbits);
|
||||
}
|
||||
|
||||
|
||||
// Basic Coordinate Routines (these contain bit-field size AND fixed point scaling constants)
|
||||
float bf_read::ReadBitCoord (void)
|
||||
{
|
||||
#if defined( BB_PROFILING )
|
||||
VPROF( "bf_write::ReadBitCoord" );
|
||||
#endif
|
||||
int intval=0,fractval=0,signbit=0;
|
||||
float value = 0.0;
|
||||
|
||||
|
||||
// Read the required integer and fraction flags
|
||||
intval = ReadOneBit();
|
||||
fractval = ReadOneBit();
|
||||
|
||||
// If we got either parse them, otherwise it's a zero.
|
||||
if ( intval || fractval )
|
||||
{
|
||||
// Read the sign bit
|
||||
signbit = ReadOneBit();
|
||||
|
||||
// If there's an integer, read it in
|
||||
if ( intval )
|
||||
{
|
||||
// Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE]
|
||||
intval = ReadUBitLong( COORD_INTEGER_BITS ) + 1;
|
||||
}
|
||||
|
||||
// If there's a fraction, read it in
|
||||
if ( fractval )
|
||||
{
|
||||
fractval = ReadUBitLong( COORD_FRACTIONAL_BITS );
|
||||
}
|
||||
|
||||
// Calculate the correct floating point value
|
||||
value = intval + ((float)fractval * COORD_RESOLUTION);
|
||||
|
||||
// Fixup the sign if negative.
|
||||
if ( signbit )
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void bf_read::ReadBitVec3Coord( Vector& fa )
|
||||
{
|
||||
int xflag, yflag, zflag;
|
||||
|
||||
// This vector must be initialized! Otherwise, If any of the flags aren't set,
|
||||
// the corresponding component will not be read and will be stack garbage.
|
||||
fa.Init( 0, 0, 0 );
|
||||
|
||||
xflag = ReadOneBit();
|
||||
yflag = ReadOneBit();
|
||||
zflag = ReadOneBit();
|
||||
|
||||
if ( xflag )
|
||||
fa[0] = ReadBitCoord();
|
||||
if ( yflag )
|
||||
fa[1] = ReadBitCoord();
|
||||
if ( zflag )
|
||||
fa[2] = ReadBitCoord();
|
||||
}
|
||||
|
||||
float bf_read::ReadBitNormal (void)
|
||||
{
|
||||
// Read the sign bit
|
||||
int signbit = ReadOneBit();
|
||||
|
||||
// Read the fractional part
|
||||
unsigned int fractval = ReadUBitLong( NORMAL_FRACTIONAL_BITS );
|
||||
|
||||
// Calculate the correct floating point value
|
||||
float value = (float)fractval * NORMAL_RESOLUTION;
|
||||
|
||||
// Fixup the sign if negative.
|
||||
if ( signbit )
|
||||
value = -value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void bf_read::ReadBitVec3Normal( Vector& fa )
|
||||
{
|
||||
int xflag = ReadOneBit();
|
||||
int yflag = ReadOneBit();
|
||||
|
||||
if (xflag)
|
||||
fa[0] = ReadBitNormal();
|
||||
else
|
||||
fa[0] = 0.0f;
|
||||
|
||||
if (yflag)
|
||||
fa[1] = ReadBitNormal();
|
||||
else
|
||||
fa[1] = 0.0f;
|
||||
|
||||
// The first two imply the third (but not its sign)
|
||||
int znegative = ReadOneBit();
|
||||
|
||||
float fafafbfb = fa[0] * fa[0] + fa[1] * fa[1];
|
||||
if (fafafbfb < 1.0f)
|
||||
fa[2] = sqrt( 1.0f - fafafbfb );
|
||||
else
|
||||
fa[2] = 0.0f;
|
||||
|
||||
if (znegative)
|
||||
fa[2] = -fa[2];
|
||||
}
|
||||
|
||||
void bf_read::ReadBitAngles( QAngle& fa )
|
||||
{
|
||||
Vector tmp;
|
||||
ReadBitVec3Coord( tmp );
|
||||
fa.Init( tmp.x, tmp.y, tmp.z );
|
||||
}
|
||||
|
||||
int bf_read::ReadChar()
|
||||
{
|
||||
return ReadSBitLong(sizeof(char) << 3);
|
||||
}
|
||||
|
||||
int bf_read::ReadByte()
|
||||
{
|
||||
return ReadUBitLong(sizeof(unsigned char) << 3);
|
||||
}
|
||||
|
||||
int bf_read::ReadShort()
|
||||
{
|
||||
return ReadSBitLong(sizeof(short) << 3);
|
||||
}
|
||||
|
||||
int bf_read::ReadWord()
|
||||
{
|
||||
return ReadUBitLong(sizeof(unsigned short) << 3);
|
||||
}
|
||||
|
||||
long bf_read::ReadLong()
|
||||
{
|
||||
return ReadSBitLong(sizeof(long) << 3);
|
||||
}
|
||||
|
||||
float bf_read::ReadFloat()
|
||||
{
|
||||
float ret;
|
||||
Assert( sizeof(ret) == 4 );
|
||||
ReadBits(&ret, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool bf_read::ReadBytes(void *pOut, int nBytes)
|
||||
{
|
||||
return ReadBits(pOut, nBytes << 3);
|
||||
}
|
||||
|
||||
bool bf_read::ReadString( char *pStr, int maxLen, bool bLine, int *pOutNumChars )
|
||||
{
|
||||
Assert( maxLen != 0 );
|
||||
|
||||
bool bTooSmall = false;
|
||||
int iChar = 0;
|
||||
while(1)
|
||||
{
|
||||
char val = ReadChar();
|
||||
if ( val == 0 )
|
||||
break;
|
||||
else if ( bLine && val == '\n' )
|
||||
break;
|
||||
|
||||
if ( iChar < (maxLen-1) )
|
||||
{
|
||||
pStr[iChar] = val;
|
||||
++iChar;
|
||||
}
|
||||
else
|
||||
{
|
||||
bTooSmall = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure it's null-terminated.
|
||||
Assert( iChar < maxLen );
|
||||
pStr[iChar] = 0;
|
||||
|
||||
if ( pOutNumChars )
|
||||
*pOutNumChars = iChar;
|
||||
|
||||
return !IsOverflowed() && !bTooSmall;
|
||||
}
|
||||
|
||||
|
||||
char* bf_read::ReadAndAllocateString( bool *pOverflow )
|
||||
{
|
||||
char str[2048];
|
||||
|
||||
int nChars;
|
||||
bool bOverflow = !ReadString( str, sizeof( str ), false, &nChars );
|
||||
if ( pOverflow )
|
||||
*pOverflow = bOverflow;
|
||||
|
||||
// Now copy into the output and return it;
|
||||
char *pRet = new char[ nChars + 1 ];
|
||||
for ( int i=0; i <= nChars; i++ )
|
||||
pRet[i] = str[i];
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
|
||||
bool bf_read::Seek(int iBit)
|
||||
{
|
||||
if(iBit < 0)
|
||||
{
|
||||
SetOverflowFlag();
|
||||
m_iCurBit = m_nDataBits;
|
||||
return false;
|
||||
}
|
||||
else if(iBit > m_nDataBits)
|
||||
{
|
||||
SetOverflowFlag();
|
||||
m_iCurBit = m_nDataBits;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iCurBit = iBit;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void bf_read::ExciseBits( int startbit, int bitstoremove )
|
||||
{
|
||||
int endbit = startbit + bitstoremove;
|
||||
int remaining_to_end = m_nDataBits - endbit;
|
||||
|
||||
bf_write temp;
|
||||
temp.StartWriting( (void *)m_pData, m_nDataBits << 3, startbit );
|
||||
|
||||
Seek( endbit );
|
||||
|
||||
for ( int i = 0; i < remaining_to_end; i++ )
|
||||
{
|
||||
temp.WriteOneBit( ReadOneBit() );
|
||||
}
|
||||
|
||||
Seek( startbit );
|
||||
|
||||
m_nDataBits -= bitstoremove;
|
||||
m_nDataBytes = m_nDataBits >> 3;
|
||||
}
|
181
tier1/byteswap.cpp
Normal file
181
tier1/byteswap.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
//========= Copyright <20> 1996-2006, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Low level byte swapping routines.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "datamap.h"
|
||||
#include "byteswap.h"
|
||||
|
||||
|
||||
void WriteField( void* pOutputBuffer, void *pData, typedescription_t *pField )
|
||||
{
|
||||
switch ( pField->fieldType )
|
||||
{
|
||||
case FIELD_CHARACTER:
|
||||
SwapBufferToTargetEndian<char>( (char*)pOutputBuffer, (char*)pData, pField->fieldSize );
|
||||
break;
|
||||
|
||||
case FIELD_SHORT:
|
||||
SwapBufferToTargetEndian<short>( (short*)pOutputBuffer, (short*)pData, pField->fieldSize );
|
||||
break;
|
||||
|
||||
case FIELD_FLOAT:
|
||||
SwapBufferToTargetEndian<float>( (float*)pOutputBuffer, (float*)pData, pField->fieldSize );
|
||||
break;
|
||||
|
||||
case FIELD_INTEGER:
|
||||
SwapBufferToTargetEndian<int>( (int*)pOutputBuffer, (int*)pData, pField->fieldSize );
|
||||
break;
|
||||
|
||||
case FIELD_VECTOR:
|
||||
SwapBufferToTargetEndian<float>( (float*)pOutputBuffer, (float*)pData, pField->fieldSize * 3 );
|
||||
break;
|
||||
|
||||
case FIELD_QUATERNION:
|
||||
SwapBufferToTargetEndian<float>( (float*)pOutputBuffer, (float*)pData, pField->fieldSize * 4 );
|
||||
break;
|
||||
|
||||
case FIELD_EMBEDDED:
|
||||
// Where does the offset happen?
|
||||
WriteFields( pOutputBuffer, pData, pField->td->dataDesc, pField->td->dataNumFields );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteFields( void *pOutputBuffer, void *pBaseData, typedescription_t *pFields, int fieldCount )
|
||||
{
|
||||
for ( int i = 0; i < fieldCount; ++i )
|
||||
{
|
||||
typedescription_t *pField = &pFields[i];
|
||||
WriteField( (BYTE*)pOutputBuffer + pField->fieldOffset[ TD_OFFSET_NORMAL ],
|
||||
(BYTE*)pBaseData + pField->fieldOffset[ TD_OFFSET_NORMAL ],
|
||||
pField );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Determines the target byte ordering we are swapping to.
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool g_bTargetLittleEndian = true;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the target byte ordering we are swapping to.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetTargetEndian( bool bIsLittleEndian )
|
||||
{
|
||||
g_bTargetLittleEndian = bIsLittleEndian;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// True if the current machine is detected as little endian.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsLittleEndian()
|
||||
{
|
||||
short nIsLittleEndian = 1;
|
||||
|
||||
// if we are little endian, the first byte will be a 1, if big endian, it will be a zero.
|
||||
return (bool)(0 != *(char *)&nIsLittleEndian );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the target machine is the same as this one in endianness
|
||||
// false, if bytes need to be swapped.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsMachineTargetEndian()
|
||||
{
|
||||
// If we are already in the target endianness, then just return the value:
|
||||
if( g_bTargetLittleEndian == IsLittleEndian() )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The lowest level byte swapping workhorse of doom.
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class T> T LowLevelByteSwap( T input )
|
||||
{
|
||||
T output = input; // To solve the "output may not have been initialized" warning.
|
||||
|
||||
for( int i = 0; i < sizeof(T); i++ )
|
||||
{
|
||||
((unsigned char* )&output)[i] = ((unsigned char*)&input)[sizeof(T)-(i+1)];
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the input is byteswapped relative to the native version of
|
||||
// the constant.
|
||||
// ( This is useful for detecting byteswapping in magic numbers in structure
|
||||
// headers for example. )
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class T> bool IsByteSwapped( T input, T nativeConstant )
|
||||
{
|
||||
// If it's the same, it isn't byteswapped:
|
||||
if( input == nativeConstant )
|
||||
return false;
|
||||
|
||||
if( LowLevelByteSwap<T>(input) == nativeConstant )
|
||||
return true;
|
||||
|
||||
// assert( 0 ); // if we get here, input is neither a swapped nor unswapped version of nativeConstant.
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Templated swap function for a given type
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class T> T SwapToTargetEndian( T input )
|
||||
{
|
||||
if( IsMachineTargetEndian() )
|
||||
return input;
|
||||
|
||||
// Otherwise swap it:
|
||||
return LowLevelByteSwap<T>( input );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Swaps an input buffer full of type T into the given output buffer.
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class T> void SwapBufferToTargetEndian( T* outputBuffer, T* inputBuffer, int count )
|
||||
{
|
||||
assert( count >= 0 );
|
||||
assert( outputBuffer );
|
||||
|
||||
// Fail gracefully in release:
|
||||
if( count <=0 || !outputBuffer )
|
||||
return;
|
||||
|
||||
// Optimization for the case when we are swapping in place.
|
||||
if( inputBuffer == outputBuffer )
|
||||
{
|
||||
inputBuffer = NULL;
|
||||
}
|
||||
|
||||
// Are we already the correct endienness? ( or are we swapping 1 byte items? )
|
||||
if( IsMachineTargetEndian() || ( sizeof(T) == 1 ) )
|
||||
{
|
||||
// If we were just going to swap in place then return.
|
||||
if( !inputBuffer )
|
||||
return;
|
||||
|
||||
// Otherwise copy the inputBuffer to the outputBuffer:
|
||||
memcpy( outputBuffer, inputBuffer, count * sizeof( T ) );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Swap everything in the buffer:
|
||||
for( int i = 0; i < count; i++ )
|
||||
{
|
||||
outputBuffer[i] = LowLevelByteSwap<T>(inputBuffer[i]);
|
||||
}
|
||||
}
|
41
tier1/characterset.cpp
Normal file
41
tier1/characterset.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include <string.h>
|
||||
#include "characterset.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: builds a simple lookup table of a group of important characters
|
||||
// Input : *pParseGroup - pointer to the buffer for the group
|
||||
// *pGroupString - null terminated list of characters to flag
|
||||
//-----------------------------------------------------------------------------
|
||||
void CharacterSetBuild( characterset_t *pSetBuffer, const char *pszSetString )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// Test our pointers
|
||||
if ( !pSetBuffer || !pszSetString )
|
||||
return;
|
||||
|
||||
memset( pSetBuffer->set, 0, sizeof(pSetBuffer->set) );
|
||||
|
||||
while ( pszSetString[i] )
|
||||
{
|
||||
pSetBuffer->set[ pszSetString[i] ] = 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
180
tier1/checksum_crc.cpp
Normal file
180
tier1/checksum_crc.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Generic CRC functions
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "commonmacros.h"
|
||||
#include "checksum_crc.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define CRC32_INIT_VALUE 0xFFFFFFFFUL
|
||||
#define CRC32_XOR_VALUE 0xFFFFFFFFUL
|
||||
|
||||
#define NUM_BYTES 256
|
||||
static const CRC32_t pulCRCTable[NUM_BYTES] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
void CRC32_Init(CRC32_t *pulCRC)
|
||||
{
|
||||
*pulCRC = CRC32_INIT_VALUE;
|
||||
}
|
||||
|
||||
void CRC32_Final(CRC32_t *pulCRC)
|
||||
{
|
||||
*pulCRC ^= CRC32_XOR_VALUE;
|
||||
}
|
||||
|
||||
CRC32_t CRC32_GetTableEntry( unsigned int slot )
|
||||
{
|
||||
return pulCRCTable[(unsigned char)slot];
|
||||
}
|
||||
|
||||
void CRC32_ProcessBuffer(CRC32_t *pulCRC, const void *pBuffer, int nBuffer)
|
||||
{
|
||||
CRC32_t ulCrc = *pulCRC;
|
||||
unsigned char *pb = (unsigned char *)pBuffer;
|
||||
unsigned int nFront;
|
||||
int nMain;
|
||||
|
||||
JustAfew:
|
||||
|
||||
switch (nBuffer)
|
||||
{
|
||||
case 7:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
|
||||
case 6:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
|
||||
case 5:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
|
||||
case 4:
|
||||
ulCrc ^= *(CRC32_t *)pb; // Warning, this only works on little-endian.
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
*pulCRC = ulCrc;
|
||||
return;
|
||||
|
||||
case 3:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
|
||||
case 2:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
|
||||
case 1:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
|
||||
case 0:
|
||||
*pulCRC = ulCrc;
|
||||
return;
|
||||
}
|
||||
|
||||
// We may need to do some alignment work up front, and at the end, so that
|
||||
// the main loop is aligned and only has to worry about 8 byte at a time.
|
||||
//
|
||||
// The low-order two bits of pb and nBuffer in total control the
|
||||
// upfront work.
|
||||
//
|
||||
nFront = ((unsigned int)pb) & 3;
|
||||
nBuffer -= nFront;
|
||||
switch (nFront)
|
||||
{
|
||||
case 3:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
case 2:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
case 1:
|
||||
ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
}
|
||||
|
||||
nMain = nBuffer >> 3;
|
||||
while (nMain--)
|
||||
{
|
||||
ulCrc ^= *(CRC32_t *)pb; // Warning, this only works on little-endian.
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc ^= *(CRC32_t *)(pb + 4); // Warning, this only works on little-endian.
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8);
|
||||
pb += 8;
|
||||
}
|
||||
|
||||
nBuffer &= 7;
|
||||
goto JustAfew;
|
||||
}
|
271
tier1/checksum_md5.cpp
Normal file
271
tier1/checksum_md5.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "commonmacros.h"
|
||||
#include "checksum_md5.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "vstdlib/strtools.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// The four core functions - F1 is optimized somewhat
|
||||
// #define F1(x, y, z) (x & y | ~x & z)
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
// This is the central step in the MD5 algorithm.
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
// reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
// the data and converts bytes into longwords for this routine.
|
||||
// Input : buf[4] -
|
||||
// in[16] -
|
||||
// Output : static void
|
||||
//-----------------------------------------------------------------------------
|
||||
static void MD5Transform(unsigned int buf[4], unsigned int const in[16])
|
||||
{
|
||||
register unsigned int a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Start MD5 accumulation. Set bit count to 0 and buffer to mysterious initialization constants.
|
||||
|
||||
// Input : *ctx -
|
||||
//-----------------------------------------------------------------------------
|
||||
void MD5Init(MD5Context_t *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update context to reflect the concatenation of another buffer full of bytes.
|
||||
// Input : *ctx -
|
||||
// *buf -
|
||||
// len -
|
||||
//-----------------------------------------------------------------------------
|
||||
void MD5Update(MD5Context_t *ctx, unsigned char const *buf, unsigned int len)
|
||||
{
|
||||
unsigned int t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((unsigned int) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t)
|
||||
{
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t)
|
||||
{
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
//byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (unsigned int *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64)
|
||||
{
|
||||
memcpy(ctx->in, buf, 64);
|
||||
//byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (unsigned int *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
// 1 0* (64-bit count of bits processed, MSB-first)
|
||||
// Input : digest[MD5_DIGEST_LENGTH] -
|
||||
// *ctx -
|
||||
//-----------------------------------------------------------------------------
|
||||
void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5Context_t *ctx)
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8)
|
||||
{
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
//byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (unsigned int *) ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
//byteReverse(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
((unsigned int *) ctx->in)[14] = ctx->bits[0];
|
||||
((unsigned int *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (unsigned int *) ctx->in);
|
||||
//byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, MD5_DIGEST_LENGTH);
|
||||
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *hash -
|
||||
// hashlen -
|
||||
// Output : char
|
||||
//-----------------------------------------------------------------------------
|
||||
char *MD5_Print( unsigned char *hash, int hashlen )
|
||||
{
|
||||
static char szReturn[64];
|
||||
|
||||
Assert( hashlen <= 32 );
|
||||
|
||||
Q_binarytohex( hash, hashlen, szReturn, sizeof( szReturn ) );
|
||||
return szReturn;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: generate pseudo random number from a seed number
|
||||
// Input : seed number
|
||||
// Output : pseudo random number
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int MD5_PseudoRandom(unsigned int nSeed)
|
||||
{
|
||||
MD5Context_t ctx;
|
||||
unsigned char digest[MD5_DIGEST_LENGTH]; // The MD5 Hash
|
||||
|
||||
memset( &ctx, 0, sizeof( ctx ) );
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (unsigned char*)&nSeed, sizeof(nSeed) );
|
||||
MD5Final(digest, &ctx);
|
||||
|
||||
return *(unsigned int*)(digest+6); // use 4 middle bytes for random value
|
||||
}
|
1029
tier1/convar.cpp
Normal file
1029
tier1/convar.cpp
Normal file
File diff suppressed because it is too large
Load Diff
377
tier1/datamanager.cpp
Normal file
377
tier1/datamanager.cpp
Normal file
@ -0,0 +1,377 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "datamanager.h"
|
||||
|
||||
DECLARE_POINTER_HANDLE( memhandle_t );
|
||||
|
||||
|
||||
CDataManagerBase::CDataManagerBase( unsigned int maxSize )
|
||||
{
|
||||
m_targetMemorySize = maxSize;
|
||||
m_memUsed = 0;
|
||||
m_lruList = m_memoryLists.CreateList();
|
||||
m_lockList = m_memoryLists.CreateList();
|
||||
m_freeList = m_memoryLists.CreateList();
|
||||
m_listsAreFreed = 0;
|
||||
}
|
||||
|
||||
CDataManagerBase::~CDataManagerBase()
|
||||
{
|
||||
Assert( m_listsAreFreed );
|
||||
}
|
||||
|
||||
void CDataManagerBase::SetTargetSize( unsigned int targetSize )
|
||||
{
|
||||
m_targetMemorySize = targetSize;
|
||||
}
|
||||
|
||||
// Frees everything! The LRU AND the LOCKED items. This is only used to forcibly free the resources,
|
||||
// not to make space.
|
||||
void CDataManagerBase::FreeAllLists()
|
||||
{
|
||||
int node;
|
||||
int nextNode;
|
||||
|
||||
node = m_memoryLists.Head(m_lruList);
|
||||
while ( node != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
nextNode = m_memoryLists.Next(node);
|
||||
m_memoryLists.Unlink( m_lruList, node );
|
||||
FreeByIndex( node );
|
||||
node = nextNode;
|
||||
}
|
||||
|
||||
node = m_memoryLists.Head(m_lockList);
|
||||
while ( node != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
nextNode = m_memoryLists.Next(node);
|
||||
m_memoryLists.Unlink( m_lockList, node );
|
||||
m_memoryLists[node].lockCount = 0;
|
||||
FreeByIndex( node );
|
||||
node = nextNode;
|
||||
}
|
||||
m_listsAreFreed = true;
|
||||
}
|
||||
|
||||
|
||||
unsigned int CDataManagerBase::FlushAllUnlocked()
|
||||
{
|
||||
unsigned nBytesInitial = MemUsed_Inline();
|
||||
|
||||
int node = m_memoryLists.Head(m_lruList);
|
||||
while ( node != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
int next = m_memoryLists.Next(node);
|
||||
m_memoryLists.Unlink( m_lruList, node );
|
||||
FreeByIndex( node );
|
||||
node = next;
|
||||
}
|
||||
|
||||
return ( nBytesInitial - MemUsed_Inline() );
|
||||
}
|
||||
|
||||
unsigned int CDataManagerBase::FlushToTargetSize()
|
||||
{
|
||||
unsigned nBytesInitial = MemUsed_Inline();
|
||||
EnsureCapacity(0);
|
||||
return ( nBytesInitial - MemUsed_Inline() );
|
||||
}
|
||||
|
||||
unsigned int CDataManagerBase::FlushAll()
|
||||
{
|
||||
unsigned result = MemUsed_Inline();
|
||||
FreeAllLists();
|
||||
m_listsAreFreed = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int CDataManagerBase::Purge( unsigned int nBytesToPurge )
|
||||
{
|
||||
unsigned int nOriginalTargetSize = MemTotal_Inline();
|
||||
unsigned int nTempTargetSize = MemUsed_Inline() - nBytesToPurge;
|
||||
if ( nTempTargetSize < 0 )
|
||||
nTempTargetSize = 0;
|
||||
SetTargetSize( nTempTargetSize );
|
||||
unsigned result = FlushToTargetSize();
|
||||
SetTargetSize( nOriginalTargetSize );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void CDataManagerBase::DestroyResource( memhandle_t handle )
|
||||
{
|
||||
unsigned short index = FromHandle( handle );
|
||||
if ( !m_memoryLists.IsValidIndex(index) )
|
||||
return;
|
||||
|
||||
Assert( m_memoryLists[index].lockCount == 0 );
|
||||
if ( m_memoryLists[index].lockCount )
|
||||
BreakLock( handle );
|
||||
m_memoryLists.Unlink( m_lruList, index );
|
||||
FreeByIndex( index );
|
||||
}
|
||||
|
||||
|
||||
void *CDataManagerBase::LockResource( memhandle_t handle )
|
||||
{
|
||||
return LockByIndex( FromHandle(handle) );
|
||||
}
|
||||
|
||||
int CDataManagerBase::UnlockResource( memhandle_t handle )
|
||||
{
|
||||
return UnlockByIndex( FromHandle(handle) );
|
||||
}
|
||||
|
||||
void *CDataManagerBase::GetResource_NoLockNoLRUTouch( memhandle_t handle )
|
||||
{
|
||||
unsigned short memoryIndex = FromHandle(handle);
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
return m_memoryLists[memoryIndex].pStore;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void *CDataManagerBase::GetResource_NoLock( memhandle_t handle )
|
||||
{
|
||||
unsigned short memoryIndex = FromHandle(handle);
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
TouchByIndex( memoryIndex );
|
||||
return m_memoryLists[memoryIndex].pStore;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CDataManagerBase::TouchResource( memhandle_t handle )
|
||||
{
|
||||
TouchByIndex( FromHandle(handle) );
|
||||
}
|
||||
|
||||
void CDataManagerBase::MarkAsStale( memhandle_t handle )
|
||||
{
|
||||
MarkAsStaleByIndex( FromHandle(handle) );
|
||||
}
|
||||
|
||||
int CDataManagerBase::BreakLock( memhandle_t handle )
|
||||
{
|
||||
unsigned short memoryIndex = FromHandle(handle);
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() && m_memoryLists[memoryIndex].lockCount )
|
||||
{
|
||||
int nBroken = m_memoryLists[memoryIndex].lockCount;
|
||||
m_memoryLists[memoryIndex].lockCount = 0;
|
||||
m_memoryLists.Unlink( m_lockList, memoryIndex );
|
||||
m_memoryLists.LinkToTail( m_lruList, memoryIndex );
|
||||
|
||||
return nBroken;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CDataManagerBase::BreakAllLocks()
|
||||
{
|
||||
int nBroken = 0;
|
||||
int node;
|
||||
int nextNode;
|
||||
|
||||
node = m_memoryLists.Head(m_lockList);
|
||||
while ( node != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
nBroken++;
|
||||
nextNode = m_memoryLists.Next(node);
|
||||
m_memoryLists[node].lockCount = 0;
|
||||
m_memoryLists.Unlink( m_lockList, node );
|
||||
m_memoryLists.LinkToTail( m_lruList, node );
|
||||
node = nextNode;
|
||||
}
|
||||
|
||||
return nBroken;
|
||||
|
||||
}
|
||||
|
||||
unsigned short CDataManagerBase::CreateHandle()
|
||||
{
|
||||
int memoryIndex = m_memoryLists.Head(m_freeList);
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
m_memoryLists.Unlink( m_freeList, memoryIndex );
|
||||
m_memoryLists.LinkToTail( m_lruList, memoryIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
memoryIndex = m_memoryLists.AddToTail( m_lruList );
|
||||
}
|
||||
return memoryIndex;
|
||||
}
|
||||
|
||||
memhandle_t CDataManagerBase::StoreResourceInHandle( unsigned short memoryIndex, void *pStore, unsigned int realSize )
|
||||
{
|
||||
resource_lru_element_t &mem = m_memoryLists[memoryIndex];
|
||||
mem.pStore = pStore;
|
||||
m_memUsed += realSize;
|
||||
return ToHandle(memoryIndex);
|
||||
}
|
||||
|
||||
void *CDataManagerBase::LockByIndex( unsigned short memoryIndex )
|
||||
{
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
if ( m_memoryLists[memoryIndex].lockCount == 0 )
|
||||
{
|
||||
m_memoryLists.Unlink( m_lruList, memoryIndex );
|
||||
m_memoryLists.LinkToTail( m_lockList, memoryIndex );
|
||||
}
|
||||
Assert(m_memoryLists[memoryIndex].lockCount != (unsigned short)-1);
|
||||
m_memoryLists[memoryIndex].lockCount++;
|
||||
return m_memoryLists[memoryIndex].pStore;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CDataManagerBase::TouchByIndex( unsigned short memoryIndex )
|
||||
{
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
if ( m_memoryLists[memoryIndex].lockCount == 0 )
|
||||
{
|
||||
m_memoryLists.Unlink( m_lruList, memoryIndex );
|
||||
m_memoryLists.LinkToTail( m_lruList, memoryIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CDataManagerBase::MarkAsStaleByIndex( unsigned short memoryIndex )
|
||||
{
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
if ( m_memoryLists[memoryIndex].lockCount == 0 )
|
||||
{
|
||||
m_memoryLists.Unlink( m_lruList, memoryIndex );
|
||||
m_memoryLists.LinkToHead( m_lruList, memoryIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memhandle_t CDataManagerBase::ToHandle( unsigned short index )
|
||||
{
|
||||
unsigned int hiword = m_memoryLists.Element(index).serial;
|
||||
hiword <<= 16;
|
||||
index++;
|
||||
return (memhandle_t)( hiword|index );
|
||||
}
|
||||
|
||||
unsigned int CDataManagerBase::TargetSize()
|
||||
{
|
||||
return MemTotal_Inline();
|
||||
}
|
||||
|
||||
unsigned int CDataManagerBase::AvailableSize()
|
||||
{
|
||||
return MemAvailable_Inline();
|
||||
}
|
||||
|
||||
|
||||
unsigned int CDataManagerBase::UsedSize()
|
||||
{
|
||||
return MemUsed_Inline();
|
||||
}
|
||||
|
||||
bool CDataManagerBase::FreeLRU()
|
||||
{
|
||||
int lruIndex = m_memoryLists.Head( m_lruList );
|
||||
if ( lruIndex == m_memoryLists.InvalidIndex() )
|
||||
return false;
|
||||
m_memoryLists.Unlink( m_lruList, lruIndex );
|
||||
FreeByIndex( lruIndex );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// free resources until there is enough space to hold "size"
|
||||
unsigned int CDataManagerBase::EnsureCapacity( unsigned int size )
|
||||
{
|
||||
unsigned nBytesInitial = MemUsed_Inline();
|
||||
while ( MemUsed_Inline() > MemTotal_Inline() || MemAvailable_Inline() < size )
|
||||
{
|
||||
if ( !FreeLRU() )
|
||||
break;
|
||||
}
|
||||
return ( MemUsed_Inline() - nBytesInitial );
|
||||
}
|
||||
|
||||
// unlock this resource, moving out of the locked list if ref count is zero
|
||||
int CDataManagerBase::UnlockByIndex( unsigned short memoryIndex )
|
||||
{
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
Assert( m_memoryLists[memoryIndex].lockCount > 0 );
|
||||
if ( m_memoryLists[memoryIndex].lockCount > 0 )
|
||||
{
|
||||
m_memoryLists[memoryIndex].lockCount--;
|
||||
if ( m_memoryLists[memoryIndex].lockCount == 0 )
|
||||
{
|
||||
m_memoryLists.Unlink( m_lockList, memoryIndex );
|
||||
m_memoryLists.LinkToTail( m_lruList, memoryIndex );
|
||||
}
|
||||
}
|
||||
return m_memoryLists[memoryIndex].lockCount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// free this resource and move the handle to the free list
|
||||
void CDataManagerBase::FreeByIndex( unsigned short memoryIndex )
|
||||
{
|
||||
if ( memoryIndex != m_memoryLists.InvalidIndex() )
|
||||
{
|
||||
Assert( m_memoryLists[memoryIndex].lockCount == 0 );
|
||||
|
||||
resource_lru_element_t &mem = m_memoryLists[memoryIndex];
|
||||
unsigned size = GetRealSize( mem.pStore );
|
||||
if ( size > m_memUsed )
|
||||
{
|
||||
ExecuteOnce( Warning( "Data manager 'used' memory incorrect\n" ) );
|
||||
size = m_memUsed;
|
||||
}
|
||||
m_memUsed -= size;
|
||||
this->DestroyResourceStorage( mem.pStore );
|
||||
mem.pStore = NULL;
|
||||
mem.serial++;
|
||||
m_memoryLists.LinkToTail( m_freeList, memoryIndex );
|
||||
}
|
||||
}
|
||||
|
||||
// get a list of everything in the LRU
|
||||
void CDataManagerBase::GetLRUHandleList( CUtlVector< memhandle_t >& list )
|
||||
{
|
||||
for ( int node = m_memoryLists.Tail(m_lruList);
|
||||
node != m_memoryLists.InvalidIndex();
|
||||
node = m_memoryLists.Previous(node) )
|
||||
{
|
||||
list.AddToTail( ToHandle( node ) );
|
||||
}
|
||||
}
|
||||
|
||||
// get a list of everything locked
|
||||
void CDataManagerBase::GetLockHandleList( CUtlVector< memhandle_t >& list )
|
||||
{
|
||||
for ( int node = m_memoryLists.Head(m_lockList);
|
||||
node != m_memoryLists.InvalidIndex();
|
||||
node = m_memoryLists.Next(node) )
|
||||
{
|
||||
list.AddToTail( ToHandle( node ) );
|
||||
}
|
||||
}
|
||||
|
547
tier1/diff.cpp
Normal file
547
tier1/diff.cpp
Normal file
@ -0,0 +1,547 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/diff.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
// format of diff output:
|
||||
// 0NN (N=1..127) copy next N literaly
|
||||
//
|
||||
// 1NN (N=1..127) ofs (-128..127) copy next N bytes from original, changin offset by N bytes from
|
||||
// last copy end
|
||||
// 100 N ofs(-32768..32767) copy next N, with larger delta offset
|
||||
// 00 NNNN(1..65535) ofs(-32768..32767) big copy from old
|
||||
// 80 00 NN NN NN big raw copy
|
||||
//
|
||||
// available codes (could be used for additonal compression ops)
|
||||
// long offset form whose offset could have fit in short offset
|
||||
|
||||
// note - this algorithm uses storage equal to 8* the old buffer size. 64k=.5mb
|
||||
|
||||
|
||||
#define MIN_MATCH_LEN 8
|
||||
#define ACCEPTABLE_MATCH_LEN 4096
|
||||
|
||||
struct BlockPtr
|
||||
{
|
||||
BlockPtr *Next;
|
||||
uint8 const *dataptr;
|
||||
};
|
||||
|
||||
template<class T,class V> static inline void AddToHead(T * & head, V * node)
|
||||
{
|
||||
node->Next=head;
|
||||
head=node;
|
||||
}
|
||||
|
||||
void Fail(char const *msg)
|
||||
{
|
||||
Assert(0);
|
||||
}
|
||||
|
||||
void ApplyDiffs(uint8 const *OldBlock, uint8 const *DiffList,
|
||||
int OldSize, int DiffListSize, int &ResultListSize,uint8 *Output,uint32 OutSize)
|
||||
{
|
||||
uint8 const *copy_src=OldBlock;
|
||||
uint8 const *end_of_diff_list=DiffList+DiffListSize;
|
||||
uint8 const *obuf=Output;
|
||||
while(DiffList<end_of_diff_list)
|
||||
{
|
||||
// printf("dptr=%x ",DiffList-d);
|
||||
uint8 op=*(DiffList++);
|
||||
if (op==0)
|
||||
{
|
||||
uint16 copy_sz=DiffList[0]+256*DiffList[1];
|
||||
int copy_ofs=DiffList[2]+DiffList[3]*256;
|
||||
if (copy_ofs>32767)
|
||||
copy_ofs|=0xffff0000;
|
||||
// printf("long cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz);
|
||||
|
||||
memcpy(Output,copy_src+copy_ofs,copy_sz);
|
||||
Output+=copy_sz;
|
||||
copy_src=copy_src+copy_ofs+copy_sz;
|
||||
DiffList+=4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (op & 0x80)
|
||||
{
|
||||
int copy_sz=op & 0x7f;
|
||||
int copy_ofs;
|
||||
if (copy_sz==0)
|
||||
{
|
||||
copy_sz=DiffList[0];
|
||||
if (copy_sz==0)
|
||||
{
|
||||
// big raw copy
|
||||
copy_sz=DiffList[1]+256*DiffList[2]+65536*DiffList[3];
|
||||
memcpy(Output,DiffList+4,copy_sz);
|
||||
// printf("big rawcopy to %x len=%d\n", Output-obuf,copy_sz);
|
||||
|
||||
DiffList+=copy_sz+4;
|
||||
Output+=copy_sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_ofs=DiffList[1]+(DiffList[2]*256);
|
||||
if (copy_ofs>32767)
|
||||
copy_ofs|=0xffff0000;
|
||||
// printf("long ofs cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz);
|
||||
|
||||
memcpy(Output,copy_src+copy_ofs,copy_sz);
|
||||
Output+=copy_sz;
|
||||
copy_src=copy_src+copy_ofs+copy_sz;
|
||||
DiffList+=3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_ofs=DiffList[0];
|
||||
if (copy_ofs>127)
|
||||
copy_ofs|=0xffffff80;
|
||||
// printf("cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz);
|
||||
|
||||
memcpy(Output,copy_src+copy_ofs,copy_sz);
|
||||
Output+=copy_sz;
|
||||
copy_src=copy_src+copy_ofs+copy_sz;
|
||||
DiffList++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("raw copy %d to %x\n",op & 127,Output-obuf);
|
||||
memcpy(Output,DiffList,op & 127);
|
||||
Output+=op & 127;
|
||||
DiffList+=(op & 127);
|
||||
}
|
||||
}
|
||||
}
|
||||
ResultListSize=Output-obuf;
|
||||
|
||||
}
|
||||
|
||||
static void CopyPending(int len, uint8 const *rawbytes,uint8 * &outbuf, uint8 const *limit)
|
||||
{
|
||||
// printf("copy raw len=%d\n",len);
|
||||
if (len<128)
|
||||
{
|
||||
if (limit-outbuf < len+1)
|
||||
Fail("diff buffer overrun");
|
||||
*(outbuf++)=len;
|
||||
memcpy(outbuf,rawbytes,len);
|
||||
outbuf+=len;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit-outbuf < len+5)
|
||||
Fail("diff buffer overrun");
|
||||
*(outbuf++)=0x80;
|
||||
*(outbuf++)=0x00;
|
||||
*(outbuf++)=(len & 255);
|
||||
*(outbuf++)=((len>>8) & 255);
|
||||
*(outbuf++)=((len>>16) & 255);
|
||||
memcpy(outbuf,rawbytes,len);
|
||||
outbuf+=len;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 hasher(uint8 const *mdata)
|
||||
{
|
||||
// attempt to scramble the bits of h1 and h2 together
|
||||
uint32 ret=0;
|
||||
for(int i=0;i<MIN_MATCH_LEN;i++)
|
||||
{
|
||||
ret=ret<<4;
|
||||
ret+=(*mdata++);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FindDiffsForLargeFiles(uint8 const *NewBlock, uint8 const *OldBlock,
|
||||
int NewSize, int OldSize, int &DiffListSize,uint8 *Output,
|
||||
uint32 OutSize,
|
||||
int hashsize)
|
||||
{
|
||||
|
||||
int ret=0;
|
||||
if (OldSize!=NewSize)
|
||||
ret=1;
|
||||
// first, build the hash table
|
||||
BlockPtr **HashedMatches=new BlockPtr* [hashsize];
|
||||
memset(HashedMatches,0,sizeof(HashedMatches[0])*hashsize);
|
||||
BlockPtr *Blocks=0;
|
||||
if (OldSize)
|
||||
Blocks=new BlockPtr[OldSize];
|
||||
BlockPtr *FreeList=Blocks;
|
||||
// now, build the hash table
|
||||
uint8 const *walk=OldBlock;
|
||||
if (OldBlock && OldSize)
|
||||
while(walk<OldBlock+OldSize-MIN_MATCH_LEN)
|
||||
{
|
||||
uint32 hash1=hasher(walk);
|
||||
hash1 &=(hashsize-1);
|
||||
BlockPtr *newnode=FreeList;
|
||||
FreeList++;
|
||||
newnode->dataptr=walk;
|
||||
AddToHead(HashedMatches[hash1],newnode);
|
||||
walk++;
|
||||
}
|
||||
else
|
||||
ret=1;
|
||||
// now, we have the hash table which may be used to search. begin the output step
|
||||
int pending_raw_len=0;
|
||||
walk=NewBlock;
|
||||
uint8 *outbuf=Output;
|
||||
uint8 const *lastmatchend=OldBlock;
|
||||
while(walk<NewBlock+NewSize)
|
||||
{
|
||||
int longest=0;
|
||||
BlockPtr *longest_block=0;
|
||||
if (walk<NewBlock+NewSize-MIN_MATCH_LEN)
|
||||
{
|
||||
// check for a match
|
||||
uint32 hash1=hasher(walk);
|
||||
hash1 &= (hashsize-1);
|
||||
// now, find the longest match in the hash table. If we find one >MIN_MATCH_LEN, take it
|
||||
for(BlockPtr *b=HashedMatches[hash1];b;b=b->Next)
|
||||
{
|
||||
// find the match length
|
||||
int match_of=b->dataptr-lastmatchend;
|
||||
if ((match_of>-32768) && (match_of<32767))
|
||||
{
|
||||
int max_mlength=min(65535,OldBlock+OldSize-b->dataptr);
|
||||
max_mlength=min(max_mlength,NewBlock+NewSize-walk);
|
||||
int i;
|
||||
for(i=0;i<max_mlength;i++)
|
||||
if (walk[i]!=b->dataptr[i])
|
||||
break;
|
||||
if ((i>MIN_MATCH_LEN) && (i>longest))
|
||||
{
|
||||
longest=i;
|
||||
longest_block=b;
|
||||
if (longest>ACCEPTABLE_MATCH_LEN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// now, we have a match maybe
|
||||
if (longest_block)
|
||||
{
|
||||
if (pending_raw_len) // must output
|
||||
{
|
||||
ret=1;
|
||||
CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize);
|
||||
pending_raw_len=0;
|
||||
}
|
||||
// now, output copy block
|
||||
int match_of=longest_block->dataptr-lastmatchend;
|
||||
int nremaining=OutSize-(outbuf-Output);
|
||||
|
||||
if (match_of)
|
||||
ret=1;
|
||||
// printf("copy from %x to %x len=%d\n", match_of,outbuf-Output,longest);
|
||||
if (longest>127)
|
||||
{
|
||||
// use really long encoding
|
||||
if (nremaining<5)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=00;
|
||||
*(outbuf++)=(longest & 255);
|
||||
*(outbuf++)=((longest>>8) & 255);
|
||||
*(outbuf++)=(match_of & 255);
|
||||
*(outbuf++)=((match_of>>8) & 255);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((match_of>=-128) && (match_of<128))
|
||||
{
|
||||
if (nremaining<2)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=128+longest;
|
||||
*(outbuf++)=(match_of&255);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use long encoding
|
||||
if (nremaining<4)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=0x80;
|
||||
*(outbuf++)=longest;
|
||||
*(outbuf++)=(match_of & 255);
|
||||
*(outbuf++)=((match_of>>8) & 255);
|
||||
}
|
||||
}
|
||||
lastmatchend=longest_block->dataptr+longest;
|
||||
walk+=longest;
|
||||
}
|
||||
else
|
||||
{
|
||||
walk++;
|
||||
pending_raw_len++;
|
||||
}
|
||||
}
|
||||
// now, flush pending raw copy
|
||||
if (pending_raw_len) // must output
|
||||
{
|
||||
ret=1;
|
||||
CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize);
|
||||
pending_raw_len=0;
|
||||
}
|
||||
delete[] HashedMatches;
|
||||
if (Blocks)
|
||||
delete[] Blocks;
|
||||
DiffListSize=outbuf-Output;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int FindDiffs(uint8 const *NewBlock, uint8 const *OldBlock,
|
||||
int NewSize, int OldSize, int &DiffListSize,uint8 *Output,uint32 OutSize)
|
||||
{
|
||||
|
||||
int ret=0;
|
||||
if (OldSize!=NewSize)
|
||||
ret=1;
|
||||
// first, build the hash table
|
||||
BlockPtr *HashedMatches[65536];
|
||||
memset(HashedMatches,0,sizeof(HashedMatches));
|
||||
BlockPtr *Blocks=0;
|
||||
if (OldSize)
|
||||
Blocks=new BlockPtr[OldSize];
|
||||
BlockPtr *FreeList=Blocks;
|
||||
// now, build the hash table
|
||||
uint8 const *walk=OldBlock;
|
||||
if (OldBlock && OldSize)
|
||||
while(walk<OldBlock+OldSize-MIN_MATCH_LEN)
|
||||
{
|
||||
uint16 hash1=*((uint16 const *) walk)+*((uint16 const *) walk+2);
|
||||
BlockPtr *newnode=FreeList;
|
||||
FreeList++;
|
||||
newnode->dataptr=walk;
|
||||
AddToHead(HashedMatches[hash1],newnode);
|
||||
walk++;
|
||||
}
|
||||
else
|
||||
ret=1;
|
||||
// now, we have the hash table which may be used to search. begin the output step
|
||||
int pending_raw_len=0;
|
||||
walk=NewBlock;
|
||||
uint8 *outbuf=Output;
|
||||
uint8 const *lastmatchend=OldBlock;
|
||||
while(walk<NewBlock+NewSize)
|
||||
{
|
||||
int longest=0;
|
||||
BlockPtr *longest_block=0;
|
||||
if (walk<NewBlock+NewSize-MIN_MATCH_LEN)
|
||||
{
|
||||
// check for a match
|
||||
uint16 hash1=*((uint16 const *) walk)+*((uint16 const *) walk+2);
|
||||
// now, find the longest match in the hash table. If we find one >MIN_MATCH_LEN, take it
|
||||
for(BlockPtr *b=HashedMatches[hash1];b;b=b->Next)
|
||||
{
|
||||
// find the match length
|
||||
int match_of=b->dataptr-lastmatchend;
|
||||
if ((match_of>-32768) && (match_of<32767))
|
||||
{
|
||||
int max_mlength=min(65535,OldBlock+OldSize-b->dataptr);
|
||||
max_mlength=min(max_mlength,NewBlock+NewSize-walk);
|
||||
int i;
|
||||
for(i=0;i<max_mlength;i++)
|
||||
if (walk[i]!=b->dataptr[i])
|
||||
break;
|
||||
if ((i>MIN_MATCH_LEN) && (i>longest))
|
||||
{
|
||||
longest=i;
|
||||
longest_block=b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// now, we have a match maybe
|
||||
if (longest_block)
|
||||
{
|
||||
if (pending_raw_len) // must output
|
||||
{
|
||||
ret=1;
|
||||
CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize);
|
||||
pending_raw_len=0;
|
||||
}
|
||||
// now, output copy block
|
||||
int match_of=longest_block->dataptr-lastmatchend;
|
||||
int nremaining=OutSize-(outbuf-Output);
|
||||
if (match_of)
|
||||
ret=1;
|
||||
if (longest>127)
|
||||
{
|
||||
// use really long encoding
|
||||
if (nremaining<5)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=00;
|
||||
*(outbuf++)=(longest & 255);
|
||||
*(outbuf++)=((longest>>8) & 255);
|
||||
*(outbuf++)=(match_of & 255);
|
||||
*(outbuf++)=((match_of>>8) & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((match_of>=-128) && (match_of<128))
|
||||
{
|
||||
if (nremaining<2)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=128+longest;
|
||||
*(outbuf++)=(match_of&255);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use long encoding
|
||||
if (nremaining<4)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=0x80;
|
||||
*(outbuf++)=longest;
|
||||
*(outbuf++)=(match_of & 255);
|
||||
*(outbuf++)=((match_of>>8) & 255);
|
||||
}
|
||||
}
|
||||
lastmatchend=longest_block->dataptr+longest;
|
||||
walk+=longest;
|
||||
}
|
||||
else
|
||||
{
|
||||
walk++;
|
||||
pending_raw_len++;
|
||||
}
|
||||
}
|
||||
// now, flush pending raw copy
|
||||
if (pending_raw_len) // must output
|
||||
{
|
||||
ret=1;
|
||||
CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize);
|
||||
pending_raw_len=0;
|
||||
}
|
||||
if (Blocks)
|
||||
delete[] Blocks;
|
||||
DiffListSize=outbuf-Output;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int FindDiffsLowMemory(uint8 const *NewBlock, uint8 const *OldBlock,
|
||||
int NewSize, int OldSize, int &DiffListSize,uint8 *Output,uint32 OutSize)
|
||||
{
|
||||
|
||||
int ret=0;
|
||||
if (OldSize!=NewSize)
|
||||
ret=1;
|
||||
uint8 const *old_data_hash[256];
|
||||
memset(old_data_hash,0,sizeof(old_data_hash));
|
||||
int pending_raw_len=0;
|
||||
uint8 const *walk=NewBlock;
|
||||
uint8 const *oldptr=OldBlock;
|
||||
uint8 *outbuf=Output;
|
||||
uint8 const *lastmatchend=OldBlock;
|
||||
while(walk<NewBlock+NewSize)
|
||||
{
|
||||
while( (oldptr-OldBlock<walk-NewBlock+40) && (oldptr-OldBlock<OldSize-MIN_MATCH_LEN))
|
||||
{
|
||||
uint16 hash1=(oldptr[0]+oldptr[1]+oldptr[2]+oldptr[3]) & (NELEMS(old_data_hash)-1);
|
||||
old_data_hash[hash1]=oldptr;
|
||||
oldptr++;
|
||||
}
|
||||
int longest=0;
|
||||
uint8 const *longest_block=0;
|
||||
if (walk<NewBlock+NewSize-MIN_MATCH_LEN)
|
||||
{
|
||||
// check for a match
|
||||
uint16 hash1=(walk[0]+walk[1]+walk[2]+walk[3]) & (NELEMS(old_data_hash)-1);
|
||||
if (old_data_hash[hash1])
|
||||
{
|
||||
int max_bytes_to_compare=min(NewBlock+NewSize-walk,OldBlock+OldSize-old_data_hash[hash1]);
|
||||
int nmatches;
|
||||
for(nmatches=0;nmatches<max_bytes_to_compare;nmatches++)
|
||||
if (walk[nmatches]!=old_data_hash[hash1][nmatches])
|
||||
break;
|
||||
if (nmatches>MIN_MATCH_LEN)
|
||||
{
|
||||
longest_block=old_data_hash[hash1];
|
||||
longest=nmatches;
|
||||
}
|
||||
}
|
||||
}
|
||||
// now, we have a match maybe
|
||||
if (longest_block)
|
||||
{
|
||||
if (pending_raw_len) // must output
|
||||
{
|
||||
ret=1;
|
||||
CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize);
|
||||
pending_raw_len=0;
|
||||
}
|
||||
// now, output copy block
|
||||
int match_of=longest_block-lastmatchend;
|
||||
int nremaining=OutSize-(outbuf-Output);
|
||||
if (match_of)
|
||||
ret=1;
|
||||
if (longest>127)
|
||||
{
|
||||
// use really long encoding
|
||||
if (nremaining<5)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=00;
|
||||
*(outbuf++)=(longest & 255);
|
||||
*(outbuf++)=((longest>>8) & 255);
|
||||
*(outbuf++)=(match_of & 255);
|
||||
*(outbuf++)=((match_of>>8) & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((match_of>=-128) && (match_of<128))
|
||||
{
|
||||
if (nremaining<2)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=128+longest;
|
||||
*(outbuf++)=(match_of&255);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use long encoding
|
||||
if (nremaining<4)
|
||||
Fail("diff buff needs increase");
|
||||
*(outbuf++)=0x80;
|
||||
*(outbuf++)=longest;
|
||||
*(outbuf++)=(match_of & 255);
|
||||
*(outbuf++)=((match_of>>8) & 255);
|
||||
}
|
||||
}
|
||||
lastmatchend=longest_block+longest;
|
||||
walk+=longest;
|
||||
}
|
||||
else
|
||||
{
|
||||
walk++;
|
||||
pending_raw_len++;
|
||||
}
|
||||
}
|
||||
// now, flush pending raw copy
|
||||
if (pending_raw_len) // must output
|
||||
{
|
||||
ret=1;
|
||||
CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize);
|
||||
pending_raw_len=0;
|
||||
}
|
||||
DiffListSize=outbuf-Output;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
290
tier1/generichash.cpp
Normal file
290
tier1/generichash.cpp
Normal file
@ -0,0 +1,290 @@
|
||||
//======= Copyright <20> 2005, , Valve Corporation, All rights reserved. =========
|
||||
//
|
||||
// Purpose: Variant Pearson Hash general purpose hashing algorithm described
|
||||
// by Cargill in C++ Report 1994. Generates a 16-bit result.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/platform.h"
|
||||
#include "generichash.h"
|
||||
#include <ctype.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Table of randomly shuffled values from 0-255 generated by:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
void MakeRandomValues()
|
||||
{
|
||||
int i, j, r;
|
||||
unsigned t;
|
||||
srand( 0xdeadbeef );
|
||||
|
||||
for ( i = 0; i < 256; i++ )
|
||||
{
|
||||
g_nRandomValues[i] = (unsigned )i;
|
||||
}
|
||||
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
r = rand() & 0xff;
|
||||
t = g_nRandomValues[i];
|
||||
g_nRandomValues[i] = g_nRandomValues[r];
|
||||
g_nRandomValues[r] = t;
|
||||
}
|
||||
}
|
||||
|
||||
printf("static unsigned g_nRandomValues[256] =\n{\n");
|
||||
|
||||
for (i = 0; i < 256; i += 16)
|
||||
{
|
||||
printf("\t");
|
||||
for (j = 0; j < 16; j++)
|
||||
printf(" %3d,", g_nRandomValues[i+j]);
|
||||
printf("\n");
|
||||
}
|
||||
printf("};\n");
|
||||
}
|
||||
*/
|
||||
|
||||
static unsigned g_nRandomValues[256] =
|
||||
{
|
||||
238, 164, 191, 168, 115, 16, 142, 11, 213, 214, 57, 151, 248, 252, 26, 198,
|
||||
13, 105, 102, 25, 43, 42, 227, 107, 210, 251, 86, 66, 83, 193, 126, 108,
|
||||
131, 3, 64, 186, 192, 81, 37, 158, 39, 244, 14, 254, 75, 30, 2, 88,
|
||||
172, 176, 255, 69, 0, 45, 116, 139, 23, 65, 183, 148, 33, 46, 203, 20,
|
||||
143, 205, 60, 197, 118, 9, 171, 51, 233, 135, 220, 49, 71, 184, 82, 109,
|
||||
36, 161, 169, 150, 63, 96, 173, 125, 113, 67, 224, 78, 232, 215, 35, 219,
|
||||
79, 181, 41, 229, 149, 153, 111, 217, 21, 72, 120, 163, 133, 40, 122, 140,
|
||||
208, 231, 211, 200, 160, 182, 104, 110, 178, 237, 15, 101, 27, 50, 24, 189,
|
||||
177, 130, 187, 92, 253, 136, 100, 212, 19, 174, 70, 22, 170, 206, 162, 74,
|
||||
247, 5, 47, 32, 179, 117, 132, 195, 124, 123, 245, 128, 236, 223, 12, 84,
|
||||
54, 218, 146, 228, 157, 94, 106, 31, 17, 29, 194, 34, 56, 134, 239, 246,
|
||||
241, 216, 127, 98, 7, 204, 154, 152, 209, 188, 48, 61, 87, 97, 225, 85,
|
||||
90, 167, 155, 112, 145, 114, 141, 93, 250, 4, 201, 156, 38, 89, 226, 196,
|
||||
1, 235, 44, 180, 159, 121, 119, 166, 190, 144, 10, 91, 76, 230, 221, 80,
|
||||
207, 55, 58, 53, 175, 8, 6, 52, 68, 242, 18, 222, 103, 249, 147, 129,
|
||||
138, 243, 28, 185, 62, 59, 240, 202, 234, 99, 77, 73, 199, 137, 95, 165,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned HashString( const char *pszKey )
|
||||
{
|
||||
const uint8 *k = (const uint8 *)pszKey;
|
||||
unsigned even = 0,
|
||||
odd = 0,
|
||||
n;
|
||||
|
||||
while ((n = *k++) != 0)
|
||||
{
|
||||
even = g_nRandomValues[odd ^ n];
|
||||
if ((n = *k++) != 0)
|
||||
odd = g_nRandomValues[even ^ n];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return (even << 8) | odd ;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Case-insensitive string
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned HashStringCaseless( const char *pszKey )
|
||||
{
|
||||
const uint8 *k = (const uint8 *) pszKey;
|
||||
unsigned even = 0,
|
||||
odd = 0,
|
||||
n;
|
||||
|
||||
while ((n = toupper(*k++)) != 0)
|
||||
{
|
||||
even = g_nRandomValues[odd ^ n];
|
||||
if ((n = toupper(*k++)) != 0)
|
||||
odd = g_nRandomValues[even ^ n];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return (even << 8) | odd;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 32 bit conventional case-insensitive string
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned HashStringCaselessConventional( const char *pszKey )
|
||||
{
|
||||
unsigned hash = 0xAAAAAAAA; // Alternating 1's and 0's to maximize the effect of the later multiply and add
|
||||
|
||||
for( ; *pszKey ; pszKey++ )
|
||||
{
|
||||
hash = ( ( hash << 5 ) + hash ) + (uint8)tolower(*pszKey);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Case-insensitive string
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 4-byte hash
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned Hash4( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
return (even << 8) | odd;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 8-byte hash
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned Hash8( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
n = *(p+1);
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
return (even << 8) | odd;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 12-byte hash
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned Hash12( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
n = *(p+1);
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
n = *(p+2);
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
return (even << 8) | odd;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 16-byte hash
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned Hash16( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
n = *(p+1);
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
n = *(p+2);
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
n = *(p+3);
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
return (even << 8) | odd;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Arbitrary fixed length hash
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned HashBlock( const void *pKey, unsigned size )
|
||||
{
|
||||
const uint8 * k = (const uint8 *) pKey;
|
||||
unsigned even = 0,
|
||||
odd = 0,
|
||||
n;
|
||||
|
||||
while (size)
|
||||
{
|
||||
--size;
|
||||
n = *k++;
|
||||
even = g_nRandomValues[odd ^ n];
|
||||
if (size)
|
||||
{
|
||||
--size;
|
||||
n = *k++;
|
||||
odd = g_nRandomValues[even ^ n];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return (even << 8) | odd;
|
||||
}
|
||||
|
359
tier1/interface.cpp
Normal file
359
tier1/interface.cpp
Normal file
@ -0,0 +1,359 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "xbox/xbox_platform.h"
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
#if !defined( DONT_PROTECT_FILEIO_FUNCTIONS )
|
||||
#define DONT_PROTECT_FILEIO_FUNCTIONS // for protected_things.h
|
||||
#endif
|
||||
|
||||
#if defined( PROTECTED_THINGS_ENABLE )
|
||||
#undef PROTECTED_THINGS_ENABLE // from protected_things.h
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "interface.h"
|
||||
#include "basetypes.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "vstdlib/strtools.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "tier0/dbg.h"
|
||||
#ifdef _WIN32
|
||||
#include <direct.h> // getcwd
|
||||
#elif _LINUX
|
||||
#define _getcwd getcwd
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
// InterfaceReg.
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
InterfaceReg *InterfaceReg::s_pInterfaceRegs = NULL;
|
||||
|
||||
InterfaceReg::InterfaceReg( InstantiateInterfaceFn fn, const char *pName ) :
|
||||
m_pName(pName)
|
||||
{
|
||||
m_CreateFn = fn;
|
||||
m_pNext = s_pInterfaceRegs;
|
||||
s_pInterfaceRegs = this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
// CreateInterface.
|
||||
// This is the primary exported function by a dll, referenced by name via dynamic binding
|
||||
// that exposes an opqaue function pointer to the interface.
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
void* CreateInterface( const char *pName, int *pReturnCode )
|
||||
{
|
||||
InterfaceReg *pCur;
|
||||
|
||||
for (pCur=InterfaceReg::s_pInterfaceRegs; pCur; pCur=pCur->m_pNext)
|
||||
{
|
||||
if (strcmp(pCur->m_pName, pName) == 0)
|
||||
{
|
||||
if (pReturnCode)
|
||||
{
|
||||
*pReturnCode = IFACE_OK;
|
||||
}
|
||||
return pCur->m_CreateFn();
|
||||
}
|
||||
}
|
||||
|
||||
if (pReturnCode)
|
||||
{
|
||||
*pReturnCode = IFACE_FAILED;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _LINUX
|
||||
// Linux doesn't have this function so this emulates its functionality
|
||||
void *GetModuleHandle(const char *name)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
if( name == NULL )
|
||||
{
|
||||
// hmm, how can this be handled under linux....
|
||||
// is it even needed?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( (handle=dlopen(name, RTLD_NOW))==NULL)
|
||||
{
|
||||
printf("DLOPEN Error:%s\n",dlerror());
|
||||
// couldn't open this file
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// read "man dlopen" for details
|
||||
// in short dlopen() inc a ref count
|
||||
// so dec the ref count by performing the close
|
||||
dlclose(handle);
|
||||
return handle;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to a function, given a module
|
||||
// Input : pModuleName - module name
|
||||
// *pName - proc name
|
||||
//-----------------------------------------------------------------------------
|
||||
static void *Sys_GetProcAddress( const char *pModuleName, const char *pName )
|
||||
{
|
||||
return GetProcAddress( GetModuleHandle(pModuleName), pName );
|
||||
}
|
||||
|
||||
static void *Sys_GetProcAddress( HMODULE hModule, const char *pName )
|
||||
{
|
||||
return GetProcAddress( hModule, pName );
|
||||
}
|
||||
|
||||
static bool Sys_IsDebuggerPresent()
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
static BOOL (*pfnIsDebuggerPresent)(VOID);
|
||||
static bool checked = false;
|
||||
if ( !checked )
|
||||
{
|
||||
checked = true;
|
||||
// We need to do this this way to work on win98/me without causing a run time .dll error (says Nick)
|
||||
// Win98/Me don't export this from the Kernel
|
||||
pfnIsDebuggerPresent = (BOOL (*)(VOID))Sys_GetProcAddress( "kernel32", "IsDebuggerPresent" );
|
||||
}
|
||||
|
||||
if ( pfnIsDebuggerPresent )
|
||||
{
|
||||
return (*pfnIsDebuggerPresent)() ? true : false;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
HMODULE Sys_LoadLibrary( const char *pLibraryName )
|
||||
{
|
||||
char str[1024];
|
||||
#if defined(_WIN32)
|
||||
const char *pModuleExtension = ".dll";
|
||||
const char *pModuleAddition = pModuleExtension;
|
||||
#elif _LINUX
|
||||
const char *pModuleExtension = ".so";
|
||||
const char *pModuleAddition = "_i486.so"; // if an extension is on the filename assume the i486 binary set
|
||||
#endif
|
||||
Q_strncpy(str, pLibraryName, sizeof(str));
|
||||
if ( !Q_stristr( str, pModuleExtension ) )
|
||||
{
|
||||
Q_strncat( str, pModuleAddition, sizeof(str) );
|
||||
}
|
||||
Q_FixSlashes( str );
|
||||
#ifdef _WIN32
|
||||
return LoadLibrary( str );
|
||||
#elif _LINUX
|
||||
return dlopen( str, RTLD_NOW );
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Loads a DLL/component from disk and returns a handle to it
|
||||
// Input : *pModuleName - filename of the component
|
||||
// Output : opaque handle to the module (hides system dependency)
|
||||
//-----------------------------------------------------------------------------
|
||||
CSysModule *Sys_LoadModule( const char *pModuleName )
|
||||
{
|
||||
// If using the Steam filesystem, either the DLL must be a minimum footprint
|
||||
// file in the depot (MFP) or a filesystem GetLocalCopy() call must be made
|
||||
// prior to the call to this routine.
|
||||
#ifndef _XBOX
|
||||
char szCwd[1024];
|
||||
#endif
|
||||
HMODULE hDLL = NULL;
|
||||
// if a full path wasn't passed in use the current working dir
|
||||
#ifndef _XBOX
|
||||
if ( !Q_IsAbsolutePath(pModuleName) ) // if a full path wasn't passed in
|
||||
{
|
||||
char szAbsoluteModuleName[1024];
|
||||
_getcwd( szCwd, sizeof( szCwd ) );
|
||||
if ( szCwd[ strlen( szCwd ) - 1 ] == '/' )
|
||||
szCwd[ strlen( szCwd ) - 1 ] = 0;
|
||||
Q_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName),"%s/bin/%s", szCwd, pModuleName );
|
||||
hDLL = Sys_LoadLibrary(szAbsoluteModuleName);
|
||||
}
|
||||
#endif
|
||||
if ( !hDLL )
|
||||
{
|
||||
// full path failed, let LoadLibrary() try to search the PATH now
|
||||
hDLL = Sys_LoadLibrary(pModuleName);
|
||||
|
||||
#if defined(_DEBUG) && !defined(_XBOX)
|
||||
if( !hDLL )
|
||||
{
|
||||
// So you can see what the error is in the debugger...
|
||||
#ifdef _WIN32
|
||||
char *lpMsgBuf;
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
LocalFree( (HLOCAL)lpMsgBuf );
|
||||
#else
|
||||
Error( "Failed to load %s: %s\n",pModuleName, dlerror() );
|
||||
#endif // _WIN32
|
||||
}
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
#ifndef _XBOX
|
||||
// If running in the debugger, assume debug binaries are okay, otherwise they must run with -allowdebug
|
||||
if ( hDLL &&
|
||||
!CommandLine()->FindParm( "-allowdebug" ) &&
|
||||
!Sys_IsDebuggerPresent() )
|
||||
{
|
||||
if ( Sys_GetProcAddress( hDLL, "BuiltDebug" ) )
|
||||
{
|
||||
Error( "Module %s is a debug build\n", pModuleName );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<CSysModule *>(hDLL);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Unloads a DLL/component from
|
||||
// Input : *pModuleName - filename of the component
|
||||
// Output : opaque handle to the module (hides system dependency)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Sys_UnloadModule( CSysModule *pModule )
|
||||
{
|
||||
if ( !pModule )
|
||||
return;
|
||||
|
||||
HMODULE hDLL = reinterpret_cast<HMODULE>(pModule);
|
||||
|
||||
#ifdef _WIN32
|
||||
FreeLibrary( hDLL );
|
||||
#elif defined(_LINUX)
|
||||
dlclose((void *)hDLL);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to a function, given a module
|
||||
// Input : module - windows HMODULE from Sys_LoadModule()
|
||||
// *pName - proc name
|
||||
// Output : factory for this module
|
||||
//-----------------------------------------------------------------------------
|
||||
CreateInterfaceFn Sys_GetFactory( CSysModule *pModule )
|
||||
{
|
||||
if ( !pModule )
|
||||
return NULL;
|
||||
|
||||
HMODULE hDLL = reinterpret_cast<HMODULE>(pModule);
|
||||
#ifdef _WIN32
|
||||
return reinterpret_cast<CreateInterfaceFn>(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME ));
|
||||
#elif defined(_LINUX)
|
||||
// Linux gives this error:
|
||||
//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory
|
||||
//(CSysModule *)) (const char *, int *)':
|
||||
//../public/interface.cpp:154: ISO C++ forbids casting between
|
||||
//pointer-to-function and pointer-to-object
|
||||
//
|
||||
// so lets get around it :)
|
||||
return (CreateInterfaceFn)(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME ));
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the instance of this module
|
||||
// Output : interface_instance_t
|
||||
//-----------------------------------------------------------------------------
|
||||
CreateInterfaceFn Sys_GetFactoryThis( void )
|
||||
{
|
||||
return CreateInterface;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the instance of the named module
|
||||
// Input : *pModuleName - name of the module
|
||||
// Output : interface_instance_t - instance of that module
|
||||
//-----------------------------------------------------------------------------
|
||||
CreateInterfaceFn Sys_GetFactory( const char *pModuleName )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return static_cast<CreateInterfaceFn>( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) );
|
||||
#elif defined(_LINUX)
|
||||
// see Sys_GetFactory( CSysModule *pModule ) for an explanation
|
||||
return (CreateInterfaceFn)( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get the interface for the specified module and version
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Sys_LoadInterface(
|
||||
const char *pModuleName,
|
||||
const char *pInterfaceVersionName,
|
||||
CSysModule **pOutModule,
|
||||
void **pOutInterface )
|
||||
{
|
||||
CSysModule *pMod = Sys_LoadModule( pModuleName );
|
||||
if ( !pMod )
|
||||
return false;
|
||||
|
||||
CreateInterfaceFn fn = Sys_GetFactory( pMod );
|
||||
if ( !fn )
|
||||
{
|
||||
Sys_UnloadModule( pMod );
|
||||
return false;
|
||||
}
|
||||
|
||||
*pOutInterface = fn( pInterfaceVersionName, NULL );
|
||||
if ( !( *pOutInterface ) )
|
||||
{
|
||||
Sys_UnloadModule( pMod );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pOutModule )
|
||||
*pOutModule = pMod;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLISH_DLL_SUBSYSTEM()
|
700
tier1/jobthread.cpp
Normal file
700
tier1/jobthread.cpp
Normal file
@ -0,0 +1,700 @@
|
||||
//========== Copyright <20> 2005, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#ifdef _XBOX
|
||||
#include "xbox/xbox_platform.h"
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#include "xbox/xbox_core.h"
|
||||
#else
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#endif // _WIN32
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/jobthread.h"
|
||||
|
||||
#include "tier1/utlvector.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define NO_THREADPOOL
|
||||
|
||||
#ifdef _LINUX
|
||||
#define NO_THREADPOOL
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NO_THREADPOOL
|
||||
class CThreadPool
|
||||
{
|
||||
public:
|
||||
CThreadPool()
|
||||
: m_pPendingJob( NULL ),
|
||||
m_Exit( true )
|
||||
{
|
||||
}
|
||||
|
||||
void Init( int nThreads, int stackSize, int priority, bool bDistribute )
|
||||
{
|
||||
while ( nThreads-- )
|
||||
{
|
||||
int iThread = m_Threads.AddToTail();
|
||||
m_IdleEvents.AddToTail();
|
||||
m_Threads[iThread] = CreateSimpleThread( PoolThreadFunc, this, stackSize );
|
||||
m_IdleEvents[iThread].Wait();
|
||||
}
|
||||
|
||||
if ( bDistribute )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
void Execute( CAsyncJob *pJob )
|
||||
{
|
||||
if ( m_Threads.Count() )
|
||||
{
|
||||
pJob->AddRef();
|
||||
m_pPendingJob = pJob;
|
||||
|
||||
m_JobAccepted.Reset();
|
||||
m_JobAvailable.Set();
|
||||
m_JobAccepted.Wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
pJob->TryExecute();
|
||||
}
|
||||
}
|
||||
|
||||
void WaitForIdle()
|
||||
{
|
||||
WaitForMultipleObjects( m_IdleEvents.Count(), (HANDLE *)m_IdleEvents.Base(), TRUE, 60000 );
|
||||
}
|
||||
|
||||
void Term()
|
||||
{
|
||||
m_Exit.Set();
|
||||
WaitForMultipleObjects( m_Threads.Count(), (HANDLE *)m_Threads.Base(), TRUE, 60000 );
|
||||
}
|
||||
|
||||
private:
|
||||
static unsigned PoolThreadFunc( void *pParam )
|
||||
{
|
||||
CThreadPool *pOwner = (CThreadPool *)pParam;
|
||||
int iThread = pOwner->m_Threads.Count() - 1;
|
||||
pOwner->m_IdleEvents[iThread].Set();
|
||||
|
||||
HANDLE waitHandles[] =
|
||||
{
|
||||
pOwner->m_JobAvailable,
|
||||
pOwner->m_Exit
|
||||
};
|
||||
|
||||
DWORD waitResult;
|
||||
|
||||
while ( ( waitResult = WaitForMultipleObjects( ARRAYSIZE(waitHandles), waitHandles, FALSE, INFINITE ) ) != WAIT_FAILED )
|
||||
{
|
||||
switch ( waitResult - WAIT_OBJECT_0 )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
pOwner->m_IdleEvents[iThread].Reset();
|
||||
CAsyncJob *pJob = pOwner->m_pPendingJob;
|
||||
pOwner->m_pPendingJob = NULL;
|
||||
pOwner->m_JobAccepted.Set();
|
||||
|
||||
pJob->TryExecute();
|
||||
pJob->Release();
|
||||
|
||||
pOwner->m_IdleEvents[iThread].Set();
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
CAsyncJob *m_pPendingJob;
|
||||
|
||||
CThreadEvent m_JobAvailable;
|
||||
CThreadEvent m_JobAccepted;
|
||||
CThreadEvent m_Exit;
|
||||
CInterlockedInt m_IdleCount;
|
||||
|
||||
CUtlVector<ThreadHandle_t> m_Threads;
|
||||
CUtlVector<CThreadManualEvent> m_IdleEvents;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class CThreadPool
|
||||
{
|
||||
public:
|
||||
void Init( int nThreads, int stackSize, int priority, bool bDistribute )
|
||||
{
|
||||
}
|
||||
|
||||
void Execute( CAsyncJob *pJob )
|
||||
{
|
||||
pJob->TryExecute();
|
||||
}
|
||||
|
||||
void WaitForIdle()
|
||||
{
|
||||
}
|
||||
|
||||
void Term()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
CThreadPool g_TestThreadPool;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CAsyncJobFuliller
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CAsyncJobFuliller::CAsyncJobFuliller( int maxJobs )
|
||||
: m_JobSignal( true ),
|
||||
#ifdef _WIN32
|
||||
m_PutSemaphore( maxJobs, maxJobs ),
|
||||
m_bUseSemaphore( true ),
|
||||
#elif _LINUX
|
||||
m_bUseSemaphore( false ), // no semaphore support
|
||||
#endif
|
||||
m_nSuspend( 0 )
|
||||
{
|
||||
Assert( maxJobs < USHRT_MAX - 1 );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
CAsyncJobFuliller::CAsyncJobFuliller()
|
||||
: m_JobSignal( true ),
|
||||
#ifdef _WIN32
|
||||
m_PutSemaphore( 0, 0 ),
|
||||
#endif
|
||||
m_bUseSemaphore( false ),
|
||||
m_nSuspend( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
CAsyncJobFuliller::~CAsyncJobFuliller()
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
inline void CAsyncJobFuliller::WaitPut()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( m_bUseSemaphore )
|
||||
m_PutSemaphore.Wait();
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
inline void CAsyncJobFuliller::ReleasePut()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( m_bUseSemaphore )
|
||||
m_PutSemaphore.Release();
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Pause/resume processing jobs
|
||||
//---------------------------------------------------------
|
||||
int CAsyncJobFuliller::SuspendExecution()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( !ThreadInMainThread() )
|
||||
{
|
||||
Assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If not already suspended
|
||||
if ( m_nSuspend == 0 )
|
||||
{
|
||||
// Make sure state is correct
|
||||
int curCount = Suspend();
|
||||
Resume();
|
||||
Assert( curCount == 0 );
|
||||
|
||||
if ( curCount == 0 )
|
||||
{
|
||||
CallWorker( AF_SUSPEND );
|
||||
|
||||
// Because worker must signal before suspending, we could reach
|
||||
// here with the thread not actually suspended
|
||||
while ( Suspend() == 0 )
|
||||
{
|
||||
Resume();
|
||||
ThreadSleep();
|
||||
}
|
||||
Resume();
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
curCount = Suspend();
|
||||
Resume();
|
||||
Assert( curCount > 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_nSuspend++;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
int CAsyncJobFuliller::ResumeExecution()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( !ThreadInMainThread() )
|
||||
{
|
||||
Assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
AssertMsg( m_nSuspend >= 1, "Attempted resume when not suspended");
|
||||
int result = m_nSuspend--;
|
||||
if (m_nSuspend == 0 )
|
||||
{
|
||||
Resume();
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Add a job to the queue
|
||||
//---------------------------------------------------------
|
||||
|
||||
void CAsyncJobFuliller::AddJob( CAsyncJob *pJob )
|
||||
{
|
||||
if ( !pJob )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
BoostPriority();
|
||||
|
||||
// If queue is full, wait for worker to get something from our queue
|
||||
WaitPut();
|
||||
|
||||
m_mutex.Lock();
|
||||
|
||||
pJob->AddRef();
|
||||
|
||||
unsigned i = m_queue.Tail();
|
||||
int priority = pJob->GetPriority();
|
||||
|
||||
while ( i != m_queue.InvalidIndex() && priority > m_queue[i]->GetPriority() )
|
||||
{
|
||||
i = m_queue.Previous( i );
|
||||
}
|
||||
|
||||
if ( i != m_queue.InvalidIndex() )
|
||||
{
|
||||
pJob->m_queueID = m_queue.InsertAfter( i, pJob );
|
||||
}
|
||||
else
|
||||
{
|
||||
pJob->m_queueID = m_queue.AddToHead( pJob );
|
||||
}
|
||||
|
||||
pJob->m_pFulfiller = this;
|
||||
pJob->m_status = ASYNC_STATUS_PENDING;
|
||||
|
||||
if ( m_queue.Count() == 1 )
|
||||
{
|
||||
// Release worker to remove an object from our queue
|
||||
m_JobSignal.Set();
|
||||
}
|
||||
|
||||
m_mutex.Unlock();
|
||||
#else
|
||||
pJob->Execute();
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Remove a job from the queue
|
||||
//---------------------------------------------------------
|
||||
|
||||
bool CAsyncJobFuliller::RemoveJob( CAsyncJob *pJob )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( !pJob )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AUTO_LOCK( m_mutex );
|
||||
|
||||
if ( !m_queue.IsValidIndex( pJob->m_queueID ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Take the job out
|
||||
m_queue.Remove( pJob->m_queueID );
|
||||
pJob->m_queueID = m_queue.InvalidIndex();
|
||||
pJob->m_pFulfiller = NULL;
|
||||
pJob->Release();
|
||||
|
||||
// Release master to put more in
|
||||
ReleasePut();
|
||||
|
||||
// If we're transitioning to empty...
|
||||
if ( m_queue.Count() == 0 )
|
||||
{
|
||||
// Block the worker until there's something to do...
|
||||
m_JobSignal.Reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Execute to a specified priority
|
||||
//---------------------------------------------------------
|
||||
|
||||
int CAsyncJobFuliller::ExecuteToPriority( AsyncJobPriority_t iToPriority )
|
||||
{
|
||||
int nExecuted = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( CThread::GetCurrentCThread() != this )
|
||||
{
|
||||
SuspendExecution();
|
||||
}
|
||||
|
||||
if ( m_queue.Count() )
|
||||
{
|
||||
CAsyncJob *pJob = NULL;
|
||||
|
||||
while ( ( pJob = GetJob() ) != NULL )
|
||||
{
|
||||
if ( pJob->GetPriority() >= iToPriority )
|
||||
{
|
||||
pJob->Execute();
|
||||
pJob->Release();
|
||||
pJob = NULL;
|
||||
nExecuted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Extracted one of lower priority, so reinsert it...
|
||||
if ( pJob )
|
||||
{
|
||||
AddJob( pJob/*, true !!!!!!!! */ );
|
||||
pJob->Release();
|
||||
}
|
||||
}
|
||||
|
||||
if ( CThread::GetCurrentCThread() != this )
|
||||
{
|
||||
ResumeExecution();
|
||||
}
|
||||
#endif
|
||||
return nExecuted;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
|
||||
int CAsyncJobFuliller::AbortAll()
|
||||
{
|
||||
int nExecuted = 0;
|
||||
#ifdef _WIN32
|
||||
if ( CThread::GetCurrentCThread() != this )
|
||||
{
|
||||
SuspendExecution();
|
||||
}
|
||||
|
||||
if ( m_queue.Count() )
|
||||
{
|
||||
CAsyncJob *pJob = NULL;
|
||||
|
||||
while ( ( pJob = GetJob() ) != NULL )
|
||||
{
|
||||
pJob->Abort();
|
||||
pJob->Release();
|
||||
}
|
||||
}
|
||||
|
||||
if ( CThread::GetCurrentCThread() != this )
|
||||
{
|
||||
ResumeExecution();
|
||||
}
|
||||
#endif
|
||||
|
||||
return nExecuted;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get the next job from the queue
|
||||
//---------------------------------------------------------
|
||||
|
||||
CAsyncJob *CAsyncJobFuliller::GetJob()
|
||||
{
|
||||
CAsyncJob *pReturn = NULL;
|
||||
#ifdef _WIN32
|
||||
m_mutex.Lock();
|
||||
unsigned i = m_queue.Head();
|
||||
|
||||
if ( i != m_queue.InvalidIndex() )
|
||||
{
|
||||
pReturn = m_queue[i];
|
||||
pReturn->AddRef();
|
||||
RemoveJob(pReturn);
|
||||
}
|
||||
|
||||
m_mutex.Unlock();
|
||||
#endif
|
||||
return pReturn;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// CAsyncJobFuliller thread functions
|
||||
//---------------------------------------------------------
|
||||
|
||||
bool CAsyncJobFuliller::Start( unsigned nBytesStack )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( CWorkerThread::Start( nBytesStack ) )
|
||||
{
|
||||
BoostPriority();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
int CAsyncJobFuliller::Run()
|
||||
{
|
||||
#if defined( _WIN32 )
|
||||
enum FulfillerEvent_t
|
||||
{
|
||||
CALL_FROM_MASTER,
|
||||
JOB_REQUEST
|
||||
};
|
||||
|
||||
g_TestThreadPool.Init( 4, 0, 2, false );
|
||||
|
||||
// Wait for either a call from the master thread, or an item in the queue...
|
||||
DWORD waitResult;
|
||||
bool bExit = false;
|
||||
HANDLE waitHandles[2];
|
||||
|
||||
waitHandles[CALL_FROM_MASTER] = GetCallHandle();
|
||||
waitHandles[JOB_REQUEST] = GetJobSignalHandle();
|
||||
|
||||
while (!bExit &&
|
||||
( waitResult = WaitForMultipleObjects( 2, waitHandles, FALSE, INFINITE ) ) != WAIT_FAILED )
|
||||
{
|
||||
switch ( waitResult - WAIT_OBJECT_0 )
|
||||
{
|
||||
// It's a call from the master thread...
|
||||
case CALL_FROM_MASTER:
|
||||
{
|
||||
switch ( GetCallParam() )
|
||||
{
|
||||
case AF_EXIT:
|
||||
Reply( true );
|
||||
bExit = TRUE;
|
||||
break;
|
||||
|
||||
case AF_SUSPEND:
|
||||
g_TestThreadPool.WaitForIdle();
|
||||
Reply( true );
|
||||
Suspend();
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg( 0, "Unknown call async fulfiller" );
|
||||
Reply( false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, if there's a read request to service...
|
||||
case JOB_REQUEST:
|
||||
{
|
||||
// Get the request
|
||||
CAsyncJob *pJob;
|
||||
|
||||
while ( ( pJob = GetJob() ) != NULL )
|
||||
{
|
||||
// Job can be NULL if the main thread may have preempted and fulfilled
|
||||
// the job on its own.
|
||||
g_TestThreadPool.Execute( pJob );
|
||||
pJob->Release();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
AssertMsg( 0, "There was nothing to do!" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
g_TestThreadPool.Term();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CAsyncJob
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
AsyncStatus_t CAsyncJob::Execute()
|
||||
{
|
||||
AUTO_LOCK( m_mutex );
|
||||
AddRef();
|
||||
|
||||
AsyncStatus_t result;
|
||||
|
||||
switch (m_status)
|
||||
{
|
||||
case ASYNC_STATUS_UNSERVICED:
|
||||
case ASYNC_STATUS_PENDING:
|
||||
{
|
||||
if ( m_pFulfiller ) // Jobs can exist on thier own
|
||||
{
|
||||
CAutoLock autoLock( m_pFulfiller->GetQueueLock() );
|
||||
if ( m_pFulfiller )
|
||||
{
|
||||
m_pFulfiller->RemoveJob( this );
|
||||
}
|
||||
}
|
||||
|
||||
// Service it
|
||||
m_status = ASYNC_STATUS_INPROGRESS;
|
||||
ThreadSleep( 0 );
|
||||
result = m_status = DoExecute();
|
||||
DoCleanup();
|
||||
ThreadSleep( 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case ASYNC_STATUS_INPROGRESS:
|
||||
AssertMsg(0, "Mutex Should have protected use while processing");
|
||||
// fall through...
|
||||
|
||||
case ASYNC_OK:
|
||||
case ASYNC_STATUS_ABORTED:
|
||||
result = m_status;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg( m_status < ASYNC_OK, "Unknown async job state");
|
||||
result = m_status;
|
||||
}
|
||||
|
||||
Release();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
AsyncStatus_t CAsyncJob::TryExecute()
|
||||
{
|
||||
// TryLock() would only fail if another thread has entered
|
||||
// Execute() or Abort()
|
||||
if ( TryLock() )
|
||||
{
|
||||
// ...service the request
|
||||
Execute();
|
||||
Unlock();
|
||||
}
|
||||
return m_status;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
AsyncStatus_t CAsyncJob::Abort( bool bDiscard )
|
||||
{
|
||||
AUTO_LOCK(m_mutex);
|
||||
AddRef();
|
||||
|
||||
AsyncStatus_t result;
|
||||
|
||||
switch (m_status)
|
||||
{
|
||||
case ASYNC_STATUS_UNSERVICED:
|
||||
case ASYNC_STATUS_PENDING:
|
||||
{
|
||||
if ( m_pFulfiller ) // Jobs can exist on thier own
|
||||
{
|
||||
CAutoLock autoLock( m_pFulfiller->GetQueueLock() );
|
||||
if ( m_pFulfiller )
|
||||
{
|
||||
m_pFulfiller->RemoveJob( this );
|
||||
}
|
||||
}
|
||||
|
||||
result = m_status = DoAbort( bDiscard );
|
||||
if ( bDiscard )
|
||||
DoCleanup();
|
||||
}
|
||||
break;
|
||||
|
||||
case ASYNC_STATUS_ABORTED:
|
||||
case ASYNC_STATUS_INPROGRESS:
|
||||
case ASYNC_OK:
|
||||
result = m_status;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg( m_status < ASYNC_OK, "Unknown async job state");
|
||||
result = m_status;
|
||||
}
|
||||
|
||||
Release();
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
310
tier1/mempool.cpp
Normal file
310
tier1/mempool.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "mempool.h"
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include "tier0/dbg.h"
|
||||
#include <ctype.h>
|
||||
#include "vstdlib/strtools.h"
|
||||
#include "minmax.h" // max()
|
||||
|
||||
// Should be last include
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
MemoryPoolReportFunc_t CMemoryPool::g_ReportFunc = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Error reporting... (debug only)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CMemoryPool::SetErrorReportFunc( MemoryPoolReportFunc_t func )
|
||||
{
|
||||
g_ReportFunc = func;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CMemoryPool::CMemoryPool(int blockSize, int numElements, int growMode, const char *pszAllocOwner)
|
||||
{
|
||||
#ifdef _XBOX
|
||||
if( numElements > 0 && growMode != GROW_NONE )
|
||||
{
|
||||
numElements = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_BlockSize = blockSize < sizeof(void*) ? sizeof(void*) : blockSize;
|
||||
m_BlocksPerBlob = numElements;
|
||||
m_PeakAlloc = 0;
|
||||
m_GrowMode = growMode;
|
||||
Init();
|
||||
if ( !pszAllocOwner )
|
||||
pszAllocOwner = __FILE__;
|
||||
m_pszAllocOwner = pszAllocOwner;
|
||||
AddNewBlob();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Frees the memory contained in the mempool, and invalidates it for
|
||||
// any further use.
|
||||
// Input : *memPool - the mempool to shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
CMemoryPool::~CMemoryPool()
|
||||
{
|
||||
if (m_BlocksAllocated > 0)
|
||||
{
|
||||
ReportLeaks();
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resets the pool
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMemoryPool::Init()
|
||||
{
|
||||
m_NumBlobs = 0;
|
||||
m_BlocksAllocated = 0;
|
||||
m_pHeadOfFreeList = 0;
|
||||
m_BlobHead.m_pNext = m_BlobHead.m_pPrev = &m_BlobHead;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frees everything
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMemoryPool::Clear()
|
||||
{
|
||||
// Free everything..
|
||||
CBlob *pNext;
|
||||
for( CBlob *pCur = m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur = pNext )
|
||||
{
|
||||
pNext = pCur->m_pNext;
|
||||
free( pCur );
|
||||
}
|
||||
Init();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reports memory leaks
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CMemoryPool::ReportLeaks()
|
||||
{
|
||||
if (!g_ReportFunc)
|
||||
return;
|
||||
|
||||
g_ReportFunc("Memory leak: mempool blocks left in memory: %d\n", m_BlocksAllocated);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// walk and destroy the free list so it doesn't intefere in the scan
|
||||
while (m_pHeadOfFreeList != NULL)
|
||||
{
|
||||
void *next = *((void**)m_pHeadOfFreeList);
|
||||
memset(m_pHeadOfFreeList, 0, m_BlockSize);
|
||||
m_pHeadOfFreeList = next;
|
||||
}
|
||||
|
||||
g_ReportFunc("Dumping memory: \'");
|
||||
|
||||
for( CBlob *pCur=m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur=pCur->m_pNext )
|
||||
{
|
||||
// scan the memory block and dump the leaks
|
||||
char *scanPoint = (char *)pCur->m_Data;
|
||||
char *scanEnd = pCur->m_Data + pCur->m_NumBytes;
|
||||
bool needSpace = false;
|
||||
|
||||
while (scanPoint < scanEnd)
|
||||
{
|
||||
// search for and dump any strings
|
||||
if ((unsigned)(*scanPoint + 1) <= 256 && isprint(*scanPoint))
|
||||
{
|
||||
g_ReportFunc("%c", *scanPoint);
|
||||
needSpace = true;
|
||||
}
|
||||
else if (needSpace)
|
||||
{
|
||||
needSpace = false;
|
||||
g_ReportFunc(" ");
|
||||
}
|
||||
|
||||
scanPoint++;
|
||||
}
|
||||
}
|
||||
|
||||
g_ReportFunc("\'\n");
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMemoryPool::AddNewBlob()
|
||||
{
|
||||
MEM_ALLOC_CREDIT_(m_pszAllocOwner);
|
||||
|
||||
int sizeMultiplier;
|
||||
|
||||
if( m_GrowMode == GROW_SLOW )
|
||||
{
|
||||
sizeMultiplier = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_GrowMode == GROW_NONE )
|
||||
{
|
||||
// Can only have one allocation when we're in this mode
|
||||
if( m_NumBlobs != 0 )
|
||||
{
|
||||
Assert( !"CMemoryPool::AddNewBlob: mode == GROW_NONE" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// GROW_FAST and GROW_NONE use this.
|
||||
sizeMultiplier = m_NumBlobs + 1;
|
||||
}
|
||||
|
||||
// maybe use something other than malloc?
|
||||
int nElements = m_BlocksPerBlob * sizeMultiplier;
|
||||
int blobSize = m_BlockSize * nElements;
|
||||
CBlob *pBlob = (CBlob*)malloc( sizeof(CBlob) + blobSize - 1 );
|
||||
Assert( pBlob );
|
||||
|
||||
// Link it in at the end of the blob list.
|
||||
pBlob->m_NumBytes = blobSize;
|
||||
pBlob->m_pNext = &m_BlobHead;
|
||||
pBlob->m_pPrev = pBlob->m_pNext->m_pPrev;
|
||||
pBlob->m_pNext->m_pPrev = pBlob->m_pPrev->m_pNext = pBlob;
|
||||
|
||||
// setup the free list
|
||||
m_pHeadOfFreeList = pBlob->m_Data;
|
||||
Assert (m_pHeadOfFreeList);
|
||||
|
||||
void **newBlob = (void**)m_pHeadOfFreeList;
|
||||
for (int j = 0; j < nElements-1; j++)
|
||||
{
|
||||
newBlob[0] = (char*)newBlob + m_BlockSize;
|
||||
newBlob = (void**)newBlob[0];
|
||||
}
|
||||
|
||||
// null terminate list
|
||||
newBlob[0] = NULL;
|
||||
m_NumBlobs++;
|
||||
}
|
||||
|
||||
|
||||
void* CMemoryPool::Alloc()
|
||||
{
|
||||
return Alloc( m_BlockSize );
|
||||
}
|
||||
|
||||
|
||||
void* CMemoryPool::AllocZero()
|
||||
{
|
||||
return AllocZero( m_BlockSize );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Allocs a single block of memory from the pool.
|
||||
// Input : amount -
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CMemoryPool::Alloc( unsigned int amount )
|
||||
{
|
||||
void *returnBlock;
|
||||
|
||||
if ( amount > (unsigned int)m_BlockSize )
|
||||
return NULL;
|
||||
|
||||
if( !m_pHeadOfFreeList )
|
||||
{
|
||||
// returning NULL is fine in GROW_NONE
|
||||
if( m_GrowMode == GROW_NONE )
|
||||
{
|
||||
//Assert( !"CMemoryPool::Alloc: tried to make new blob with GROW_NONE" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// overflow
|
||||
AddNewBlob();
|
||||
|
||||
// still failure, error out
|
||||
if( !m_pHeadOfFreeList )
|
||||
{
|
||||
Assert( !"CMemoryPool::Alloc: ran out of memory" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
m_BlocksAllocated++;
|
||||
m_PeakAlloc = max(m_PeakAlloc, m_BlocksAllocated);
|
||||
|
||||
returnBlock = m_pHeadOfFreeList;
|
||||
|
||||
// move the pointer the next block
|
||||
m_pHeadOfFreeList = *((void**)m_pHeadOfFreeList);
|
||||
|
||||
return returnBlock;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Allocs a single block of memory from the pool, zeroes the memory before returning
|
||||
// Input : amount -
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CMemoryPool::AllocZero( unsigned int amount )
|
||||
{
|
||||
void *mem = Alloc( amount );
|
||||
if ( mem )
|
||||
{
|
||||
V_memset( mem, 0x00, amount );
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Frees a block of memory
|
||||
// Input : *memBlock - the memory to free
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMemoryPool::Free( void *memBlock )
|
||||
{
|
||||
if ( !memBlock )
|
||||
return; // trying to delete NULL pointer, ignore
|
||||
|
||||
#ifdef _DEBUG
|
||||
// check to see if the memory is from the allocated range
|
||||
bool bOK = false;
|
||||
for( CBlob *pCur=m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur=pCur->m_pNext )
|
||||
{
|
||||
if (memBlock >= pCur->m_Data && (char*)memBlock < (pCur->m_Data + pCur->m_NumBytes))
|
||||
{
|
||||
bOK = true;
|
||||
}
|
||||
}
|
||||
Assert (bOK);
|
||||
#endif // _DEBUG
|
||||
|
||||
#ifdef _DEBUG
|
||||
// invalidate the memory
|
||||
memset( memBlock, 0xDD, m_BlockSize );
|
||||
#endif
|
||||
|
||||
m_BlocksAllocated--;
|
||||
|
||||
// make the block point to the first item in the list
|
||||
*((void**)memBlock) = m_pHeadOfFreeList;
|
||||
|
||||
// the list head is now the new block
|
||||
m_pHeadOfFreeList = memBlock;
|
||||
}
|
||||
|
||||
|
275
tier1/memstack.cpp
Normal file
275
tier1/memstack.cpp
Normal file
@ -0,0 +1,275 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if !defined(_XBOX)
|
||||
#define WIN_32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#define VA_COMMIT_FLAGS MEM_COMMIT
|
||||
#else
|
||||
#include <xtl.h>
|
||||
#define VA_COMMIT_FLAGS (MEM_COMMIT|MEM_NOZERO)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "memstack.h"
|
||||
#include "utlmap.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
MEMALLOC_DEFINE_EXTERNAL_TRACKING(CMemoryStack);
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
template <typename T>
|
||||
inline T MemAlign( T val, unsigned alignment )
|
||||
{
|
||||
return (T)( ( (unsigned)val + alignment - 1 ) & ~( alignment - 1 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CMemoryStack::CMemoryStack()
|
||||
: m_pBase( NULL ),
|
||||
m_pNextAlloc( NULL ),
|
||||
m_pAllocLimit( NULL ),
|
||||
m_pCommitLimit( NULL ),
|
||||
m_alignment( 16 ),
|
||||
#if defined(_WIN32)
|
||||
m_commitSize( 0 ),
|
||||
m_minCommit( 0 ),
|
||||
#endif
|
||||
m_maxSize( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
CMemoryStack::~CMemoryStack()
|
||||
{
|
||||
if ( m_pBase )
|
||||
Term();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
bool CMemoryStack::Init( unsigned maxSize, unsigned commitSize, unsigned initialCommit, unsigned alignment )
|
||||
{
|
||||
Assert( !m_pBase );
|
||||
|
||||
m_maxSize = maxSize;
|
||||
m_alignment = MemAlign( alignment, 4 );
|
||||
|
||||
Assert( m_alignment == alignment );
|
||||
Assert( m_maxSize > 0 );
|
||||
|
||||
#if defined(_WIN32)
|
||||
if ( commitSize != 0 )
|
||||
{
|
||||
m_commitSize = commitSize;
|
||||
}
|
||||
|
||||
unsigned pageSize;
|
||||
|
||||
#ifndef _XBOX
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetSystemInfo(&sysInfo);
|
||||
|
||||
Assert( !( sysInfo.dwPageSize & (sysInfo.dwPageSize-1)) );
|
||||
pageSize = sysInfo.dwPageSize;
|
||||
#else
|
||||
pageSize = 4096;
|
||||
#endif
|
||||
|
||||
if ( m_commitSize == 0 )
|
||||
{
|
||||
m_commitSize = pageSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_commitSize = MemAlign( m_commitSize, pageSize );
|
||||
}
|
||||
|
||||
m_maxSize = MemAlign( m_maxSize, m_commitSize );
|
||||
|
||||
Assert( m_maxSize % pageSize == 0 && m_commitSize % pageSize == 0 && m_commitSize <= m_maxSize );
|
||||
|
||||
m_pBase = (unsigned char *)VirtualAlloc( NULL, m_maxSize, MEM_RESERVE, PAGE_NOACCESS );
|
||||
Assert( m_pBase );
|
||||
m_pCommitLimit = m_pNextAlloc = m_pBase;
|
||||
|
||||
if ( initialCommit )
|
||||
{
|
||||
initialCommit = MemAlign( initialCommit, m_commitSize );
|
||||
Assert( initialCommit < m_maxSize );
|
||||
if ( !VirtualAlloc( m_pCommitLimit, initialCommit, VA_COMMIT_FLAGS, PAGE_READWRITE ) )
|
||||
return false;
|
||||
m_minCommit = initialCommit;
|
||||
m_pCommitLimit += initialCommit;
|
||||
MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() );
|
||||
}
|
||||
|
||||
#else
|
||||
m_pBase = new unsigned char[m_maxSize];
|
||||
m_pNextAlloc = m_pBase;
|
||||
m_pCommitLimit = m_pBase + m_maxSize;
|
||||
#endif
|
||||
|
||||
m_pAllocLimit = m_pBase + m_maxSize;
|
||||
|
||||
return ( m_pBase != NULL );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CMemoryStack::Term()
|
||||
{
|
||||
FreeAll();
|
||||
if ( m_pBase )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
VirtualFree( m_pBase, 0, MEM_RELEASE );
|
||||
#else
|
||||
delete m_pBase;
|
||||
#endif
|
||||
m_pBase = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
int CMemoryStack::GetSize()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return m_pCommitLimit - m_pBase;
|
||||
#else
|
||||
return m_maxSize;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void *CMemoryStack::Alloc( unsigned bytes, const char *pszName )
|
||||
{
|
||||
Assert( m_pBase );
|
||||
|
||||
if ( !bytes )
|
||||
bytes = 1;
|
||||
|
||||
bytes = MemAlign( bytes, m_alignment );
|
||||
|
||||
void *pResult = m_pNextAlloc;
|
||||
m_pNextAlloc += bytes;
|
||||
|
||||
if ( m_pNextAlloc > m_pCommitLimit )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
unsigned char * pNewCommitLimit = MemAlign( m_pNextAlloc, m_commitSize );
|
||||
unsigned commitSize = pNewCommitLimit - m_pCommitLimit;
|
||||
|
||||
MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() );
|
||||
|
||||
Assert( m_pCommitLimit + commitSize < m_pAllocLimit );
|
||||
if ( !VirtualAlloc( m_pCommitLimit, commitSize, VA_COMMIT_FLAGS, PAGE_READWRITE ) )
|
||||
{
|
||||
Assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
m_pCommitLimit = pNewCommitLimit;
|
||||
|
||||
MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() );
|
||||
#else
|
||||
Assert( 0 );
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
memset( pResult, 0, bytes );
|
||||
|
||||
return pResult;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
MemoryStackMark_t CMemoryStack::GetCurrentAllocPoint()
|
||||
{
|
||||
return ( m_pNextAlloc - m_pBase );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CMemoryStack::FreeToAllocPoint( MemoryStackMark_t mark )
|
||||
{
|
||||
void *pAllocPoint = m_pBase + mark;
|
||||
Assert( pAllocPoint >= m_pBase && pAllocPoint <= m_pNextAlloc );
|
||||
|
||||
if ( pAllocPoint >= m_pBase && pAllocPoint < m_pNextAlloc )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
unsigned char *pDecommitPoint = MemAlign( (unsigned char *)pAllocPoint, m_commitSize );
|
||||
|
||||
if ( pDecommitPoint < m_pBase + m_minCommit )
|
||||
{
|
||||
pDecommitPoint = m_pBase + m_minCommit;
|
||||
}
|
||||
|
||||
unsigned decommitSize = m_pCommitLimit - pDecommitPoint;
|
||||
|
||||
if ( decommitSize > 0 )
|
||||
{
|
||||
MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() );
|
||||
|
||||
VirtualFree( pDecommitPoint, decommitSize, MEM_DECOMMIT );
|
||||
m_pCommitLimit = pDecommitPoint;
|
||||
|
||||
if ( mark > 0 )
|
||||
{
|
||||
MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
m_pNextAlloc = (unsigned char *)pAllocPoint;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CMemoryStack::FreeAll()
|
||||
{
|
||||
if ( m_pBase && m_pCommitLimit - m_pBase > 0 )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() );
|
||||
|
||||
VirtualFree( m_pBase, m_pCommitLimit - m_pBase, MEM_DECOMMIT );
|
||||
m_pCommitLimit = m_pBase;
|
||||
#endif
|
||||
m_pNextAlloc = m_pBase;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CMemoryStack::Access( void **ppRegion, unsigned *pBytes )
|
||||
{
|
||||
*ppRegion = m_pBase;
|
||||
*pBytes = ( m_pNextAlloc - m_pBase);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CMemoryStack::PrintContents()
|
||||
{
|
||||
Msg( "Total used memory: %d", GetUsed() );
|
||||
Msg( "Total committed memory: %d", GetSize() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
270
tier1/processor_detect.cpp
Normal file
270
tier1/processor_detect.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: win32 dependant ASM code for CPU capability detection
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifdef _LINUX
|
||||
#include "processor_detect_linux.cpp"
|
||||
#elif _WIN32
|
||||
|
||||
#pragma optimize( "", off )
|
||||
#pragma warning( disable: 4800 ) //'int' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
|
||||
// stuff from windows.h
|
||||
#ifndef EXCEPTION_EXECUTE_HANDLER
|
||||
#define EXCEPTION_EXECUTE_HANDLER 1
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
bool CheckMMXTechnology(void)
|
||||
{
|
||||
int retval = true;
|
||||
unsigned int RegEDX = 0;
|
||||
|
||||
#ifdef CPUID
|
||||
_asm pushad;
|
||||
#endif
|
||||
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
#ifdef CPUID
|
||||
xor edx, edx // Clue the compiler that EDX is about to be used.
|
||||
#endif
|
||||
mov eax, 1 // set up CPUID to return processor version and features
|
||||
// 0 = vendor string, 1 = version info, 2 = cache info
|
||||
CPUID // code bytes = 0fh, 0a2h
|
||||
mov RegEDX, edx // features returned in edx
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
|
||||
// If CPUID not supported, then certainly no MMX extensions.
|
||||
if (retval)
|
||||
{
|
||||
if (RegEDX & 0x800000) // bit 23 is set for MMX technology
|
||||
{
|
||||
__try
|
||||
{
|
||||
// try executing the MMX instruction "emms"
|
||||
_asm EMMS
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
retval = false; // processor supports CPUID but does not support MMX technology
|
||||
|
||||
// if retval == 0 here, it means the processor has MMX technology but
|
||||
// floating-point emulation is on; so MMX technology is unavailable
|
||||
}
|
||||
|
||||
#ifdef CPUID
|
||||
_asm popad;
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
// --------------------------------------------------------------------------
|
||||
bool CheckSSETechnology(void)
|
||||
{
|
||||
int retval = true;
|
||||
unsigned int RegEDX = 0;
|
||||
|
||||
#ifdef CPUID
|
||||
_asm pushad;
|
||||
#endif
|
||||
|
||||
// Do we have support for the CPUID function?
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
#ifdef CPUID
|
||||
xor edx, edx // Clue the compiler that EDX is about to be used.
|
||||
#endif
|
||||
mov eax, 1 // set up CPUID to return processor version and features
|
||||
// 0 = vendor string, 1 = version info, 2 = cache info
|
||||
CPUID // code bytes = 0fh, 0a2h
|
||||
mov RegEDX, edx // features returned in edx
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
|
||||
// If CPUID not supported, then certainly no SSE extensions.
|
||||
if (retval)
|
||||
{
|
||||
// Do we have support for SSE in this processor?
|
||||
if ( RegEDX & 0x2000000L ) // bit 25 is set for SSE technology
|
||||
{
|
||||
// Make sure that SSE is supported by executing an inline SSE instruction
|
||||
|
||||
// BUGBUG, FIXME - Visual C Version 6.0 does not support SSE inline code YET (No macros from Intel either)
|
||||
// Fix this if VC7 supports inline SSE instructinons like "xorps" as shown below.
|
||||
#if 1
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
// Attempt execution of a SSE instruction to make sure OS supports SSE FPU context switches
|
||||
xorps xmm0, xmm0
|
||||
// This will work on Win2k+ (Including masking SSE FPU exception to "normalized" values)
|
||||
// This will work on Win98+ (But no "masking" of FPU exceptions provided)
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
#endif
|
||||
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
retval = false;
|
||||
}
|
||||
#ifdef CPUID
|
||||
_asm popad;
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
bool CheckSSE2Technology(void)
|
||||
{
|
||||
int retval = true;
|
||||
unsigned int RegEDX = 0;
|
||||
|
||||
#ifdef CPUID
|
||||
_asm pushad;
|
||||
#endif
|
||||
|
||||
// Do we have support for the CPUID function?
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
#ifdef CPUID
|
||||
xor edx, edx // Clue the compiler that EDX is about to be used.
|
||||
#endif
|
||||
mov eax, 1 // set up CPUID to return processor version and features
|
||||
// 0 = vendor string, 1 = version info, 2 = cache info
|
||||
CPUID // code bytes = 0fh, 0a2h
|
||||
mov RegEDX, edx // features returned in edx
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
|
||||
// If CPUID not supported, then certainly no SSE extensions.
|
||||
if (retval)
|
||||
{
|
||||
// Do we have support for SSE in this processor?
|
||||
if ( RegEDX & 0x04000000 ) // bit 26 is set for SSE2 technology
|
||||
{
|
||||
// Make sure that SSE is supported by executing an inline SSE instruction
|
||||
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
// Attempt execution of a SSE2 instruction to make sure OS supports SSE FPU context switches
|
||||
xorpd xmm0, xmm0
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
retval = false;
|
||||
}
|
||||
#ifdef CPUID
|
||||
_asm popad;
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
bool Check3DNowTechnology(void)
|
||||
{
|
||||
int retval = true;
|
||||
unsigned int RegEAX = 0;
|
||||
|
||||
#ifdef CPUID
|
||||
_asm pushad;
|
||||
#endif
|
||||
|
||||
// First see if we can execute CPUID at all
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
#ifdef CPUID
|
||||
// xor edx, edx // Clue the compiler that EDX is about to be used.
|
||||
#endif
|
||||
mov eax, 0x80000000 // setup CPUID to return whether AMD >0x80000000 function are supported.
|
||||
// 0x80000000 = Highest 0x80000000+ function, 0x80000001 = 3DNow support
|
||||
CPUID // code bytes = 0fh, 0a2h
|
||||
mov RegEAX, eax // result returned in eax
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
|
||||
// If CPUID not supported, then there is definitely no 3DNow support
|
||||
if (retval)
|
||||
{
|
||||
// Are there any "higher" AMD CPUID functions?
|
||||
if (RegEAX > 0x80000000L )
|
||||
{
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
mov eax, 0x80000001 // setup to test for CPU features
|
||||
CPUID // code bytes = 0fh, 0a2h
|
||||
shr edx, 31 // If bit 31 is set, we have 3DNow support!
|
||||
mov retval, edx // Save the return value for end of function
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// processor supports CPUID but does not support AMD CPUID functions
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CPUID
|
||||
_asm popad;
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#pragma optimize( "", on )
|
||||
|
||||
#endif // _WIN32
|
47
tier1/processor_detect_linux.cpp
Normal file
47
tier1/processor_detect_linux.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: linux dependant ASM code for CPU capability detection
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#define cpuid(in,a,b,c,d)\
|
||||
asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
|
||||
|
||||
bool CheckMMXTechnology(void)
|
||||
{
|
||||
unsigned long eax,ebx,edx,unused;
|
||||
cpuid(1,eax,ebx,unused,edx);
|
||||
|
||||
return edx & 0x800000;
|
||||
}
|
||||
|
||||
bool CheckSSETechnology(void)
|
||||
{
|
||||
unsigned long eax,ebx,edx,unused;
|
||||
cpuid(1,eax,ebx,unused,edx);
|
||||
|
||||
return edx & 0x2000000L;
|
||||
}
|
||||
|
||||
bool CheckSSE2Technology(void)
|
||||
{
|
||||
unsigned long eax,ebx,edx,unused;
|
||||
cpuid(1,eax,ebx,unused,edx);
|
||||
|
||||
return edx & 0x04000000;
|
||||
}
|
||||
|
||||
bool Check3DNowTechnology(void)
|
||||
{
|
||||
unsigned long eax, unused;
|
||||
cpuid(0x80000000,eax,unused,unused,unused);
|
||||
|
||||
if ( eax > 0x80000000L )
|
||||
{
|
||||
cpuid(0x80000001,unused,unused,unused,eax);
|
||||
return ( eax & 1<<31 );
|
||||
}
|
||||
return false;
|
||||
}
|
37
tier1/rangecheckedvar.cpp
Normal file
37
tier1/rangecheckedvar.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "rangecheckedvar.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
bool g_bDoRangeChecks = true;
|
||||
|
||||
|
||||
static int g_nDisables = 0;
|
||||
|
||||
|
||||
CDisableRangeChecks::CDisableRangeChecks()
|
||||
{
|
||||
g_nDisables++;
|
||||
g_bDoRangeChecks = false;
|
||||
}
|
||||
|
||||
|
||||
CDisableRangeChecks::~CDisableRangeChecks()
|
||||
{
|
||||
Assert( g_nDisables > 0 );
|
||||
--g_nDisables;
|
||||
if ( g_nDisables == 0 )
|
||||
{
|
||||
g_bDoRangeChecks = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
340
tier1/stringpool.cpp
Normal file
340
tier1/stringpool.cpp
Normal file
@ -0,0 +1,340 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "convar.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "stringpool.h"
|
||||
#include "vstdlib/strtools.h"
|
||||
#include "generichash.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Comparison function for string sorted associative data structures
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool StrLess( const char * const &pszLeft, const char * const &pszRight )
|
||||
{
|
||||
return ( Q_stricmp( pszLeft, pszRight) < 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CStringPool::CStringPool()
|
||||
: m_Strings( 32, 256, StrLess )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CStringPool::~CStringPool()
|
||||
{
|
||||
FreeAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
unsigned int CStringPool::Count() const
|
||||
{
|
||||
return m_Strings.Count();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char * CStringPool::Find( const char *pszValue )
|
||||
{
|
||||
unsigned short i = m_Strings.Find(pszValue);
|
||||
if ( m_Strings.IsValidIndex(i) )
|
||||
return m_Strings[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * CStringPool::Allocate( const char *pszValue )
|
||||
{
|
||||
char *pszNew;
|
||||
|
||||
unsigned short i = m_Strings.Find(pszValue);
|
||||
bool bNew = (i == m_Strings.InvalidIndex());
|
||||
|
||||
if ( !bNew )
|
||||
return m_Strings[i];
|
||||
|
||||
pszNew = strdup( pszValue );
|
||||
|
||||
if ( bNew )
|
||||
m_Strings.Insert( pszNew );
|
||||
|
||||
return pszNew;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CStringPool::FreeAll()
|
||||
{
|
||||
unsigned short i = m_Strings.FirstInorder();
|
||||
while ( i != m_Strings.InvalidIndex() )
|
||||
{
|
||||
free( (void *)m_Strings[i] );
|
||||
i = m_Strings.NextInorder(i);
|
||||
}
|
||||
m_Strings.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
CCountedStringPool::CCountedStringPool()
|
||||
{
|
||||
MEM_ALLOC_CREDIT();
|
||||
m_HashTable.EnsureCount(HASH_TABLE_SIZE);
|
||||
|
||||
for( int i = 0; i < m_HashTable.Count(); i++ )
|
||||
{
|
||||
m_HashTable[i] = INVALID_ELEMENT;
|
||||
}
|
||||
|
||||
m_FreeListStart = INVALID_ELEMENT;
|
||||
m_Elements.AddToTail();
|
||||
m_Elements[0].pString = NULL;
|
||||
m_Elements[0].nReferenceCount = 0;
|
||||
m_Elements[0].nNextElement = INVALID_ELEMENT;
|
||||
|
||||
}
|
||||
|
||||
CCountedStringPool::~CCountedStringPool()
|
||||
{
|
||||
FreeAll();
|
||||
}
|
||||
|
||||
void CCountedStringPool::FreeAll()
|
||||
{
|
||||
int i;
|
||||
|
||||
// Reset the hash table:
|
||||
for( i = 0; i < m_HashTable.Count(); i++ )
|
||||
{
|
||||
m_HashTable[i] = INVALID_ELEMENT;
|
||||
}
|
||||
|
||||
// Blow away the free list:
|
||||
m_FreeListStart = INVALID_ELEMENT;
|
||||
|
||||
for( i = 0; i < m_Elements.Count(); i++ )
|
||||
{
|
||||
if( m_Elements[i].pString )
|
||||
{
|
||||
delete [] m_Elements[i].pString;
|
||||
m_Elements[i].pString = NULL;
|
||||
m_Elements[i].nReferenceCount = 0;
|
||||
m_Elements[i].nNextElement = INVALID_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all but the invalid element:
|
||||
m_Elements.SetCount(1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned short CCountedStringPool::FindStringHandle( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return INVALID_ELEMENT;
|
||||
|
||||
unsigned short nHashBucketIndex = (HashStringCaseless(pIntrinsic ) %HASH_TABLE_SIZE);
|
||||
unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ];
|
||||
|
||||
// Does the bucket already exist?
|
||||
if( nCurrentBucket != INVALID_ELEMENT )
|
||||
{
|
||||
for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement )
|
||||
{
|
||||
if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) )
|
||||
{
|
||||
return nCurrentBucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
char* CCountedStringPool::FindString( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return NULL;
|
||||
|
||||
// Yes, this will be NULL on failure.
|
||||
return m_Elements[FindStringHandle(pIntrinsic)].pString;
|
||||
}
|
||||
|
||||
unsigned short CCountedStringPool::ReferenceStringHandle( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return INVALID_ELEMENT;
|
||||
|
||||
unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % HASH_TABLE_SIZE);
|
||||
unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ];
|
||||
|
||||
// Does the bucket already exist?
|
||||
if( nCurrentBucket != INVALID_ELEMENT )
|
||||
{
|
||||
for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement )
|
||||
{
|
||||
if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) )
|
||||
{
|
||||
// Anyone who hits 65k references is permanant
|
||||
if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE )
|
||||
{
|
||||
m_Elements[nCurrentBucket].nReferenceCount ++ ;
|
||||
}
|
||||
return nCurrentBucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( m_FreeListStart != INVALID_ELEMENT )
|
||||
{
|
||||
nCurrentBucket = m_FreeListStart;
|
||||
m_FreeListStart = m_Elements[nCurrentBucket].nNextElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
nCurrentBucket = m_Elements.AddToTail();
|
||||
}
|
||||
|
||||
m_Elements[nCurrentBucket].nReferenceCount = 1;
|
||||
|
||||
// Insert at the beginning of the bucket:
|
||||
m_Elements[nCurrentBucket].nNextElement = m_HashTable[ nHashBucketIndex ];
|
||||
m_HashTable[ nHashBucketIndex ] = nCurrentBucket;
|
||||
|
||||
m_Elements[nCurrentBucket].pString = new char[Q_strlen( pIntrinsic ) + 1];
|
||||
Q_strcpy( m_Elements[nCurrentBucket].pString, pIntrinsic );
|
||||
|
||||
return nCurrentBucket;
|
||||
}
|
||||
|
||||
|
||||
char* CCountedStringPool::ReferenceString( const char* pIntrinsic )
|
||||
{
|
||||
if(!pIntrinsic)
|
||||
return NULL;
|
||||
|
||||
return m_Elements[ReferenceStringHandle( pIntrinsic)].pString;
|
||||
}
|
||||
|
||||
void CCountedStringPool::DereferenceString( const char* pIntrinsic )
|
||||
{
|
||||
// If we get a NULL pointer, just return
|
||||
if(!pIntrinsic)
|
||||
return;
|
||||
|
||||
unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % m_HashTable.Count());
|
||||
unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ];
|
||||
|
||||
// If there isn't anything in the bucket, just return.
|
||||
if( nCurrentBucket == INVALID_ELEMENT )
|
||||
return;
|
||||
|
||||
|
||||
for( unsigned short previous = INVALID_ELEMENT; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement )
|
||||
{
|
||||
if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) )
|
||||
{
|
||||
// Anyone who hits 65k references is permanant
|
||||
if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE )
|
||||
{
|
||||
m_Elements[nCurrentBucket].nReferenceCount --;
|
||||
}
|
||||
|
||||
if( m_Elements[nCurrentBucket].nReferenceCount == 0 )
|
||||
{
|
||||
if( previous == INVALID_ELEMENT )
|
||||
{
|
||||
m_HashTable[nHashBucketIndex] = m_Elements[nCurrentBucket].nNextElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Elements[previous].nNextElement = m_Elements[nCurrentBucket].nNextElement;
|
||||
}
|
||||
|
||||
delete [] m_Elements[nCurrentBucket].pString;
|
||||
m_Elements[nCurrentBucket].pString = NULL;
|
||||
m_Elements[nCurrentBucket].nReferenceCount = 0;
|
||||
|
||||
m_Elements[nCurrentBucket].nNextElement = m_FreeListStart;
|
||||
m_FreeListStart = nCurrentBucket;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
previous = nCurrentBucket;
|
||||
}
|
||||
}
|
||||
|
||||
char* CCountedStringPool::HandleToString( unsigned short handle )
|
||||
{
|
||||
return m_Elements[handle].pString;
|
||||
}
|
||||
|
||||
CCountedStringPool g_CountedStringPool;
|
||||
|
||||
CON_COMMAND( dumpcountedstrings, "Tests the class CStringPool" )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < g_CountedStringPool.m_Elements.Count(); i++ )
|
||||
{
|
||||
char* string = g_CountedStringPool.m_Elements[i].pString;
|
||||
|
||||
Msg("String %d: ref:%d %s", i, g_CountedStringPool.m_Elements[i].nReferenceCount, string == NULL? "EMPTY - ok for slot zero only!" : string);
|
||||
}
|
||||
|
||||
Msg("\n%d total counted strings.",g_CountedStringPool.m_Elements.Count());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
CON_COMMAND( test_stringpool, "Tests the class CStringPool" )
|
||||
{
|
||||
CStringPool pool;
|
||||
|
||||
Assert(pool.Count() == 0);
|
||||
|
||||
pool.Allocate("test");
|
||||
Assert(pool.Count() == 1);
|
||||
|
||||
pool.Allocate("test");
|
||||
Assert(pool.Count() == 1);
|
||||
|
||||
pool.Allocate("test2");
|
||||
Assert(pool.Count() == 2);
|
||||
|
||||
Assert( pool.Find("test2") != NULL );
|
||||
Assert( pool.Find("TEST") != NULL );
|
||||
Assert( pool.Find("Test2") != NULL );
|
||||
Assert( pool.Find("test") != NULL );
|
||||
|
||||
pool.FreeAll();
|
||||
Assert(pool.Count() == 0);
|
||||
|
||||
Msg("Pass.");
|
||||
}
|
||||
|
||||
#endif
|
1767
tier1/strtools.cpp
Normal file
1767
tier1/strtools.cpp
Normal file
File diff suppressed because it is too large
Load Diff
362
tier1/tier1-2003.vcproj
Normal file
362
tier1/tier1-2003.vcproj
Normal file
@ -0,0 +1,362 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="tier1"
|
||||
ProjectGUID="{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
ImproveFloatingPointConsistency="TRUE"
|
||||
OptimizeForProcessor="3"
|
||||
AdditionalIncludeDirectories="..\common,..\public,..\public\tier1"
|
||||
PreprocessorDefinitions="_WIN32;_DEBUG;_LIB;TIER1_STATIC_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
BufferSecurityCheck="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="..\lib-vc7\public\tier1.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
CommandLine="if exist ..\lib-vc7\public\tier1.lib attrib -r ..\lib-vc7\public\tier1.lib
|
||||
if exist ..\lib-vc7\public\tier1.pdb attrib -r ..\lib-vc7\public\tier1.pdb
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
ImproveFloatingPointConsistency="FALSE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OptimizeForProcessor="3"
|
||||
AdditionalIncludeDirectories="..\common,..\public,..\public\tier1"
|
||||
PreprocessorDefinitions="_WIN32;NDEBUG;_LIB;TIER1_STATIC_LIB"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="2"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="..\lib-vc7\public\tier1.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
CommandLine="if exist ..\lib-vc7\public\tier1.lib attrib -r ..\lib-vc7\public\tier1.lib
|
||||
if exist ..\lib-vc7\public\tier1.pdb attrib -r ..\lib-vc7\public\tier1.pdb
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\bitbuf.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\byteswap.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\characterset.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\checksum_crc.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\checksum_md5.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\convar.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\datamanager.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\diff.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\generichash.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\interface.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jobthread.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\KeyValues.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mempool.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\memstack.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NetAdr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\processor_detect.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\processor_detect_linux.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangecheckedvar.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stringpool.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\strtools.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tier1.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tokenreader.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlbuffer.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlstring.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlsymbol.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xboxstubs.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath="..\public\tier1\bitbuf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\characterset.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\checksum_crc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\checksum_md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\convar.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\datamanager.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\datamap.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\diff.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\fmtstr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\generichash.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\interface.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\jobthread.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\KeyValues.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\mempool.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\memstack.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\netadr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\processor_detect.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\rangecheckedvar.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\refcount.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\smartptr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\stringpool.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\strtools.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\tier1.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\tokenreader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlbidirectionalset.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlbuffer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utldict.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlfixedlinkedlist.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlfixedmemory.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlhandletable.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlhash.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utllinkedlist.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmap.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmemory.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmultilist.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlpriorityqueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlqueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlrbtree.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\UtlSortVector.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlstack.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlstring.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\UtlStringMap.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlsymbol.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlvector.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\xbox\xboxstubs.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
480
tier1/tier1-2005.vcproj
Normal file
480
tier1/tier1-2005.vcproj
Normal file
@ -0,0 +1,480 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="tier1"
|
||||
ProjectGUID="{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\common,..\public,..\public\tier1"
|
||||
PreprocessorDefinitions="_WIN32;_DEBUG;_LIB;TIER1_STATIC_LIB"
|
||||
MinimalRebuild="true"
|
||||
ExceptionHandling="1"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
BufferSecurityCheck="true"
|
||||
ForceConformanceInForLoopScope="true"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
CommandLine="if exist ..\lib\public\tier1.lib attrib -r ..\lib\public\tier1.lib
if exist ..\lib\public\tier1.pdb attrib -r ..\lib\public\tier1.pdb
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="..\lib\public\tier1.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\common,..\public,..\public\tier1"
|
||||
PreprocessorDefinitions="_WIN32;NDEBUG;_LIB;TIER1_STATIC_LIB;_SECURE_SCL=0 "
|
||||
StringPooling="true"
|
||||
ExceptionHandling="1"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
ForceConformanceInForLoopScope="true"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
CommandLine="if exist ..\lib\public\tier1.lib attrib -r ..\lib\public\tier1.lib
if exist ..\lib\public\tier1.pdb attrib -r ..\lib\public\tier1.pdb
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="..\lib\public\tier1.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\bitbuf.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\byteswap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\characterset.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\checksum_crc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\checksum_md5.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\convar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\datamanager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\diff.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\generichash.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\interface.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jobthread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\KeyValues.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mempool.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\memstack.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NetAdr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\processor_detect.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\processor_detect_linux.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangecheckedvar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stringpool.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\strtools.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tier1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tokenreader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlbuffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlstring.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlsymbol.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xboxstubs.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\public\tier1\bitbuf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\characterset.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\checksum_crc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\checksum_md5.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\convar.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\datamanager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\datamap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\diff.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\fmtstr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\generichash.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\interface.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\jobthread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\KeyValues.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\mempool.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\memstack.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\netadr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\processor_detect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\rangecheckedvar.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\refcount.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\smartptr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\stringpool.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\strtools.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\tier1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\tokenreader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlbidirectionalset.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlbuffer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utldict.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlfixedlinkedlist.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlfixedmemory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlhandletable.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlhash.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utllinkedlist.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmemory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmultilist.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlpriorityqueue.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlqueue.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlrbtree.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\UtlSortVector.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlstack.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlstring.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\UtlStringMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlsymbol.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlvector.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\xbox\xboxstubs.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
56
tier1/tier1.cpp
Normal file
56
tier1/tier1.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: A higher level link library for general use in the game and tools.
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include <tier1/tier1.h>
|
||||
#include "tier0/dbg.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "icvar.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// These tier1 libraries must be set by any users of this library.
|
||||
// They can be set by calling ConnectTier1Libraries or InitDefaultFileSystem.
|
||||
// It is hoped that setting this, and using this library will be the common mechanism for
|
||||
// allowing link libraries to access tier1 library interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
ICvar *cvar = 0;
|
||||
ICvar *g_pCVar = 0;
|
||||
IDataModel *g_pDataModel = 0;
|
||||
IDmElementFramework *g_pDmElementFramework = 0;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Call this to connect to all tier 1 libraries.
|
||||
// It's up to the caller to check the globals it cares about to see if ones are missing
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConnectTier1Libraries( CreateInterfaceFn *pFactoryList, int nFactoryCount )
|
||||
{
|
||||
// Don't connect twice..
|
||||
Assert( !g_pCVar && !g_pDataModel && !g_pDmElementFramework );
|
||||
|
||||
for ( int i = 0; i < nFactoryCount; ++i )
|
||||
{
|
||||
if ( !g_pCVar )
|
||||
{
|
||||
cvar = g_pCVar = ( ICvar * )pFactoryList[i]( VENGINE_CVAR_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pDataModel )
|
||||
{
|
||||
g_pDataModel = ( IDataModel * )pFactoryList[i]( VDATAMODEL_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pDmElementFramework )
|
||||
{
|
||||
g_pDmElementFramework = ( IDmElementFramework * )pFactoryList[i]( VDMELEMENTFRAMEWORK_VERSION, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisconnectTier1Libraries()
|
||||
{
|
||||
g_pCVar = cvar = 0;
|
||||
g_pDataModel = 0;
|
||||
g_pDmElementFramework = 0;
|
||||
}
|
548
tier1/tier1_xbox.vcproj
Normal file
548
tier1/tier1_xbox.vcproj
Normal file
@ -0,0 +1,548 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="tier1"
|
||||
ProjectGUID="{B9E5E3DB-8DF6-4741-A773-03A9B698B4E1}"
|
||||
Keyword="XboxProj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Xbox"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Xbox"
|
||||
OutputDirectory="Debug_XBox"
|
||||
IntermediateDirectory="Debug_XBox"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
ImproveFloatingPointConsistency="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
AdditionalIncludeDirectories="..\common,..\public,..\public\tier1"
|
||||
PreprocessorDefinitions="_DEBUG;_XBOX;_STATIC_LINKED;_SUBSYSTEM=Tier1"
|
||||
StringPooling="TRUE"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Publishing to target directory (..\..\lib_xbox\)..."
|
||||
CommandLine="if exist ..\lib_xbox\public\tier1_xbox.lib attrib -r ..\lib_xbox\public\tier1_xbox.lib
|
||||
if exist $(TargetPath) copy $(TargetPath) ..\lib_xbox\public\tier1_xbox.lib"
|
||||
Outputs="..\lib_xbox\public\tier1_xbox.lib"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="if exist ..\lib_xbox\public\tier1_xbox.lib del ..\lib_xbox\public\tier1_xbox.lib"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Profile|Xbox"
|
||||
OutputDirectory="Profile"
|
||||
IntermediateDirectory="Profile"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
PreprocessorDefinitions="NDEBUG;_XBOX;PROFILE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="TRUE"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="xapilib.lib d3d8i.lib d3dx8.lib xgraphics.lib dsound.lib dmusici.lib xactengi.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib xbdm.lib xperf.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="1"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="XboxDeploymentTool"/>
|
||||
<Tool
|
||||
Name="XboxImageTool"
|
||||
StackSize="65536"
|
||||
IncludeDebugInfo="TRUE"
|
||||
NoLibWarn="TRUE"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Profile_FastCap|Xbox"
|
||||
OutputDirectory="Profile_FastCap"
|
||||
IntermediateDirectory="Profile_FastCap"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
PreprocessorDefinitions="NDEBUG;_XBOX;PROFILE;FASTCAP"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="TRUE"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"
|
||||
FastCAP="TRUE"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="xapilib.lib d3d8i.lib d3dx8.lib xgraphics.lib dsound.lib dmusici.lib xactengi.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib xbdm.lib xperf.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="1"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="XboxDeploymentTool"/>
|
||||
<Tool
|
||||
Name="XboxImageTool"
|
||||
StackSize="65536"
|
||||
IncludeDebugInfo="TRUE"
|
||||
NoLibWarn="TRUE"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Xbox"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
PreprocessorDefinitions="NDEBUG;_XBOX"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="TRUE"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib dmusic.lib xacteng.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="1"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="XboxDeploymentTool"/>
|
||||
<Tool
|
||||
Name="XboxImageTool"
|
||||
StackSize="65536"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release_LTCG|Xbox"
|
||||
OutputDirectory="Release_LTCG"
|
||||
IntermediateDirectory="Release_LTCG"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
PreprocessorDefinitions="NDEBUG;_XBOX;LTCG"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="TRUE"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
UsePrecompiledHeader="3"
|
||||
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="xapilib.lib d3d8ltcg.lib d3dx8.lib xgraphicsltcg.lib dsound.lib dmusicltcg.lib xactengltcg.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib"
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="1"
|
||||
SetChecksum="TRUE"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="XboxDeploymentTool"/>
|
||||
<Tool
|
||||
Name="XboxImageTool"
|
||||
StackSize="65536"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release_XBox|Xbox"
|
||||
OutputDirectory="Release_XBox"
|
||||
IntermediateDirectory="Release_XBox"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
ImproveFloatingPointConsistency="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
AdditionalIncludeDirectories="..\common,..\public,..\public\tier1"
|
||||
PreprocessorDefinitions="NDEBUG;_RELEASE;_XBOX;_STATIC_LINKED;_SUBSYSTEM=Tier1"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="2"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="if exist ..\lib_xbox\public\tier1_xbox.lib attrib -r ..\lib_xbox\public\tier1_xbox.lib
|
||||
if exist $(TargetPath) copy $(TargetPath) ..\lib_xbox\public\tier1_xbox.lib"
|
||||
Outputs="..\lib_xbox\public\tier1_xbox.lib"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="if exist ..\lib_xbox\public\tier1_xbox.lib del ..\lib_xbox\public\tier1_xbox.lib"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Retail_XBox|Xbox"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D "_RETAIL""
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
ImproveFloatingPointConsistency="TRUE"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
AdditionalIncludeDirectories="..\common,..\public,..\public\tier1"
|
||||
PreprocessorDefinitions="NDEBUG;_XBOX;_STATIC_LINKED;_SUBSYSTEM=Tier1"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
RuntimeTypeInfo="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="2"
|
||||
CallingConvention="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="if exist ..\lib_xbox\public\tier1_xbox.lib attrib -r ..\lib_xbox\public\tier1_xbox.lib
|
||||
if exist $(TargetPath) copy $(TargetPath) ..\lib_xbox\public\tier1_xbox.lib"
|
||||
Outputs="..\lib_xbox\public\tier1_xbox.lib"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="if exist ..\lib_xbox\public\tier1_xbox.lib del ..\lib_xbox\public\tier1_xbox.lib"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\bitbuf.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\characterset.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\checksum_crc.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\checksum_md5.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\convar.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\datamanager.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\generichash.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\interface.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Xbox"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release_XBox|Xbox"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Retail_XBox|Xbox"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jobthread.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\KeyValues.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mempool.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\memstack.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NetAdr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\processor_detect.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangecheckedvar.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stringpool.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tokenreader.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\undiff.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlbuffer.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlstring.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlsymbol.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath="..\public\tier1\bitbuf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\characterset.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\checksum_crc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\checksum_md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\convar.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\datamanager.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\fmtstr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\generichash.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\interface.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\KeyValues.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\mempool.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\memstack.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\netadr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\processor_detect.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\rangecheckedvar.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\smartptr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\stringpool.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\tokenreader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlbidirectionalset.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlbuffer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utldict.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlfixedlinkedlist.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlfixedmemory.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlhash.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utllinkedlist.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmap.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmemory.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlmultilist.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlpriorityqueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlqueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlrbtree.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\UtlSortVector.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlstack.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlstring.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\UtlStringMap.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlsymbol.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\public\tier1\utlvector.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
480
tier1/tokenreader.cpp
Normal file
480
tier1/tokenreader.cpp
Normal file
@ -0,0 +1,480 @@
|
||||
//========= 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 "vstdlib/strtools.h"
|
||||
#include "tier0/dbg.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)
|
||||
{
|
||||
open(pszFilename, std::ios::in | std::ios::binary );
|
||||
Q_strncpy(m_szFilename, pszFilename, sizeof( m_szFilename ) );
|
||||
m_nLine = 1;
|
||||
m_nErrorCount = 0;
|
||||
m_bStuffed = false;
|
||||
return(is_open() != 0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void TokenReader::Close()
|
||||
{
|
||||
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.
|
||||
//
|
||||
get(szBuf, sizeof(szBuf), '\"');
|
||||
if (eof())
|
||||
{
|
||||
return TOKENEOF;
|
||||
}
|
||||
|
||||
if (fail())
|
||||
{
|
||||
// Just means nothing was read (empty string probably "")
|
||||
clear();
|
||||
}
|
||||
|
||||
//
|
||||
// Transfer the text to the destination buffer.
|
||||
//
|
||||
char *pszSrc = szBuf;
|
||||
while ((*pszSrc != '\0') && (nSize > 1))
|
||||
{
|
||||
if (*pszSrc == 0x0d)
|
||||
{
|
||||
//
|
||||
// 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. Skip to the close-quote,
|
||||
// terminate the string, and exit.
|
||||
//
|
||||
ignore(1024, '\"');
|
||||
*pszStore = '\0';
|
||||
return TOKENSTRINGTOOLONG;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for closing quote.
|
||||
//
|
||||
if (peek() == '\"')
|
||||
{
|
||||
//
|
||||
// Eat the close quote and any whitespace.
|
||||
//
|
||||
get();
|
||||
|
||||
bool bCombineStrings = SkipWhiteSpace();
|
||||
|
||||
//
|
||||
// Combine consecutive quoted strings if the combine strings character was
|
||||
// encountered between the two strings.
|
||||
//
|
||||
if (bCombineStrings && (peek() == '\"'))
|
||||
{
|
||||
//
|
||||
// Eat the open quote and keep parsing this string.
|
||||
//
|
||||
get();
|
||||
}
|
||||
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 (!is_open())
|
||||
{
|
||||
return TOKENEOF;
|
||||
}
|
||||
|
||||
//
|
||||
// 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 (eof())
|
||||
{
|
||||
return TOKENEOF;
|
||||
}
|
||||
|
||||
if (fail())
|
||||
{
|
||||
return TOKENEOF;
|
||||
}
|
||||
|
||||
char ch = get();
|
||||
|
||||
//
|
||||
// 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;
|
||||
return OPERATOR;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Look for the start of a quoted string.
|
||||
//
|
||||
if (ch == '\"')
|
||||
{
|
||||
return GetString(pszStore, nSize);
|
||||
}
|
||||
|
||||
//
|
||||
// Integers consist of numbers with an optional leading minus sign.
|
||||
//
|
||||
if (isdigit(ch) || (ch == '-'))
|
||||
{
|
||||
do
|
||||
{
|
||||
if ( (pszStore - pStart + 1) < nSize )
|
||||
{
|
||||
*pszStore = ch;
|
||||
pszStore++;
|
||||
}
|
||||
|
||||
ch = get();
|
||||
if (ch == '-')
|
||||
{
|
||||
return TOKENERROR;
|
||||
}
|
||||
} while (isdigit(ch));
|
||||
|
||||
//
|
||||
// No identifier characters are allowed contiguous with numbers.
|
||||
//
|
||||
if (isalpha(ch) || (ch == '_'))
|
||||
{
|
||||
return TOKENERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Put back the non-numeric character for the next call.
|
||||
//
|
||||
putback(ch);
|
||||
*pszStore = '\0';
|
||||
return INTEGER;
|
||||
}
|
||||
|
||||
//
|
||||
// Identifiers consist of a consecutive string of alphanumeric
|
||||
// characters and underscores.
|
||||
//
|
||||
while ( isalpha(ch) || isdigit(ch) || (ch == '_') )
|
||||
{
|
||||
if ( (pszStore - pStart + 1) < nSize )
|
||||
{
|
||||
*pszStore = ch;
|
||||
pszStore++;
|
||||
}
|
||||
|
||||
ch = get();
|
||||
}
|
||||
|
||||
//
|
||||
// Put back the non-identifier character for the next call.
|
||||
//
|
||||
putback(ch);
|
||||
*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 (true)
|
||||
{
|
||||
char ch = get();
|
||||
|
||||
if ((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '+')
|
||||
{
|
||||
bCombineStrings = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
m_nLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (eof())
|
||||
{
|
||||
return(bCombineStrings);
|
||||
}
|
||||
|
||||
//
|
||||
// Check for the start of a comment.
|
||||
//
|
||||
if (ch == '/')
|
||||
{
|
||||
if (peek() == '/')
|
||||
{
|
||||
ignore(1024, '\n');
|
||||
m_nLine++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// It is a worthy character. Put it back.
|
||||
//
|
||||
putback(ch);
|
||||
return(bCombineStrings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
94
tier1/undiff.cpp
Normal file
94
tier1/undiff.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// UnDiff - Apply difference block
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/diff.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
void ApplyDiffs(uint8 const *OldBlock, uint8 const *DiffList,
|
||||
int OldSize, int DiffListSize, int &ResultListSize,uint8 *Output,uint32 OutSize)
|
||||
{
|
||||
uint8 const *copy_src=OldBlock;
|
||||
uint8 const *end_of_diff_list=DiffList+DiffListSize;
|
||||
uint8 const *obuf=Output;
|
||||
while(DiffList<end_of_diff_list)
|
||||
{
|
||||
// printf("dptr=%x ",DiffList-d);
|
||||
uint8 op=*(DiffList++);
|
||||
if (op==0)
|
||||
{
|
||||
uint16 copy_sz=DiffList[0]+256*DiffList[1];
|
||||
int copy_ofs=DiffList[2]+DiffList[3]*256;
|
||||
if (copy_ofs>32767)
|
||||
copy_ofs|=0xffff0000;
|
||||
// printf("long cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz);
|
||||
|
||||
memcpy(Output,copy_src+copy_ofs,copy_sz);
|
||||
Output+=copy_sz;
|
||||
copy_src=copy_src+copy_ofs+copy_sz;
|
||||
DiffList+=4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (op & 0x80)
|
||||
{
|
||||
int copy_sz=op & 0x7f;
|
||||
int copy_ofs;
|
||||
if (copy_sz==0)
|
||||
{
|
||||
copy_sz=DiffList[0];
|
||||
if (copy_sz==0)
|
||||
{
|
||||
// big raw copy
|
||||
copy_sz=DiffList[1]+256*DiffList[2]+65536*DiffList[3];
|
||||
memcpy(Output,DiffList+4,copy_sz);
|
||||
// printf("big rawcopy to %x len=%d\n", Output-obuf,copy_sz);
|
||||
|
||||
DiffList+=copy_sz+4;
|
||||
Output+=copy_sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_ofs=DiffList[1]+(DiffList[2]*256);
|
||||
if (copy_ofs>32767)
|
||||
copy_ofs|=0xffff0000;
|
||||
// printf("long ofs cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz);
|
||||
|
||||
memcpy(Output,copy_src+copy_ofs,copy_sz);
|
||||
Output+=copy_sz;
|
||||
copy_src=copy_src+copy_ofs+copy_sz;
|
||||
DiffList+=3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_ofs=DiffList[0];
|
||||
if (copy_ofs>127)
|
||||
copy_ofs|=0xffffff80;
|
||||
// printf("cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz);
|
||||
|
||||
memcpy(Output,copy_src+copy_ofs,copy_sz);
|
||||
Output+=copy_sz;
|
||||
copy_src=copy_src+copy_ofs+copy_sz;
|
||||
DiffList++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("raw copy %d to %x\n",op & 127,Output-obuf);
|
||||
memcpy(Output,DiffList,op & 127);
|
||||
Output+=op & 127;
|
||||
DiffList+=(op & 127);
|
||||
}
|
||||
}
|
||||
}
|
||||
ResultListSize=Output-obuf;
|
||||
|
||||
}
|
1544
tier1/utlbuffer.cpp
Normal file
1544
tier1/utlbuffer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
218
tier1/utlstring.cpp
Normal file
218
tier1/utlstring.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
//====== Copyright <20> 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "tier1/utlstring.h"
|
||||
#include "vstdlib/strtools.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class, containing simple memory management
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( int growSize, int initSize ) : m_Memory( growSize, initSize )
|
||||
{
|
||||
m_nActualLength = 0;
|
||||
}
|
||||
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes )
|
||||
{
|
||||
m_nActualLength = nInitialLength;
|
||||
}
|
||||
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes )
|
||||
{
|
||||
m_nActualLength = nSizeInBytes;
|
||||
}
|
||||
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( const CUtlBinaryBlock& src )
|
||||
{
|
||||
Set( src.Get(), src.Length() );
|
||||
}
|
||||
|
||||
void CUtlBinaryBlock::Get( void *pValue, int nLen ) const
|
||||
{
|
||||
Assert( nLen > 0 );
|
||||
if ( m_nActualLength < nLen )
|
||||
{
|
||||
nLen = m_nActualLength;
|
||||
}
|
||||
|
||||
if ( nLen > 0 )
|
||||
{
|
||||
memcpy( pValue, m_Memory.Base(), nLen );
|
||||
}
|
||||
}
|
||||
|
||||
void CUtlBinaryBlock::SetLength( int nLength )
|
||||
{
|
||||
Assert( !m_Memory.IsReadOnly() );
|
||||
|
||||
m_nActualLength = nLength;
|
||||
if ( nLength > m_Memory.NumAllocated() )
|
||||
{
|
||||
int nOverFlow = nLength - m_Memory.NumAllocated();
|
||||
m_Memory.Grow( nOverFlow );
|
||||
|
||||
// If the reallocation failed, clamp length
|
||||
if ( nLength > m_Memory.NumAllocated() )
|
||||
{
|
||||
m_nActualLength = m_Memory.NumAllocated();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ( m_Memory.NumAllocated() > m_nActualLength )
|
||||
{
|
||||
memset( ( ( char * )m_Memory.Base() ) + m_nActualLength, 0xEB, m_Memory.NumAllocated() - m_nActualLength );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CUtlBinaryBlock::Set( const void *pValue, int nLen )
|
||||
{
|
||||
Assert( !m_Memory.IsReadOnly() );
|
||||
|
||||
if ( !pValue )
|
||||
{
|
||||
nLen = 0;
|
||||
}
|
||||
|
||||
SetLength( nLen );
|
||||
|
||||
if ( m_nActualLength )
|
||||
{
|
||||
if ( ( ( const char * )m_Memory.Base() ) >= ( ( const char * )pValue ) + nLen ||
|
||||
( ( const char * )m_Memory.Base() ) + m_nActualLength <= ( ( const char * )pValue ) )
|
||||
{
|
||||
memcpy( m_Memory.Base(), pValue, m_nActualLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove( m_Memory.Base(), pValue, m_nActualLength );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CUtlBinaryBlock &CUtlBinaryBlock::operator=( const CUtlBinaryBlock &src )
|
||||
{
|
||||
Assert( !m_Memory.IsReadOnly() );
|
||||
Set( src.Get(), src.Length() );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool CUtlBinaryBlock::operator==( const CUtlBinaryBlock &src ) const
|
||||
{
|
||||
if ( src.Length() != Length() )
|
||||
return false;
|
||||
|
||||
return !memcmp( src.Get(), Get(), Length() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Simple string class.
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlString::CUtlString()
|
||||
{
|
||||
}
|
||||
|
||||
CUtlString::CUtlString( const char *pString )
|
||||
{
|
||||
Set( pString );
|
||||
}
|
||||
|
||||
CUtlString::CUtlString( const CUtlString& string )
|
||||
{
|
||||
Set( string.Get() );
|
||||
}
|
||||
|
||||
// Attaches the string to external memory. Useful for avoiding a copy
|
||||
CUtlString::CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Storage( pMemory, nSizeInBytes, nInitialLength )
|
||||
{
|
||||
}
|
||||
|
||||
CUtlString::CUtlString( const void* pMemory, int nSizeInBytes ) : m_Storage( pMemory, nSizeInBytes )
|
||||
{
|
||||
}
|
||||
|
||||
void CUtlString::Set( const char *pValue )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
int nLen = pValue ? Q_strlen(pValue) + 1 : 0;
|
||||
m_Storage.Set( pValue, nLen );
|
||||
}
|
||||
|
||||
// Returns strlen
|
||||
int CUtlString::Length() const
|
||||
{
|
||||
return m_Storage.Length() ? m_Storage.Length() - 1 : 0;
|
||||
}
|
||||
|
||||
// Sets the length (used to serialize into the buffer )
|
||||
void CUtlString::SetLength( int nLen )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
|
||||
// Add 1 to account for the NULL
|
||||
m_Storage.SetLength( nLen > 0 ? nLen + 1 : 0 );
|
||||
}
|
||||
|
||||
const char *CUtlString::Get( ) const
|
||||
{
|
||||
if ( m_Storage.Length() == 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return reinterpret_cast< const char* >( m_Storage.Get() );
|
||||
}
|
||||
|
||||
// Converts to c-strings
|
||||
CUtlString::operator const char*() const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
char *CUtlString::Get()
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
|
||||
if ( m_Storage.Length() == 0 )
|
||||
{
|
||||
// In general, we optimise away small mallocs for empty strings
|
||||
// but if you ask for the non-const bytes, they must be writable
|
||||
// so we can't return "" here, like we do for the const version - jd
|
||||
m_Storage.SetLength( 1 );
|
||||
m_Storage[ 0 ] = '\0';
|
||||
}
|
||||
|
||||
return reinterpret_cast< char* >( m_Storage.Get() );
|
||||
}
|
||||
|
||||
CUtlString &CUtlString::operator=( const CUtlString &src )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
m_Storage = src.m_Storage;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CUtlString &CUtlString::operator=( const char *src )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
Set( src );
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CUtlString::operator==( const CUtlString &src ) const
|
||||
{
|
||||
return m_Storage == src.m_Storage;
|
||||
}
|
||||
|
||||
bool CUtlString::operator==( const char *src ) const
|
||||
{
|
||||
return ( strcmp( Get(), src ) == 0 );
|
||||
}
|
368
tier1/utlsymbol.cpp
Normal file
368
tier1/utlsymbol.cpp
Normal file
@ -0,0 +1,368 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Defines a symbol table
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef _XBOX
|
||||
#pragma warning (disable:4514)
|
||||
#endif
|
||||
|
||||
#include "utlsymbol.h"
|
||||
#include "KeyValues.h"
|
||||
#include "tier0/threadtools.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
#include "stringpool.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define INVALID_STRING_INDEX CStringPoolIndex( 0xFFFF, 0xFFFF )
|
||||
|
||||
#define MIN_STRING_POOL_SIZE 2048
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// globals
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CUtlSymbolTableMT* CUtlSymbol::s_pSymbolTable = 0;
|
||||
bool CUtlSymbol::s_bAllowStaticSymbolTable = true;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// symbol methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CUtlSymbol::Initialize()
|
||||
{
|
||||
// If this assert fails, then the module that this call is in has chosen to disallow
|
||||
// use of the static symbol table. Usually, it's to prevent confusion because it's easy
|
||||
// to accidentally use the global symbol table when you really want to use a specific one.
|
||||
#ifndef _XBOX
|
||||
// xboxissue - need to isolate this concept per lib, otherwise
|
||||
// can't trap coding mistakes (i.e. unintended global symbol table usage)
|
||||
Assert( s_bAllowStaticSymbolTable );
|
||||
#endif
|
||||
|
||||
// necessary to allow us to create global symbols
|
||||
static bool symbolsInitialized = false;
|
||||
if (!symbolsInitialized)
|
||||
{
|
||||
s_pSymbolTable = new CUtlSymbolTableMT;
|
||||
symbolsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Singleton to delete table on exit from module
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCleanupUtlSymbolTable
|
||||
{
|
||||
public:
|
||||
~CCleanupUtlSymbolTable()
|
||||
{
|
||||
delete CUtlSymbol::s_pSymbolTable;
|
||||
CUtlSymbol::s_pSymbolTable = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
static CCleanupUtlSymbolTable g_CleanupSymbolTable;
|
||||
|
||||
CUtlSymbolTableMT* CUtlSymbol::CurrTable()
|
||||
{
|
||||
Initialize();
|
||||
return s_pSymbolTable;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// string->symbol->string
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CUtlSymbol::CUtlSymbol( char const* pStr )
|
||||
{
|
||||
m_Id = CurrTable()->AddString( pStr );
|
||||
}
|
||||
|
||||
char const* CUtlSymbol::String( ) const
|
||||
{
|
||||
return CurrTable()->String(m_Id);
|
||||
}
|
||||
|
||||
void CUtlSymbol::DisableStaticSymbolTable()
|
||||
{
|
||||
s_bAllowStaticSymbolTable = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// checks if the symbol matches a string
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool CUtlSymbol::operator==( char const* pStr ) const
|
||||
{
|
||||
if (m_Id == UTL_INVAL_SYMBOL)
|
||||
return false;
|
||||
return strcmp( String(), pStr ) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// symbol table stuff
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline const char* CUtlSymbolTable::StringFromIndex( const CStringPoolIndex &index ) const
|
||||
{
|
||||
Assert( index.m_iPool < m_StringPools.Count() );
|
||||
Assert( index.m_iOffset < m_StringPools[index.m_iPool]->m_TotalLen );
|
||||
|
||||
return &m_StringPools[index.m_iPool]->m_Data[index.m_iOffset];
|
||||
}
|
||||
|
||||
|
||||
bool CUtlSymbolTable::CLess::operator()( const CStringPoolIndex &i1, const CStringPoolIndex &i2 ) const
|
||||
{
|
||||
// Need to do pointer math because CUtlSymbolTable is used in CUtlVectors, and hence
|
||||
// can be arbitrarily moved in memory on a realloc. Yes, this is portable. In reality,
|
||||
// right now at least, because m_LessFunc is the first member of CUtlRBTree, and m_Lookup
|
||||
// is the first member of CUtlSymbolTabke, this == pTable
|
||||
CUtlSymbolTable *pTable = (CUtlSymbolTable *)( (byte *)this - offsetof(CUtlSymbolTable::CTree, m_LessFunc) ) - offsetof(CUtlSymbolTable, m_Lookup );
|
||||
char const* str1 = (i1 == INVALID_STRING_INDEX) ? pTable->m_pUserSearchString :
|
||||
pTable->StringFromIndex( i1 );
|
||||
char const* str2 = (i2 == INVALID_STRING_INDEX) ? pTable->m_pUserSearchString :
|
||||
pTable->StringFromIndex( i2 );
|
||||
|
||||
if ( !pTable->m_bInsensitive )
|
||||
return strcmp( str1, str2 ) < 0;
|
||||
else
|
||||
return strcmpi( str1, str2 ) < 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CUtlSymbolTable::CUtlSymbolTable( int growSize, int initSize, bool caseInsensitive ) :
|
||||
m_Lookup( growSize, initSize ), m_bInsensitive( caseInsensitive ), m_StringPools( 8 )
|
||||
{
|
||||
}
|
||||
|
||||
CUtlSymbolTable::~CUtlSymbolTable()
|
||||
{
|
||||
// Release the stringpool string data
|
||||
RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
CUtlSymbol CUtlSymbolTable::Find( char const* pString )
|
||||
{
|
||||
if (!pString)
|
||||
return CUtlSymbol();
|
||||
|
||||
// Store a special context used to help with insertion
|
||||
m_pUserSearchString = pString;
|
||||
|
||||
// Passing this special invalid symbol makes the comparison function
|
||||
// use the string passed in the context
|
||||
UtlSymId_t idx = m_Lookup.Find( INVALID_STRING_INDEX );
|
||||
|
||||
#ifdef _DEBUG
|
||||
m_pUserSearchString = NULL;
|
||||
#endif
|
||||
|
||||
return CUtlSymbol( idx );
|
||||
}
|
||||
|
||||
|
||||
int CUtlSymbolTable::FindPoolWithSpace( int len ) const
|
||||
{
|
||||
for ( int i=0; i < m_StringPools.Count(); i++ )
|
||||
{
|
||||
StringPool_t *pPool = m_StringPools[i];
|
||||
|
||||
if ( (pPool->m_TotalLen - pPool->m_SpaceUsed) >= len )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds and/or creates a symbol based on the string
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CUtlSymbol CUtlSymbolTable::AddString( char const* pString )
|
||||
{
|
||||
if (!pString)
|
||||
return CUtlSymbol( UTL_INVAL_SYMBOL );
|
||||
|
||||
CUtlSymbol id = Find( pString );
|
||||
|
||||
if (id.IsValid())
|
||||
return id;
|
||||
|
||||
int len = strlen(pString) + 1;
|
||||
|
||||
// Find a pool with space for this string, or allocate a new one.
|
||||
int iPool = FindPoolWithSpace( len );
|
||||
if ( iPool == -1 )
|
||||
{
|
||||
// Add a new pool.
|
||||
int newPoolSize = max( len, MIN_STRING_POOL_SIZE );
|
||||
StringPool_t *pPool = (StringPool_t*)malloc( sizeof( StringPool_t ) + newPoolSize - 1 );
|
||||
pPool->m_TotalLen = newPoolSize;
|
||||
pPool->m_SpaceUsed = 0;
|
||||
iPool = m_StringPools.AddToTail( pPool );
|
||||
}
|
||||
|
||||
// Copy the string in.
|
||||
StringPool_t *pPool = m_StringPools[iPool];
|
||||
Assert( pPool->m_SpaceUsed < 0xFFFF ); // This should never happen, because if we had a string > 64k, it
|
||||
// would have been given its entire own pool.
|
||||
|
||||
unsigned short iStringOffset = pPool->m_SpaceUsed;
|
||||
|
||||
memcpy( &pPool->m_Data[pPool->m_SpaceUsed], pString, len );
|
||||
pPool->m_SpaceUsed += len;
|
||||
|
||||
// didn't find, insert the string into the vector.
|
||||
CStringPoolIndex index;
|
||||
index.m_iPool = iPool;
|
||||
index.m_iOffset = iStringOffset;
|
||||
|
||||
UtlSymId_t idx = m_Lookup.Insert( index );
|
||||
return CUtlSymbol( idx );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Look up the string associated with a particular symbol
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
char const* CUtlSymbolTable::String( CUtlSymbol id ) const
|
||||
{
|
||||
if (!id.IsValid())
|
||||
return "";
|
||||
|
||||
Assert( m_Lookup.IsValidIndex((UtlSymId_t)id) );
|
||||
return StringFromIndex( m_Lookup[id] );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Remove all symbols in the table.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CUtlSymbolTable::RemoveAll()
|
||||
{
|
||||
m_Lookup.RemoveAll();
|
||||
|
||||
for ( int i=0; i < m_StringPools.Count(); i++ )
|
||||
free( m_StringPools[i] );
|
||||
|
||||
m_StringPools.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pFileName -
|
||||
// Output : FileNameHandle_t
|
||||
//-----------------------------------------------------------------------------
|
||||
FileNameHandle_t CUtlFilenameSymbolTable::FindOrAddFileName( char const *pFileName )
|
||||
{
|
||||
if ( !pFileName )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fix slashes and make lower case first..
|
||||
char fn[ MAX_PATH ];
|
||||
Q_strncpy( fn, pFileName, sizeof( fn ) );
|
||||
Q_FixSlashes( fn );
|
||||
#ifdef _WIN32
|
||||
strlwr( fn );
|
||||
#endif
|
||||
|
||||
// Split the fn into constituent parts
|
||||
char basepath[ MAX_PATH ];
|
||||
Q_ExtractFilePath( fn, basepath, sizeof( basepath ) );
|
||||
|
||||
char filename[ MAX_PATH ];
|
||||
Q_strncpy( filename, fn + Q_strlen( basepath ), sizeof( filename ) );
|
||||
|
||||
FileNameHandleInternal_t handle;
|
||||
handle.path = g_CountedStringPool.ReferenceStringHandle(basepath);
|
||||
handle.file = g_CountedStringPool.ReferenceStringHandle(filename );
|
||||
|
||||
return *( FileNameHandle_t * )( &handle );
|
||||
}
|
||||
|
||||
FileNameHandle_t CUtlFilenameSymbolTable::FindFileName( char const *pFileName )
|
||||
{
|
||||
if ( !pFileName )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fix slashes and make lower case first..
|
||||
char fn[ MAX_PATH ];
|
||||
Q_strncpy( fn, pFileName, sizeof( fn ) );
|
||||
Q_FixSlashes( fn );
|
||||
#ifdef _WIN32
|
||||
strlwr( fn );
|
||||
#endif
|
||||
|
||||
// Split the fn into constituent parts
|
||||
char basepath[ MAX_PATH ];
|
||||
Q_ExtractFilePath( fn, basepath, sizeof( basepath ) );
|
||||
|
||||
char filename[ MAX_PATH ];
|
||||
Q_strncpy( filename, fn + Q_strlen( basepath ), sizeof( filename ) );
|
||||
|
||||
FileNameHandleInternal_t handle;
|
||||
handle.path = g_CountedStringPool.FindStringHandle(basepath);
|
||||
handle.file = g_CountedStringPool.FindStringHandle(filename);
|
||||
|
||||
if( handle.path == NULL || handle.file == NULL )
|
||||
return NULL;
|
||||
|
||||
return *( FileNameHandle_t * )( &handle );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : handle -
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CUtlFilenameSymbolTable::String( const FileNameHandle_t& handle, char *buf, int buflen )
|
||||
{
|
||||
buf[ 0 ] = 0;
|
||||
|
||||
FileNameHandleInternal_t *internal = ( FileNameHandleInternal_t * )&handle;
|
||||
if ( !internal )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char const *path = g_CountedStringPool.HandleToString(internal->path);
|
||||
if ( !path )
|
||||
return false;
|
||||
|
||||
Q_strncpy( buf, path, buflen );
|
||||
char const *fn = g_CountedStringPool.HandleToString(internal->file);
|
||||
if ( !fn )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_strncat( buf, fn, buflen, COPY_ALL_CHARACTERS );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
74
tier1/xboxstubs.cpp
Normal file
74
tier1/xboxstubs.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Stubs Xbox functions when compiling for other platforms
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef _XBOX
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif _LINUX
|
||||
#define ERROR_GEN_FAILURE 1
|
||||
#define GetTickCount() Plat_FloatTime()
|
||||
#else
|
||||
#error "implement me"
|
||||
#endif
|
||||
#include "xbox/xboxstubs.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
void XBX_DebugString(xverbose_e verbose, COLORREF color, const char* format, ...)
|
||||
{
|
||||
}
|
||||
|
||||
void XBX_ProcessEvents( void )
|
||||
{
|
||||
}
|
||||
|
||||
void XInitDevices( DWORD dwPreallocTypeCount, PXDEVICE_PREALLOC_TYPE PreallocTypes )
|
||||
{
|
||||
}
|
||||
|
||||
DWORD XGetDevices(PXPP_DEVICE_TYPE DeviceType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool XGetDeviceChanges(PXPP_DEVICE_TYPE DeviceType, DWORD *pdwInsertions, DWORD *pdwRemovals)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE XInputOpen(PXPP_DEVICE_TYPE DeviceType, DWORD dwPort, DWORD dwSlot, PXINPUT_POLLING_PARAMETERS pPollingParameters)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void XInputClose(HANDLE hDevice)
|
||||
{
|
||||
}
|
||||
|
||||
DWORD XInputSetState(HANDLE hDevice, PXINPUT_FEEDBACK pFeedback)
|
||||
{
|
||||
return ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
DWORD XInputGetState(HANDLE hDevice, PXINPUT_STATE pState)
|
||||
{
|
||||
return ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
DWORD XInputPoll(HANDLE hDevice)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int XBX_GetSystemTime( void )
|
||||
{
|
||||
return (unsigned int)GetTickCount();
|
||||
}
|
||||
|
||||
#endif // _XBOX
|
Reference in New Issue
Block a user