mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-11 11:19:09 +00:00
Merge branch 'master' into windows
This commit is contained in:
+13
-13
@@ -119,21 +119,21 @@
|
||||
#define _T( arg ) arg
|
||||
#endif
|
||||
#define INVALID_HANDLE_VALUE (void*)-1
|
||||
#define CloseHandle( arg ) close( (int) arg )
|
||||
#define CloseHandle( arg ) close( (intptr_t) arg )
|
||||
#define ZeroMemory( ptr, size ) memset( ptr, 0, size )
|
||||
#define FILE_CURRENT SEEK_CUR
|
||||
#define FILE_BEGIN SEEK_SET
|
||||
#define FILE_END SEEK_END
|
||||
#define CreateDirectory( dir, ign ) mkdir( dir, S_IRWXU | S_IRWXG | S_IRWXO )
|
||||
#define SetFilePointer( handle, pos, ign, dir ) lseek( (int) handle, pos, dir )
|
||||
#define SetFilePointer( handle, pos, ign, dir ) lseek( (intptr_t) handle, pos, dir )
|
||||
bool ReadFile( void *handle, void *outbuf, unsigned int toread, unsigned int *nread, void *ignored )
|
||||
{
|
||||
*nread = read( (int) handle, outbuf, toread );
|
||||
*nread = read( (intptr_t) handle, outbuf, toread );
|
||||
return *nread == toread;
|
||||
}
|
||||
bool WriteFile( void *handle, void *buf, unsigned int towrite, unsigned int *written, void *ignored )
|
||||
{
|
||||
*written = write( (int) handle, buf, towrite );
|
||||
*written = write( (intptr_t) handle, buf, towrite );
|
||||
return *written == towrite;
|
||||
}
|
||||
|
||||
@@ -2778,8 +2778,8 @@ LUFILE *lufopen(void *z,unsigned int len,DWORD flags,ZRESULT *err)
|
||||
#ifdef _WIN32
|
||||
res = DuplicateHandle(GetCurrentProcess(),hf,GetCurrentProcess(),&h,0,FALSE,DUPLICATE_SAME_ACCESS) == TRUE;
|
||||
#else
|
||||
h = (void*) dup( (int)hf );
|
||||
res = (int) dup >= 0;
|
||||
h = (void*)(intptr_t) dup( (intptr_t)hf );
|
||||
res = (intptr_t) dup >= 0;
|
||||
#endif
|
||||
if (!res)
|
||||
{
|
||||
@@ -2793,7 +2793,7 @@ LUFILE *lufopen(void *z,unsigned int len,DWORD flags,ZRESULT *err)
|
||||
h = CreateFile((const TCHAR *)z, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#else
|
||||
h = (void*) open( (const TCHAR *)z, O_RDONLY );
|
||||
h = (void*)(intptr_t) open( (const TCHAR *)z, O_RDONLY );
|
||||
#endif
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -2806,7 +2806,7 @@ LUFILE *lufopen(void *z,unsigned int len,DWORD flags,ZRESULT *err)
|
||||
canseek = (type==FILE_TYPE_DISK);
|
||||
#else
|
||||
struct stat buf;
|
||||
fstat( (int)h, &buf );
|
||||
fstat( (intptr_t)h, &buf );
|
||||
canseek = buf.st_mode & S_IFREG;
|
||||
#endif
|
||||
}
|
||||
@@ -4198,7 +4198,7 @@ ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags)
|
||||
h = ::CreateFile((const TCHAR*)dst, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
ze.attr, NULL);
|
||||
#else
|
||||
h = (void*) open( (const TCHAR*)dst, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
|
||||
h = (void*)(intptr_t)open( (const TCHAR*)dst, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4235,7 +4235,7 @@ ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags)
|
||||
settime=true;
|
||||
#else
|
||||
struct stat sbuf;
|
||||
fstat( (int)h, &sbuf );
|
||||
fstat( (intptr_t)h, &sbuf );
|
||||
settime = ( sbuf.st_mode & S_IFREG );
|
||||
#endif
|
||||
|
||||
@@ -4244,19 +4244,19 @@ ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags)
|
||||
#ifdef _WIN32
|
||||
SetFileTime(h,&ze.ctime,&ze.atime,&ze.mtime);
|
||||
#elif defined( ANDROID )
|
||||
struct timespec ts[2];
|
||||
struct timespec ts[2];
|
||||
ts[0].tv_sec = ze.atime;
|
||||
ts[0].tv_nsec = 0;
|
||||
ts[1].tv_sec = ze.mtime;
|
||||
ts[1].tv_nsec = 0;
|
||||
utimensat((int)h, NULL, ts, 0);
|
||||
utimensat((intptr_t)h, NULL, ts, 0);
|
||||
#else
|
||||
struct timeval tv[2];
|
||||
tv[0].tv_sec = ze.atime;
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = ze.mtime;
|
||||
tv[1].tv_usec = 0;
|
||||
futimes( (int)h, tv );
|
||||
futimes( (intptr_t)h, tv );
|
||||
#endif
|
||||
}
|
||||
if (flags!=ZIP_HANDLE)
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@
|
||||
static ZRESULT lasterrorZ=ZR_OK;
|
||||
#else
|
||||
#include "tier0/threadtools.h"
|
||||
static CThreadLocalInt<ZRESULT> lasterrorZ;
|
||||
static CTHREADLOCALINTEGER(ZRESULT) lasterrorZ;
|
||||
#endif
|
||||
|
||||
typedef unsigned char uch; // unsigned 8-bit value
|
||||
|
||||
@@ -278,14 +278,18 @@ public:
|
||||
Vector ret(0,0,0);
|
||||
int nfaces=0;
|
||||
for(int f=0;f<6;f++)
|
||||
{
|
||||
if (face_maps[f].RGBAData)
|
||||
{
|
||||
nfaces++;
|
||||
ret+=face_maps[f].AverageColor();
|
||||
}
|
||||
if (nfaces)
|
||||
ret*=(1.0/nfaces);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (nfaces)
|
||||
ret*=(1.0/nfaces);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
float BrightestColor(void)
|
||||
@@ -293,12 +297,14 @@ public:
|
||||
float ret=0.0;
|
||||
int nfaces=0;
|
||||
for(int f=0;f<6;f++)
|
||||
{
|
||||
if (face_maps[f].RGBAData)
|
||||
{
|
||||
nfaces++;
|
||||
ret=max(ret,face_maps[f].BrightestColor());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
|
||||
enum NormalDecodeMode_t
|
||||
{
|
||||
NORMAL_DECODE_NONE = 0
|
||||
NORMAL_DECODE_NONE = 0,
|
||||
NORMAL_DECODE_ATI2N,
|
||||
NORMAL_DECODE_ATI2N_ALPHA
|
||||
};
|
||||
|
||||
// Forward declaration
|
||||
|
||||
+10
-4
@@ -21,6 +21,8 @@
|
||||
#include "convar.h"
|
||||
#include "tier0/tslist.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "mathlib/compressed_vector.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "posedebugger.h"
|
||||
#endif
|
||||
@@ -378,14 +380,18 @@ void CalcBoneQuaternion( int frame, float s,
|
||||
{
|
||||
if ( panim->flags & STUDIO_ANIM_RAWROT )
|
||||
{
|
||||
q = *(panim->pQuat48());
|
||||
Quaternion48 tmp;
|
||||
memcpy( &tmp, panim->pQuat48(), sizeof(Quaternion48) );
|
||||
q = tmp;
|
||||
Assert( q.IsValid() );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( panim->flags & STUDIO_ANIM_RAWROT2 )
|
||||
{
|
||||
q = *(panim->pQuat64());
|
||||
Quaternion64 tmp;
|
||||
memcpy( &tmp, panim->pQuat64(), sizeof(Quaternion64) );
|
||||
q = tmp;
|
||||
Assert( q.IsValid() );
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -663,7 +663,7 @@ public:
|
||||
CDispCornerNeighbors m_CornerNeighbors[4]; // Indexed by CORNER_ defines.
|
||||
|
||||
enum unnamed { ALLOWEDVERTS_SIZE = PAD_NUMBER( MAX_DISPVERTS, 32 ) / 32 };
|
||||
unsigned long m_AllowedVerts[ALLOWEDVERTS_SIZE]; // This is built based on the layout and sizes of our neighbors
|
||||
unsigned int m_AllowedVerts[ALLOWEDVERTS_SIZE]; // This is built based on the layout and sizes of our neighbors
|
||||
// and tells us which vertices are allowed to be active.
|
||||
};
|
||||
|
||||
|
||||
+12
-12
@@ -35,16 +35,16 @@ public:
|
||||
void ElementMoved( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs );
|
||||
|
||||
// Enumerate elements in a particular leaf
|
||||
bool EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context );
|
||||
bool EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, intp context );
|
||||
|
||||
// For convenience, enumerates the leaves along a ray, box, etc.
|
||||
bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context );
|
||||
bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context );
|
||||
bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context );
|
||||
bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context );
|
||||
bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, intp context );
|
||||
bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, intp context );
|
||||
bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, intp context );
|
||||
bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context );
|
||||
|
||||
// methods of IBSPLeafEnumerator
|
||||
bool EnumerateLeaf( int leaf, int context );
|
||||
bool EnumerateLeaf( int leaf, intp context );
|
||||
|
||||
// Is the element in any leaves at all?
|
||||
bool IsElementInTree( BSPTreeDataHandle_t handle ) const;
|
||||
@@ -223,7 +223,7 @@ void CBSPTreeData::AddHandleToLeaf( int leaf, BSPTreeDataHandle_t handle )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inserts an element into the tree
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBSPTreeData::EnumerateLeaf( int leaf, int context )
|
||||
bool CBSPTreeData::EnumerateLeaf( int leaf, intp context )
|
||||
{
|
||||
BSPTreeDataHandle_t handle = (BSPTreeDataHandle_t)context;
|
||||
AddHandleToLeaf( leaf, handle );
|
||||
@@ -302,7 +302,7 @@ int CBSPTreeData::CountElementsInLeaf( int leaf )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enumerate elements in a particular leaf
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBSPTreeData::EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context )
|
||||
bool CBSPTreeData::EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, intp context )
|
||||
{
|
||||
#ifdef DBGFLAG_ASSERT
|
||||
// The enumeration method better damn well not change this list...
|
||||
@@ -330,22 +330,22 @@ bool CBSPTreeData::EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pE
|
||||
//-----------------------------------------------------------------------------
|
||||
// For convenience, enumerates the leaves along a ray, box, etc.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBSPTreeData::EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context )
|
||||
bool CBSPTreeData::EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, intp context )
|
||||
{
|
||||
return m_pBSPTree->EnumerateLeavesAtPoint( pt, pEnum, context );
|
||||
}
|
||||
|
||||
bool CBSPTreeData::EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context )
|
||||
bool CBSPTreeData::EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, intp context )
|
||||
{
|
||||
return m_pBSPTree->EnumerateLeavesInBox( mins, maxs, pEnum, context );
|
||||
}
|
||||
|
||||
bool CBSPTreeData::EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context )
|
||||
bool CBSPTreeData::EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, intp context )
|
||||
{
|
||||
return m_pBSPTree->EnumerateLeavesInSphere( center, radius, pEnum, context );
|
||||
}
|
||||
|
||||
bool CBSPTreeData::EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context )
|
||||
bool CBSPTreeData::EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context )
|
||||
{
|
||||
return m_pBSPTree->EnumerateLeavesAlongRay( ray, pEnum, context );
|
||||
}
|
||||
|
||||
+11
-11
@@ -58,7 +58,7 @@ public:
|
||||
// that passes the test; return true to continue enumerating,
|
||||
// false to stop
|
||||
|
||||
virtual bool EnumerateLeaf( int leaf, int context ) = 0;
|
||||
virtual bool EnumerateLeaf( int leaf, intp context ) = 0;
|
||||
};
|
||||
|
||||
abstract_class ISpatialQuery
|
||||
@@ -68,10 +68,10 @@ public:
|
||||
virtual int LeafCount() const = 0;
|
||||
|
||||
// Enumerates the leaves along a ray, box, etc.
|
||||
virtual bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
virtual bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
virtual bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ abstract_class IBSPTreeDataEnumerator
|
||||
{
|
||||
public:
|
||||
// call back with a userId and a context
|
||||
virtual bool FASTCALL EnumerateElement( int userId, int context ) = 0;
|
||||
virtual bool FASTCALL EnumerateElement( int userId, intp context ) = 0;
|
||||
};
|
||||
|
||||
abstract_class IBSPTreeData
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
virtual void ElementMoved( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs ) = 0;
|
||||
|
||||
// Enumerate elements in a particular leaf
|
||||
virtual bool EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, intp context ) = 0;
|
||||
|
||||
// Is the element in any leaves at all?
|
||||
virtual bool IsElementInTree( BSPTreeDataHandle_t handle ) const = 0;
|
||||
@@ -117,10 +117,10 @@ public:
|
||||
// NOTE: These methods call through to the functions in the attached
|
||||
// ISpatialQuery
|
||||
// For convenience, enumerates the leaves along a ray, box, etc.
|
||||
virtual bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ) = 0;
|
||||
virtual bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
virtual bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
virtual bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
//#include <stdafx.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include "builddisp.h"
|
||||
#include "collisionutils.h"
|
||||
#include "tier1/strtools.h"
|
||||
@@ -841,9 +840,9 @@ void CCoreDispInfo::InitDispInfo( int power, int minTess, float smoothingAngle,
|
||||
void CCoreDispInfo::InitDispInfo( int power, int minTess, float smoothingAngle, const CDispVert *pVerts,
|
||||
const CDispTri *pTris )
|
||||
{
|
||||
Vector vectors[MAX_DISPVERTS];
|
||||
float dists[MAX_DISPVERTS];
|
||||
float alphas[MAX_DISPVERTS];
|
||||
static Vector vectors[MAX_DISPVERTS];
|
||||
static float dists[MAX_DISPVERTS];
|
||||
static float alphas[MAX_DISPVERTS];
|
||||
|
||||
int nVerts = NUM_DISP_POWER_VERTS( power );
|
||||
for ( int i=0; i < nVerts; i++ )
|
||||
|
||||
+1
-1
@@ -790,7 +790,7 @@ public:
|
||||
|
||||
virtual bool IsConnectedUserInfoChangeAllowed( IConVar *pCvar ) = 0;
|
||||
|
||||
virtual void IN_TouchEvent( int type, int fingerId, int x, int y ) = 0;
|
||||
virtual void IN_TouchEvent( uint data, uint data2, uint data3, uint data4 ) = 0;
|
||||
};
|
||||
|
||||
#define CLIENT_DLL_INTERFACE_VERSION "VClient017"
|
||||
|
||||
@@ -635,14 +635,18 @@ bool IsOBBIntersectingOBB( const Vector &vecOrigin1, const QAngle &vecAngles1, c
|
||||
}
|
||||
|
||||
// NOTE: This is only very slightly faster on high end PCs and x360
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define USE_SIMD_RAY_CHECKS 0
|
||||
#else
|
||||
#define USE_SIMD_RAY_CHECKS 1
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns true if there's an intersection between box and ray
|
||||
//-----------------------------------------------------------------------------
|
||||
bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax,
|
||||
const Vector& origin, const Vector& vecDelta, float flTolerance )
|
||||
{
|
||||
|
||||
#if USE_SIMD_RAY_CHECKS
|
||||
// Load the unaligned ray/box parameters into SIMD registers
|
||||
fltx4 start = LoadUnaligned3SIMD(origin.Base());
|
||||
@@ -695,7 +699,7 @@ bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax,
|
||||
return IsAllZeros(separation);
|
||||
#else
|
||||
// On the x360, we force use of the SIMD functions.
|
||||
#if defined(_X360)
|
||||
#if defined(_X360)
|
||||
if (IsX360())
|
||||
{
|
||||
fltx4 delta = LoadUnaligned3SIMD(vecDelta.Base());
|
||||
@@ -766,7 +770,7 @@ bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax,
|
||||
bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax,
|
||||
const Vector& origin, const Vector& vecDelta,
|
||||
const Vector& vecInvDelta, float flTolerance )
|
||||
{
|
||||
{
|
||||
#if USE_SIMD_RAY_CHECKS
|
||||
// Load the unaligned ray/box parameters into SIMD registers
|
||||
fltx4 start = LoadUnaligned3SIMD(origin.Base());
|
||||
|
||||
@@ -35,7 +35,7 @@ class IDataCache;
|
||||
//---------------------------------------------------------
|
||||
// Unique (per section) identifier for a cache item defined by client
|
||||
//---------------------------------------------------------
|
||||
typedef uint32 DataCacheClientID_t;
|
||||
typedef uintp DataCacheClientID_t;
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
@@ -491,7 +491,7 @@ public:
|
||||
m_pCache->EnsureCapacity(STORAGE_TYPE::EstimatedSize(createParams));
|
||||
STORAGE_TYPE *pStore = STORAGE_TYPE::CreateResource( createParams );
|
||||
DataCacheHandle_t handle;
|
||||
m_pCache->AddEx( (DataCacheClientID_t)pStore, pStore, pStore->Size(), flags, &handle);
|
||||
m_pCache->AddEx( (DataCacheClientID_t)(uintp)pStore, pStore, pStore->Size(), flags, &handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,17 @@ namespace OptimizedModel
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef unsigned short MDLHandle_t;
|
||||
|
||||
// MoeMod : integer promotion keeps sign on arm, but discards sign on x86
|
||||
inline MDLHandle_t VoidPtrToMDLHandle( void *ptr )
|
||||
{
|
||||
return ( MDLHandle_t ) ( ( uintp ) ptr & 0xffff );
|
||||
}
|
||||
|
||||
inline void* MDLHandleToVirtual( MDLHandle_t hndl )
|
||||
{
|
||||
return (void*)(uintp)hndl;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
MDLHANDLE_INVALID = (MDLHandle_t)~0
|
||||
|
||||
+13
-9
@@ -62,8 +62,10 @@ typedef enum _fieldtypes
|
||||
FIELD_INTERVAL, // a start and range floating point interval ( e.g., 3.2->3.6 == 3.2 and 0.4 )
|
||||
FIELD_MODELINDEX, // a model index
|
||||
FIELD_MATERIALINDEX, // a material index (using the material precache string table)
|
||||
|
||||
|
||||
FIELD_VECTOR2D, // 2 floats
|
||||
FIELD_INTEGER64, // 64bit integer
|
||||
FIELD_POINTER,
|
||||
|
||||
FIELD_TYPECOUNT, // MUST BE LAST
|
||||
} fieldtype_t;
|
||||
@@ -93,7 +95,7 @@ public:
|
||||
#define FIELD_BITS( _fieldType ) (FIELD_SIZE( _fieldType ) * 8)
|
||||
|
||||
DECLARE_FIELD_SIZE( FIELD_FLOAT, sizeof(float) )
|
||||
DECLARE_FIELD_SIZE( FIELD_STRING, sizeof(int) )
|
||||
|
||||
DECLARE_FIELD_SIZE( FIELD_VECTOR, 3 * sizeof(float) )
|
||||
DECLARE_FIELD_SIZE( FIELD_VECTOR2D, 2 * sizeof(float) )
|
||||
DECLARE_FIELD_SIZE( FIELD_QUATERNION, 4 * sizeof(float))
|
||||
@@ -102,14 +104,16 @@ DECLARE_FIELD_SIZE( FIELD_BOOLEAN, sizeof(char))
|
||||
DECLARE_FIELD_SIZE( FIELD_SHORT, sizeof(short))
|
||||
DECLARE_FIELD_SIZE( FIELD_CHARACTER, sizeof(char))
|
||||
DECLARE_FIELD_SIZE( FIELD_COLOR32, sizeof(int))
|
||||
DECLARE_FIELD_SIZE( FIELD_CLASSPTR, sizeof(int))
|
||||
DECLARE_FIELD_SIZE( FIELD_EHANDLE, sizeof(int))
|
||||
DECLARE_FIELD_SIZE( FIELD_EDICT, sizeof(int))
|
||||
DECLARE_FIELD_SIZE( FIELD_STRING, sizeof(void*))
|
||||
DECLARE_FIELD_SIZE( FIELD_POINTER, sizeof(void*))
|
||||
DECLARE_FIELD_SIZE( FIELD_MODELNAME, sizeof(void*))
|
||||
DECLARE_FIELD_SIZE( FIELD_SOUNDNAME, sizeof(void*))
|
||||
DECLARE_FIELD_SIZE( FIELD_EHANDLE, sizeof(void*))
|
||||
DECLARE_FIELD_SIZE( FIELD_CLASSPTR, sizeof(void*))
|
||||
DECLARE_FIELD_SIZE( FIELD_EDICT, sizeof(void*))
|
||||
DECLARE_FIELD_SIZE( FIELD_POSITION_VECTOR, 3 * sizeof(float))
|
||||
DECLARE_FIELD_SIZE( FIELD_TIME, sizeof(float))
|
||||
DECLARE_FIELD_SIZE( FIELD_TICK, sizeof(int))
|
||||
DECLARE_FIELD_SIZE( FIELD_MODELNAME, sizeof(int))
|
||||
DECLARE_FIELD_SIZE( FIELD_SOUNDNAME, sizeof(int))
|
||||
DECLARE_FIELD_SIZE( FIELD_INPUT, sizeof(int))
|
||||
#ifdef POSIX
|
||||
// pointer to members under gnuc are 8bytes if you have a virtual func
|
||||
@@ -128,7 +132,7 @@ DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) )
|
||||
#define ARRAYSIZE2D(p) (sizeof(p)/sizeof(p[0][0]))
|
||||
#define SIZE_OF_ARRAY(p) _ARRAYSIZE(p)
|
||||
|
||||
#define _offsetof(s,m) ((size_t)&(((s *)0)->m))
|
||||
#define _offsetof(s,m) ((int)(intp)&(((s *)0)->m))
|
||||
|
||||
#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { _offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance }
|
||||
#define DEFINE_FIELD_NULL { FIELD_VOID,0, {0,0},0,0,0,0,0,0}
|
||||
@@ -431,7 +435,7 @@ public:
|
||||
{
|
||||
for ( int i = 0; i < m_Names.Count(); i++ )
|
||||
{
|
||||
delete m_Names[i];
|
||||
delete[] m_Names[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -429,7 +429,13 @@ void CDispCollTree::AABBTree_CreateLeafs( void )
|
||||
}
|
||||
}
|
||||
|
||||
void CDispCollTree::AABBTree_GenerateBoxes_r( int nodeIndex, Vector *pMins, Vector *pMaxs )
|
||||
#if COMPILER_CLANG
|
||||
#define NOASAN __attribute__((no_sanitize("address")))
|
||||
#else
|
||||
#define NOASAN
|
||||
#endif
|
||||
|
||||
void NOASAN CDispCollTree::AABBTree_GenerateBoxes_r( int nodeIndex, Vector *pMins, Vector *pMaxs )
|
||||
{
|
||||
// leaf
|
||||
ClearBounds( *pMins, *pMaxs );
|
||||
@@ -461,6 +467,7 @@ void CDispCollTree::AABBTree_GenerateBoxes_r( int nodeIndex, Vector *pMins, Vect
|
||||
}
|
||||
}
|
||||
|
||||
#undef NOASAN
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
|
||||
+5
-4
@@ -91,11 +91,12 @@
|
||||
|
||||
|
||||
// Use this to extern send and receive datatables, and reference them.
|
||||
#define EXTERN_SEND_TABLE(tableName) namespace tableName {extern SendTable g_SendTable;}
|
||||
#define EXTERN_RECV_TABLE(tableName) namespace tableName {extern RecvTable g_RecvTable;}
|
||||
#define EXTERN_SEND_TABLE(tableName) namespace tableName {extern SendTable g_SendTable; extern int g_SendTableInit;}
|
||||
#define EXTERN_RECV_TABLE(tableName) namespace tableName {extern RecvTable g_RecvTable; extern int g_RecvTableInit;}
|
||||
|
||||
#define REFERENCE_SEND_TABLE(tableName) tableName::g_SendTable
|
||||
#define REFERENCE_RECV_TABLE(tableName) tableName::g_RecvTable
|
||||
// MoeMod: ODR Use it to prevent being dropped by linker
|
||||
#define REFERENCE_SEND_TABLE(tableName) (tableName::g_SendTableInit + &tableName::g_SendTableInit, tableName::g_SendTable)
|
||||
#define REFERENCE_RECV_TABLE(tableName) (tableName::g_RecvTableInit + &tableName::g_RecvTableInit, tableName::g_RecvTable)
|
||||
|
||||
|
||||
class SendProp;
|
||||
|
||||
+1
-1
@@ -493,7 +493,7 @@ void RecvProxy_Int32ToInt16( const CRecvProxyData *pData, void *pStruct, void *p
|
||||
|
||||
void RecvProxy_Int32ToInt32( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
*((unsigned long*)pOut) = (unsigned long)pData->m_Value.m_Int;
|
||||
*((uint32*)pOut) = (uint32)pData->m_Value.m_Int;
|
||||
}
|
||||
|
||||
#ifdef SUPPORTS_INT64
|
||||
|
||||
+5
-5
@@ -265,7 +265,7 @@ void SendProxy_UInt16ToInt32( const SendProp *pProp, const void *pStruct, const
|
||||
|
||||
void SendProxy_UInt32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
|
||||
{
|
||||
*((unsigned long*)&pOut->m_Int) = *((unsigned long*)pData);
|
||||
memcpy( &pOut->m_Int, pData, sizeof(uint32) );
|
||||
}
|
||||
#ifdef SUPPORTS_INT64
|
||||
void SendProxy_UInt64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
|
||||
@@ -317,18 +317,18 @@ void* SendProxy_SendLocalDataTable( const SendProp *pProp, const void *pStruct,
|
||||
// ---------------------------------------------------------------------- //
|
||||
float AssignRangeMultiplier( int nBits, double range )
|
||||
{
|
||||
unsigned long iHighValue;
|
||||
uint32 iHighValue;
|
||||
if ( nBits == 32 )
|
||||
iHighValue = 0xFFFFFFFE;
|
||||
else
|
||||
iHighValue = ((1 << (unsigned long)nBits) - 1);
|
||||
iHighValue = ((1 << (uint32)nBits) - 1);
|
||||
|
||||
float fHighLowMul = iHighValue / range;
|
||||
if ( CloseEnough( range, 0 ) )
|
||||
fHighLowMul = iHighValue;
|
||||
|
||||
// If the precision is messing us up, then adjust it so it won't.
|
||||
if ( (unsigned long)(fHighLowMul * range) > iHighValue ||
|
||||
if ( (uint32)(fHighLowMul * range) > iHighValue ||
|
||||
(fHighLowMul * range) > (double)iHighValue )
|
||||
{
|
||||
// Squeeze it down smaller and smaller until it's going to produce an integer
|
||||
@@ -338,7 +338,7 @@ float AssignRangeMultiplier( int nBits, double range )
|
||||
for ( i=0; i < ARRAYSIZE( multipliers ); i++ )
|
||||
{
|
||||
fHighLowMul = (float)( iHighValue / range ) * multipliers[i];
|
||||
if ( (unsigned long)(fHighLowMul * range) > iHighValue ||
|
||||
if ( (uint32)(fHighLowMul * range) > iHighValue ||
|
||||
(fHighLowMul * range) > (double)iHighValue )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Some macros for the raytraces-in-think-function-counter.
|
||||
// They're in a header because they're included in a bunch of
|
||||
// places, but on some cases they need to define files and in
|
||||
// others only extern them.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef THINK_TRACE_COUNTER_H
|
||||
#define THINK_TRACE_COUNTER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define THINK_TRACE_COUNTER_COMPILED 1 // without this, all the code is elided.
|
||||
|
||||
|
||||
#ifdef THINK_TRACE_COUNTER_COMPILED
|
||||
// create a macro that is true if we are allowed to debug traces during thinks, and compiles out to nothing otherwise.
|
||||
#if defined( _GAMECONSOLE ) || defined( NO_STEAM )
|
||||
#define DEBUG_THINK_TRACE_COUNTER_ALLOWED() (!IsCert())
|
||||
#else
|
||||
#ifdef THINK_TRACE_COUNTER_COMPILE_FUNCTIONS_ENGINE
|
||||
bool DEBUG_THINK_TRACE_COUNTER_ALLOWED()
|
||||
{
|
||||
// done as a static var to defer initialization until Steam is ready,
|
||||
// but also to have the fastest check at runtime (rather than calling through
|
||||
// the API each time)
|
||||
static bool bIsPublic = GetSteamUniverse() == k_EUniversePublic;
|
||||
return !bIsPublic;
|
||||
}
|
||||
#elif defined( THINK_TRACE_COUNTER_COMPILE_FUNCTIONS_SERVER )
|
||||
bool DEBUG_THINK_TRACE_COUNTER_ALLOWED()
|
||||
{
|
||||
// done as a static var to defer initialization until Steam is ready,
|
||||
// but also to have the fastest check at runtime (rather than calling through
|
||||
// the API each time)
|
||||
static bool bIsPublic = steamapicontext->SteamUtils() != NULL && steamapicontext->SteamUtils()->GetConnectedUniverse() == k_EUniversePublic;
|
||||
return !bIsPublic;
|
||||
}
|
||||
#else
|
||||
extern bool DEBUG_THINK_TRACE_COUNTER_ALLOWED();
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif // THINK_TRACE_COUNTER_H
|
||||
@@ -23,7 +23,6 @@ const char* ParseFileInternal( const char* pFileBytes, OUT_Z_CAP(nMaxTokenLen) c
|
||||
template <size_t count>
|
||||
const char* ParseFile( const char* pFileBytes, OUT_Z_ARRAY char (&pTokenOut)[count], bool* pWasQuoted, characterset_t *pCharSet = NULL, unsigned int nMaxTokenLen = (unsigned int)-1 )
|
||||
{
|
||||
(void*)nMaxTokenLen; // Avoid unreferenced variable warnings.
|
||||
return ParseFileInternal( pFileBytes, pTokenOut, pWasQuoted, pCharSet, count );
|
||||
}
|
||||
|
||||
|
||||
@@ -307,6 +307,9 @@ static bool Sys_GetExecutableName( char *out, int len )
|
||||
|
||||
bool FileSystem_GetExecutableDir( char *exedir, int exeDirLen )
|
||||
{
|
||||
#ifdef ANDROID
|
||||
Q_snprintf( exedir, exeDirLen, "%s", getenv("APP_LIB_PATH") );
|
||||
#else
|
||||
exedir[0] = 0;
|
||||
|
||||
if ( s_bUseVProjectBinDir )
|
||||
@@ -341,11 +344,7 @@ bool FileSystem_GetExecutableDir( char *exedir, int exeDirLen )
|
||||
|
||||
Q_FixSlashes( exedir );
|
||||
|
||||
#ifdef ANDROID
|
||||
const char* libDir = "lib";
|
||||
#else
|
||||
const char* libDir = "bin";
|
||||
#endif
|
||||
|
||||
// Return the bin directory as the executable dir if it's not in there
|
||||
// because that's really where we're running from...
|
||||
@@ -357,6 +356,7 @@ bool FileSystem_GetExecutableDir( char *exedir, int exeDirLen )
|
||||
Q_strncat( exedir, libDir, exeDirLen, COPY_ALL_CHARACTERS );
|
||||
Q_FixSlashes( exedir );
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -581,6 +581,20 @@ FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo )
|
||||
}
|
||||
}
|
||||
|
||||
const char *ExtraVpkPaths = getenv( "EXTRAS_VPK_PATH" );
|
||||
char szAbsSearchPath[MAX_PATH];
|
||||
|
||||
if( ExtraVpkPaths )
|
||||
{
|
||||
CUtlStringList vecPaths;
|
||||
V_SplitString( ExtraVpkPaths, ",", vecPaths );
|
||||
|
||||
FOR_EACH_VEC( vecPaths, idxExtraPath )
|
||||
{
|
||||
FileSystem_AddLoadedSearchPath( initInfo, "GAME", vecPaths[idxExtraPath], false );
|
||||
}
|
||||
}
|
||||
|
||||
bool bLowViolence = initInfo.m_bLowViolence;
|
||||
for ( KeyValues *pCur=pSearchPaths->GetFirstValue(); pCur; pCur=pCur->GetNextValue() )
|
||||
{
|
||||
@@ -602,11 +616,12 @@ FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo )
|
||||
// We need a special identifier in the gameinfo.txt here because the base hl2 folder exists in different places.
|
||||
// In the case of a game or a Steam-launched dedicated server, all the necessary prior engine content is mapped in with the Steam depots,
|
||||
// so we can just use the path as-is.
|
||||
|
||||
pLocation += strlen( BASESOURCEPATHS_TOKEN );
|
||||
}
|
||||
|
||||
|
||||
CUtlStringList vecFullLocationPaths;
|
||||
char szAbsSearchPath[MAX_PATH];
|
||||
V_MakeAbsolutePath( szAbsSearchPath, sizeof( szAbsSearchPath ), pLocation, pszBaseDir );
|
||||
|
||||
// Now resolve any ./'s.
|
||||
|
||||
@@ -99,8 +99,6 @@ public:
|
||||
// Tells the entity that it's about to be destroyed due to the client receiving
|
||||
// an uncompressed update that's caused it to destroy all entities & recreate them.
|
||||
virtual void SetDestroyedOnRecreateEntities( void ) = 0;
|
||||
|
||||
virtual void OnDataUnchangedInPVS() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+1
-3
@@ -195,9 +195,7 @@ inline ConCommandBase * ICvar::Iterator::Get( void )
|
||||
// don't have to include tier1.h
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// These are marked DLL_EXPORT for Linux.
|
||||
DLL_EXPORT ICvar *cvar;
|
||||
extern ICvar *cvar;
|
||||
extern ICvar *g_pCVar;
|
||||
|
||||
|
||||
#endif // ICVAR_H
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "tier1/interface.h"
|
||||
#include "bitmap/imageformat.h"
|
||||
|
||||
typedef unsigned int ColorCorrectionHandle_t;
|
||||
typedef uintp ColorCorrectionHandle_t;
|
||||
struct ShaderColorCorrectionInfo_t;
|
||||
|
||||
#define COLORCORRECTION_INTERFACE_VERSION "COLORCORRECTION_VERSION_1"
|
||||
|
||||
@@ -1156,7 +1156,7 @@ inline void CVertexBuilder::FastAdvanceNVertices( int n )
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CVertexBuilder::FastVertex( const ModelVertexDX7_t &vertex )
|
||||
{
|
||||
#ifdef __arm__
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
FastVertexSSE( vertex );
|
||||
#else
|
||||
Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
|
||||
@@ -1244,11 +1244,11 @@ inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex )
|
||||
const char *pRead = (char *)&vertex;
|
||||
char *pCurrPos = (char *)m_pCurrPosition;
|
||||
__m128 m1 = _mm_load_ps( (float *)pRead );
|
||||
__m128 m2 = _mm_load_ps( (float *)((int)pRead + 16) );
|
||||
__m128 m3 = _mm_load_ps( (float *)((int)pRead + 32) );
|
||||
__m128 m2 = _mm_load_ps( (float *)((intp)pRead + 16) );
|
||||
__m128 m3 = _mm_load_ps( (float *)((intp)pRead + 32) );
|
||||
_mm_stream_ps( (float *)pCurrPos, m1 );
|
||||
_mm_stream_ps( (float *)((int)pCurrPos + 16), m2 );
|
||||
_mm_stream_ps( (float *)((int)pCurrPos + 32), m3 );
|
||||
_mm_stream_ps( (float *)((intp)pCurrPos + 16), m2 );
|
||||
_mm_stream_ps( (float *)((intp)pCurrPos + 32), m3 );
|
||||
#else
|
||||
Error( "Implement CMeshBuilder::FastVertexSSE(dx7)" );
|
||||
#endif
|
||||
@@ -1326,7 +1326,7 @@ inline void CVertexBuilder::Fast4VerticesSSE(
|
||||
|
||||
inline void CVertexBuilder::FastVertex( const ModelVertexDX8_t &vertex )
|
||||
{
|
||||
#ifdef __arm__
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
FastVertexSSE( vertex );
|
||||
#else
|
||||
Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
|
||||
@@ -1436,13 +1436,13 @@ inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex )
|
||||
:: "r" (pRead), "r" (pCurrPos) : "memory"); */
|
||||
|
||||
__m128 m1 = _mm_load_ps( (float *)pRead );
|
||||
__m128 m2 = _mm_load_ps( (float *)((int)pRead + 16) );
|
||||
__m128 m3 = _mm_load_ps( (float *)((int)pRead + 32) );
|
||||
__m128 m4 = _mm_load_ps( (float *)((int)pRead + 48) );
|
||||
__m128 m2 = _mm_load_ps( (float *)((intp)pRead + 16) );
|
||||
__m128 m3 = _mm_load_ps( (float *)((intp)pRead + 32) );
|
||||
__m128 m4 = _mm_load_ps( (float *)((intp)pRead + 48) );
|
||||
_mm_stream_ps( (float *)pCurrPos, m1 );
|
||||
_mm_stream_ps( (float *)((int)pCurrPos + 16), m2 );
|
||||
_mm_stream_ps( (float *)((int)pCurrPos + 32), m3 );
|
||||
_mm_stream_ps( (float *)((int)pCurrPos + 48), m4 );
|
||||
_mm_stream_ps( (float *)((intp)pCurrPos + 16), m2 );
|
||||
_mm_stream_ps( (float *)((intp)pCurrPos + 32), m3 );
|
||||
_mm_stream_ps( (float *)((intp)pCurrPos + 48), m4 );
|
||||
#else
|
||||
Error( "Implement CMeshBuilder::FastVertexSSE((dx8)" );
|
||||
#endif
|
||||
|
||||
@@ -149,7 +149,7 @@ class Quaternion64
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Quaternion64(void);
|
||||
Quaternion64(void) {};
|
||||
Quaternion64(vec_t X, vec_t Y, vec_t Z);
|
||||
|
||||
// assignment
|
||||
@@ -197,7 +197,7 @@ class Quaternion48
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Quaternion48(void);
|
||||
Quaternion48(void) {};
|
||||
Quaternion48(vec_t X, vec_t Y, vec_t Z);
|
||||
|
||||
// assignment
|
||||
|
||||
@@ -34,7 +34,7 @@ enum LightType_OptimizationFlags_t
|
||||
struct LightDesc_t
|
||||
{
|
||||
LightType_t m_Type; //< MATERIAL_LIGHT_xxx
|
||||
Vector m_Color; //< color+intensity
|
||||
Vector m_Color; //< color+intensity
|
||||
Vector m_Position; //< light source center position
|
||||
Vector m_Direction; //< for SPOT, direction it is pointing
|
||||
float m_Range; //< distance range for light.0=infinite
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
|
||||
LightDesc_t(void)
|
||||
{
|
||||
m_Type = MATERIAL_LIGHT_DISABLE;
|
||||
}
|
||||
|
||||
// constructors for various useful subtypes
|
||||
|
||||
@@ -457,6 +457,8 @@ void inline SinCos( float radians, float *sine, float *cosine )
|
||||
#elif defined( PLATFORM_WINDOWS_PC64 )
|
||||
*sine = sin( radians );
|
||||
*cosine = cos( radians );
|
||||
#elif defined( OSX )
|
||||
__sincosf(radians, sine, cosine);
|
||||
#elif defined( POSIX )
|
||||
sincosf(radians, sine, cosine);
|
||||
#endif
|
||||
@@ -1213,7 +1215,7 @@ FORCEINLINE int RoundFloatToInt(float f)
|
||||
};
|
||||
flResult = __fctiw( f );
|
||||
return pResult[1];
|
||||
#elif defined (__arm__)
|
||||
#elif defined (__arm__) || defined (__aarch64__)
|
||||
return (int)(f + 0.5f);
|
||||
#else
|
||||
#error Unknown architecture
|
||||
@@ -1245,7 +1247,7 @@ FORCEINLINE unsigned long RoundFloatToUnsignedLong(float f)
|
||||
Assert( pIntResult[1] >= 0 );
|
||||
return pResult[1];
|
||||
#else // !X360
|
||||
#ifdef __arm__
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
return (unsigned long)(f + 0.5f);
|
||||
#elif defined( PLATFORM_WINDOWS_PC64 )
|
||||
uint nRet = ( uint ) f;
|
||||
@@ -2168,7 +2170,7 @@ inline bool CloseEnough( const Vector &a, const Vector &b, float epsilon = EQUAL
|
||||
// Fast compare
|
||||
// maxUlps is the maximum error in terms of Units in the Last Place. This
|
||||
// specifies how big an error we are willing to accept in terms of the value
|
||||
// of the least significant digit of the floating point number’s
|
||||
// of the least significant digit of the floating point number�s
|
||||
// representation. maxUlps can also be interpreted in terms of how many
|
||||
// representable floats we are willing to accept between A and B.
|
||||
// This function will allow maxUlps-1 floats between A and B.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
|
||||
#if defined( _X360 )
|
||||
#include <xboxmath.h>
|
||||
#elif defined(__arm__)
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
#include "sse2neon.h"
|
||||
#else
|
||||
#include <xmmintrin.h>
|
||||
@@ -23,7 +23,7 @@
|
||||
#define USE_STDC_FOR_SIMD 0
|
||||
#endif
|
||||
|
||||
#if (!defined (__arm__) && !defined(_X360) && (USE_STDC_FOR_SIMD == 0))
|
||||
#if !(defined(_X360) && (USE_STDC_FOR_SIMD == 0))
|
||||
#define _SSE1 1
|
||||
#endif
|
||||
|
||||
@@ -1787,6 +1787,18 @@ FORCEINLINE fltx4 LoadAlignedSIMD( const VectorAligned & pSIMD )
|
||||
return SetWToZeroSIMD( LoadAlignedSIMD(pSIMD.Base()) );
|
||||
}
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
static __attribute__((no_sanitize("address"))) fltx4 LoadUnalignedSIMD( const void *pSIMD )
|
||||
{
|
||||
return _mm_loadu_ps( reinterpret_cast<const float *>( pSIMD ) );
|
||||
|
||||
}
|
||||
|
||||
static __attribute__((no_sanitize("address"))) fltx4 LoadUnaligned3SIMD( const void *pSIMD )
|
||||
{
|
||||
return _mm_loadu_ps( reinterpret_cast<const float *>( pSIMD ) );
|
||||
}
|
||||
#else
|
||||
FORCEINLINE fltx4 LoadUnalignedSIMD( const void *pSIMD )
|
||||
{
|
||||
return _mm_loadu_ps( reinterpret_cast<const float *>( pSIMD ) );
|
||||
@@ -1796,6 +1808,7 @@ FORCEINLINE fltx4 LoadUnaligned3SIMD( const void *pSIMD )
|
||||
{
|
||||
return _mm_loadu_ps( reinterpret_cast<const float *>( pSIMD ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
/// replicate a single 32 bit integer value to all 4 components of an m128
|
||||
FORCEINLINE fltx4 ReplicateIX4( int i )
|
||||
|
||||
+10
-12
@@ -23,6 +23,10 @@
|
||||
#include "tier0/dbg.h"
|
||||
#include "mathlib/math_pfns.h"
|
||||
|
||||
#if defined (__arm__) || defined(__aarch64__)
|
||||
#include "sse2neon.h"
|
||||
#endif
|
||||
|
||||
// forward declarations
|
||||
class Vector;
|
||||
class Vector2D;
|
||||
@@ -141,10 +145,8 @@ public:
|
||||
inline void Set( vec_t X, vec_t Y, vec_t Z, vec_t W );
|
||||
inline void InitZero( void );
|
||||
|
||||
#ifndef __arm__
|
||||
inline __m128 &AsM128() { return *(__m128*)&x; }
|
||||
inline const __m128 &AsM128() const { return *(const __m128*)&x; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
// No copy constructors allowed if we're in optimal mode
|
||||
@@ -616,9 +618,7 @@ inline void Vector4DAligned::Set( vec_t X, vec_t Y, vec_t Z, vec_t W )
|
||||
|
||||
inline void Vector4DAligned::InitZero( void )
|
||||
{
|
||||
#if defined (__arm__)
|
||||
x = y = z = w = 0;
|
||||
#elif !defined( _X360 )
|
||||
#if !defined( _X360 )
|
||||
this->AsM128() = _mm_set1_ps( 0.0f );
|
||||
#else
|
||||
this->AsM128() = __vspltisw( 0 );
|
||||
@@ -629,7 +629,7 @@ inline void Vector4DAligned::InitZero( void )
|
||||
inline void Vector4DMultiplyAligned( Vector4DAligned const& a, Vector4DAligned const& b, Vector4DAligned& c )
|
||||
{
|
||||
Assert( a.IsValid() && b.IsValid() );
|
||||
#if !defined( _X360 ) || defined (__arm__)
|
||||
#if !defined( _X360 )
|
||||
c.x = a.x * b.x;
|
||||
c.y = a.y * b.y;
|
||||
c.z = a.z * b.z;
|
||||
@@ -643,7 +643,7 @@ inline void Vector4DWeightMAD( vec_t w, Vector4DAligned const& vInA, Vector4DAli
|
||||
{
|
||||
Assert( vInA.IsValid() && vInB.IsValid() && IsFinite(w) );
|
||||
|
||||
#if !defined( _X360 ) || defined (__arm__)
|
||||
#if !defined( _X360 )
|
||||
vOutA.x += vInA.x * w;
|
||||
vOutA.y += vInA.y * w;
|
||||
vOutA.z += vInA.z * w;
|
||||
@@ -654,17 +654,16 @@ inline void Vector4DWeightMAD( vec_t w, Vector4DAligned const& vInA, Vector4DAli
|
||||
vOutB.z += vInB.z * w;
|
||||
vOutB.w += vInB.w * w;
|
||||
#else
|
||||
__vector4 temp;
|
||||
__vector4 temp;
|
||||
|
||||
temp = __lvlx( &w, 0 );
|
||||
temp = __vspltw( temp, 0 );
|
||||
temp = __lvlx( &w, 0 );
|
||||
temp = __vspltw( temp, 0 );
|
||||
|
||||
vOutA.AsM128() = __vmaddfp( vInA.AsM128(), temp, vOutA.AsM128() );
|
||||
vOutB.AsM128() = __vmaddfp( vInB.AsM128(), temp, vOutB.AsM128() );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __arm__
|
||||
inline void Vector4DWeightMADSSE( vec_t w, Vector4DAligned const& vInA, Vector4DAligned& vOutA, Vector4DAligned const& vInB, Vector4DAligned& vOutB )
|
||||
{
|
||||
Assert( vInA.IsValid() && vInB.IsValid() && IsFinite(w) );
|
||||
@@ -686,7 +685,6 @@ inline void Vector4DWeightMADSSE( vec_t w, Vector4DAligned const& vInA, Vector4D
|
||||
vOutB.AsM128() = __vmaddfp( vInB.AsM128(), temp, vOutB.AsM128() );
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VECTOR4D_H
|
||||
|
||||
|
||||
@@ -423,6 +423,12 @@ void MatrixInverseTranspose( const VMatrix& src, VMatrix& dst );
|
||||
//-----------------------------------------------------------------------------
|
||||
inline VMatrix::VMatrix()
|
||||
{
|
||||
Init(
|
||||
0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f
|
||||
);
|
||||
}
|
||||
|
||||
inline VMatrix::VMatrix(
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
|
||||
#pragma warning( disable : 4284 ) // warning C4284: return type for 'CNetworkVarT<int>::operator ->' is 'int *' (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation)
|
||||
|
||||
#define MyOffsetOf( type, var ) ( (int)&((type*)0)->var )
|
||||
#define MyOffsetOf( type, var ) ( (intp)&((type*)0)->var )
|
||||
|
||||
#ifdef _DEBUG
|
||||
extern bool g_bUseNetworkVars;
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ struct Vertex_t
|
||||
|
||||
// for sw skinned verts, these are indices into the global list of bones
|
||||
// for hw skinned verts, these are hardware bone indices
|
||||
char boneID[MAX_NUM_BONES_PER_VERT];
|
||||
byte boneID[MAX_NUM_BONES_PER_VERT];
|
||||
};
|
||||
|
||||
enum StripHeaderFlags_t {
|
||||
|
||||
@@ -1072,7 +1072,7 @@ public:
|
||||
float *GetInitialFloatAttributePtrForWrite( int nAttribute, int nParticleNumber );
|
||||
fltx4 *GetInitialM128AttributePtrForWrite( int nAttribute, size_t *pStrideOut );
|
||||
|
||||
void Simulate( float dt, bool updateBboxOnly );
|
||||
void Simulate( float dt, bool updateBboxOnly = false );
|
||||
void SkipToTime( float t );
|
||||
|
||||
// the camera objetc may be compared for equality against control point objects
|
||||
|
||||
+2
-1
@@ -11,13 +11,14 @@
|
||||
|
||||
#include "datamap.h"
|
||||
|
||||
|
||||
typedef struct phyheader_s
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
int size;
|
||||
int id;
|
||||
int solidCount;
|
||||
long checkSum; // checksum of source .mdl file
|
||||
int checkSum; // checksum of source .mdl file
|
||||
} phyheader_t;
|
||||
|
||||
#endif // PHYFILE_H
|
||||
|
||||
@@ -512,7 +512,7 @@ inline const char *CSaveRestoreSegment::StringFromSymbol( int token )
|
||||
/// compilers. Either way, there's no portable intrinsic.
|
||||
|
||||
// Newer GCC versions provide this in this header, older did by default.
|
||||
#if !defined( _rotr ) && defined( COMPILER_GCC ) && !defined( __arm__ )
|
||||
#if !defined( _rotr ) && defined( COMPILER_GCC ) && !defined( __arm__ ) && !defined( __aarch64__ )
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
|
||||
+4
-1
@@ -345,7 +345,9 @@ unsigned int CPhonemeTag::ComputeDataCheckSum()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simple language to string and string to language lookup dictionary
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
struct CCLanguage
|
||||
{
|
||||
@@ -369,8 +371,9 @@ static CCLanguage g_CCLanguageLookup[] =
|
||||
{ CC_THAI, "thai", 0 , 150, 250 },
|
||||
{ CC_PORTUGUESE,"portuguese", 0 , 0, 150 },
|
||||
};
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
void CSentence::ColorForLanguage( int language, unsigned char& r, unsigned char& g, unsigned char& b )
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ enum ShaderRenderTarget_t
|
||||
//-----------------------------------------------------------------------------
|
||||
// This must match the definition in playback.cpp!
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef int ShaderAPITextureHandle_t;
|
||||
typedef intp ShaderAPITextureHandle_t;
|
||||
#define INVALID_SHADERAPI_TEXTURE_HANDLE 0
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "tier0/basetypes.h"
|
||||
|
||||
|
||||
typedef int ShaderAPITextureHandle_t;
|
||||
typedef intp ShaderAPITextureHandle_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// forward declarations
|
||||
@@ -36,8 +36,8 @@ struct LightState_t
|
||||
{
|
||||
int m_nNumLights;
|
||||
bool m_bAmbientLight;
|
||||
bool m_bStaticLightVertex;
|
||||
bool m_bStaticLightTexel;
|
||||
bool m_bStaticLightVertex;
|
||||
inline int HasDynamicLight() { return (m_bAmbientLight || (m_nNumLights > 0)) ? 1 : 0; }
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -24,7 +24,7 @@ typedef unsigned char uint8;
|
||||
#define POSIX 1
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__) || defined(_WIN64)
|
||||
#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
|
||||
#define X64BITS
|
||||
#endif
|
||||
|
||||
|
||||
+129
-35
@@ -83,7 +83,7 @@ Studio models are position independent, so the cache manager can move them.
|
||||
#define MAXSTUDIOFLEXDESC 1024 // maximum number of low level flexes (actual morph targets)
|
||||
#define MAXSTUDIOFLEXCTRL 96 // maximum number of flexcontrollers (input sliders)
|
||||
#define MAXSTUDIOPOSEPARAM 24
|
||||
#define MAXSTUDIOBONECTRLS 4
|
||||
#define MAXSTUDIOBONECTRLS 5
|
||||
#define MAXSTUDIOANIMBLOCKS 256
|
||||
|
||||
#define MAXSTUDIOBONEBITS 7 // NOTE: MUST MATCH MAXSTUDIOBONES
|
||||
@@ -106,6 +106,39 @@ struct mstudiodata_t
|
||||
#define STUDIO_PROC_AIMATATTACH 4
|
||||
#define STUDIO_PROC_JIGGLE 5
|
||||
|
||||
// If you want to embed a pointer into one of the structures that is serialized, use this class! It will ensure that the pointers consume the
|
||||
// right amount of space and work correctly across 32 and 64 bit. It also makes sure that there is no surprise about how large the structure
|
||||
// is when placed in the middle of another structure, and supports Intel's desired behavior on 64-bit that pointers are always 8-byte aligned.
|
||||
#pragma pack( push, 4 )
|
||||
template < class T >
|
||||
struct ALIGN4 serializedstudioptr_t
|
||||
{
|
||||
T* m_pData;
|
||||
#ifndef PLATFORM_64BITS
|
||||
int32 padding;
|
||||
#endif
|
||||
|
||||
serializedstudioptr_t()
|
||||
{
|
||||
m_pData = nullptr;
|
||||
#if _DEBUG && !defined( PLATFORM_64BITS )
|
||||
padding = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline operator T*() { return m_pData; }
|
||||
inline operator const T*() const { return m_pData; }
|
||||
|
||||
inline T* operator->( ) { return m_pData; }
|
||||
inline const T* operator->( ) const { return m_pData; }
|
||||
|
||||
inline T* operator=( T* ptr ) { return m_pData = ptr; }
|
||||
|
||||
} ALIGN4_POST;
|
||||
|
||||
#pragma pack( pop )
|
||||
|
||||
|
||||
struct mstudioaxisinterpbone_t
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
@@ -639,6 +672,7 @@ struct mstudioanim_t
|
||||
byte bone;
|
||||
byte flags; // weighing options
|
||||
|
||||
|
||||
// valid for animating data only
|
||||
inline byte *pData( void ) const { return (((byte *)this) + sizeof( struct mstudioanim_t )); };
|
||||
inline mstudioanim_valueptr_t *pRotV( void ) const { return (mstudioanim_valueptr_t *)(pData()); };
|
||||
@@ -650,8 +684,9 @@ struct mstudioanim_t
|
||||
inline Vector48 *pPos( void ) const { return (Vector48 *)(pData() + ((flags & STUDIO_ANIM_RAWROT) != 0) * sizeof( *pQuat48() ) + ((flags & STUDIO_ANIM_RAWROT2) != 0) * sizeof( *pQuat64() ) ); };
|
||||
|
||||
short nextoffset;
|
||||
|
||||
inline mstudioanim_t *pNext( void ) const { if (nextoffset != 0) return (mstudioanim_t *)(((byte *)this) + nextoffset); else return NULL; };
|
||||
};
|
||||
} ALIGN16;
|
||||
|
||||
struct mstudiomovement_t
|
||||
{
|
||||
@@ -1192,10 +1227,16 @@ struct mstudiotexture_t
|
||||
int flags;
|
||||
int used;
|
||||
int unused1;
|
||||
#if PLATFORM_64BITS
|
||||
mutable IMaterial *material;
|
||||
mutable void *clientmaterial;
|
||||
int unused[8];
|
||||
#else
|
||||
mutable IMaterial *material; // fixme: this needs to go away . .isn't used by the engine, but is used by studiomdl
|
||||
mutable void *clientmaterial; // gary, replace with client material pointer if used
|
||||
|
||||
int unused[10];
|
||||
#endif
|
||||
};
|
||||
|
||||
// eyeball
|
||||
@@ -1284,10 +1325,22 @@ struct mstudio_modelvertexdata_t
|
||||
int GetGlobalTangentIndex( int i ) const;
|
||||
|
||||
// base of external vertex data stores
|
||||
const void *pVertexData;
|
||||
const void *pTangentData;
|
||||
serializedstudioptr_t<const void> pVertexData;
|
||||
serializedstudioptr_t<const void> pTangentData;
|
||||
|
||||
const void *GetVertexData() const {
|
||||
return pVertexData;
|
||||
}
|
||||
const void *GetTangentData() const {
|
||||
return pTangentData;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
// 64b - match 32-bit packing
|
||||
#pragma pack( push, 4 )
|
||||
#endif
|
||||
|
||||
struct mstudio_meshvertexdata_t
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
@@ -1301,12 +1354,24 @@ struct mstudio_meshvertexdata_t
|
||||
int GetModelVertexIndex( int i ) const;
|
||||
int GetGlobalVertexIndex( int i ) const;
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
// MoeMod : fix 64bit ptr size
|
||||
int index_ptr_modelvertexdata;
|
||||
#else
|
||||
// indirection to this mesh's model's vertex data
|
||||
const mstudio_modelvertexdata_t *modelvertexdata;
|
||||
|
||||
#endif
|
||||
// used for fixup calcs when culling top level lods
|
||||
// expected number of mesh verts at desired lod
|
||||
int numLODVertexes[MAX_NUM_LODS];
|
||||
|
||||
const mstudio_modelvertexdata_t *pModelVertexData() const {
|
||||
#ifdef PLATFORM_64BITS
|
||||
return *(const mstudio_modelvertexdata_t **)((byte *)this + index_ptr_modelvertexdata);
|
||||
#else
|
||||
return modelvertexdata;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct mstudiomesh_t
|
||||
@@ -1337,9 +1402,14 @@ struct mstudiomesh_t
|
||||
|
||||
Vector center;
|
||||
|
||||
mstudio_meshvertexdata_t vertexdata;
|
||||
mstudio_meshvertexdata_t vertexdata;
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
int unused[6]; // remove as appropriate
|
||||
const mstudio_modelvertexdata_t *real_modelvertexdata;
|
||||
#else
|
||||
int unused[8]; // remove as appropriate
|
||||
#endif
|
||||
|
||||
mstudiomesh_t(){}
|
||||
private:
|
||||
@@ -1381,19 +1451,24 @@ struct mstudiomodel_t
|
||||
int eyeballindex;
|
||||
inline mstudioeyeball_t *pEyeball( int i ) { return (mstudioeyeball_t *)(((byte *)this) + eyeballindex) + i; };
|
||||
|
||||
mstudio_modelvertexdata_t vertexdata;
|
||||
mstudio_modelvertexdata_t vertexdata; // sizeof(mstudio_modelvertexdata_t) == 16
|
||||
|
||||
int unused[8]; // remove as appropriate
|
||||
int unused[6]; // remove as appropriate
|
||||
};
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
#pragma pack( pop )
|
||||
#endif
|
||||
|
||||
inline bool mstudio_modelvertexdata_t::HasTangentData( void ) const
|
||||
{
|
||||
return (pTangentData != NULL);
|
||||
return (GetTangentData() != NULL);
|
||||
}
|
||||
|
||||
inline int mstudio_modelvertexdata_t::GetGlobalVertexIndex( int i ) const
|
||||
{
|
||||
mstudiomodel_t *modelptr = (mstudiomodel_t *)((byte *)this - offsetof(mstudiomodel_t, vertexdata));
|
||||
Assert(&modelptr->vertexdata == this);
|
||||
Assert( ( modelptr->vertexindex % sizeof( mstudiovertex_t ) ) == 0 );
|
||||
return ( i + ( modelptr->vertexindex / sizeof( mstudiovertex_t ) ) );
|
||||
}
|
||||
@@ -1401,13 +1476,14 @@ inline int mstudio_modelvertexdata_t::GetGlobalVertexIndex( int i ) const
|
||||
inline int mstudio_modelvertexdata_t::GetGlobalTangentIndex( int i ) const
|
||||
{
|
||||
mstudiomodel_t *modelptr = (mstudiomodel_t *)((byte *)this - offsetof(mstudiomodel_t, vertexdata));
|
||||
Assert(&modelptr->vertexdata == this);
|
||||
Assert( ( modelptr->tangentsindex % sizeof( Vector4D ) ) == 0 );
|
||||
return ( i + ( modelptr->tangentsindex / sizeof( Vector4D ) ) );
|
||||
}
|
||||
|
||||
inline mstudiovertex_t *mstudio_modelvertexdata_t::Vertex( int i ) const
|
||||
{
|
||||
return (mstudiovertex_t *)pVertexData + GetGlobalVertexIndex( i );
|
||||
return (mstudiovertex_t *)GetVertexData() + GetGlobalVertexIndex( i );
|
||||
}
|
||||
|
||||
inline Vector *mstudio_modelvertexdata_t::Position( int i ) const
|
||||
@@ -1425,7 +1501,7 @@ inline Vector4D *mstudio_modelvertexdata_t::TangentS( int i ) const
|
||||
// NOTE: The tangents vector is 16-bytes in a separate array
|
||||
// because it only exists on the high end, and if I leave it out
|
||||
// of the mstudiovertex_t, the vertex is 64-bytes (good for low end)
|
||||
return (Vector4D *)pTangentData + GetGlobalTangentIndex( i );
|
||||
return (Vector4D *)GetTangentData() + GetGlobalTangentIndex( i );
|
||||
}
|
||||
|
||||
inline Vector2D *mstudio_modelvertexdata_t::Texcoord( int i ) const
|
||||
@@ -1445,7 +1521,7 @@ inline mstudiomodel_t *mstudiomesh_t::pModel() const
|
||||
|
||||
inline bool mstudio_meshvertexdata_t::HasTangentData( void ) const
|
||||
{
|
||||
return modelvertexdata->HasTangentData();
|
||||
return pModelVertexData()->HasTangentData();
|
||||
}
|
||||
|
||||
inline const mstudio_meshvertexdata_t *mstudiomesh_t::GetVertexData( void *pModelData )
|
||||
@@ -1453,9 +1529,14 @@ inline const mstudio_meshvertexdata_t *mstudiomesh_t::GetVertexData( void *pMode
|
||||
// get this mesh's model's vertex data (allow for mstudiomodel_t::GetVertexData
|
||||
// returning NULL if the data has been converted to 'thin' vertices)
|
||||
this->pModel()->GetVertexData( pModelData );
|
||||
#ifdef PLATFORM_64BITS
|
||||
real_modelvertexdata = &( this->pModel()->vertexdata );
|
||||
vertexdata.index_ptr_modelvertexdata = (byte *)&real_modelvertexdata - (byte *)&vertexdata;
|
||||
#else
|
||||
vertexdata.modelvertexdata = &( this->pModel()->vertexdata );
|
||||
#endif
|
||||
|
||||
if ( !vertexdata.modelvertexdata->pVertexData )
|
||||
if ( !vertexdata.pModelVertexData()->GetVertexData() )
|
||||
return NULL;
|
||||
|
||||
return &vertexdata;
|
||||
@@ -1469,43 +1550,44 @@ inline const thinModelVertices_t * mstudiomesh_t::GetThinVertexData( void *pMode
|
||||
|
||||
inline int mstudio_meshvertexdata_t::GetModelVertexIndex( int i ) const
|
||||
{
|
||||
mstudiomesh_t *meshptr = (mstudiomesh_t *)((byte *)this - offsetof(mstudiomesh_t,vertexdata));
|
||||
mstudiomesh_t *meshptr = (mstudiomesh_t *)((byte *)this - offsetof(mstudiomesh_t,vertexdata));
|
||||
Assert(&meshptr->vertexdata == this);
|
||||
return meshptr->vertexoffset + i;
|
||||
}
|
||||
|
||||
inline int mstudio_meshvertexdata_t::GetGlobalVertexIndex( int i ) const
|
||||
{
|
||||
return modelvertexdata->GetGlobalVertexIndex( GetModelVertexIndex( i ) );
|
||||
return pModelVertexData()->GetGlobalVertexIndex( GetModelVertexIndex( i ) );
|
||||
}
|
||||
|
||||
inline Vector *mstudio_meshvertexdata_t::Position( int i ) const
|
||||
{
|
||||
return modelvertexdata->Position( GetModelVertexIndex( i ) );
|
||||
return pModelVertexData()->Position( GetModelVertexIndex( i ) );
|
||||
};
|
||||
|
||||
inline Vector *mstudio_meshvertexdata_t::Normal( int i ) const
|
||||
{
|
||||
return modelvertexdata->Normal( GetModelVertexIndex( i ) );
|
||||
return pModelVertexData()->Normal( GetModelVertexIndex( i ) );
|
||||
};
|
||||
|
||||
inline Vector4D *mstudio_meshvertexdata_t::TangentS( int i ) const
|
||||
{
|
||||
return modelvertexdata->TangentS( GetModelVertexIndex( i ) );
|
||||
return pModelVertexData()->TangentS( GetModelVertexIndex( i ) );
|
||||
}
|
||||
|
||||
inline Vector2D *mstudio_meshvertexdata_t::Texcoord( int i ) const
|
||||
{
|
||||
return modelvertexdata->Texcoord( GetModelVertexIndex( i ) );
|
||||
return pModelVertexData()->Texcoord( GetModelVertexIndex( i ) );
|
||||
};
|
||||
|
||||
inline mstudioboneweight_t *mstudio_meshvertexdata_t::BoneWeights( int i ) const
|
||||
{
|
||||
return modelvertexdata->BoneWeights( GetModelVertexIndex( i ) );
|
||||
return pModelVertexData()->BoneWeights( GetModelVertexIndex( i ) );
|
||||
};
|
||||
|
||||
inline mstudiovertex_t *mstudio_meshvertexdata_t::Vertex( int i ) const
|
||||
{
|
||||
return modelvertexdata->Vertex( GetModelVertexIndex( i ) );
|
||||
return pModelVertexData()->Vertex( GetModelVertexIndex( i ) );
|
||||
}
|
||||
|
||||
// a group of studio model data
|
||||
@@ -1933,7 +2015,7 @@ inline const mstudio_modelvertexdata_t * mstudiomodel_t::GetVertexData( void *pM
|
||||
vertexdata.pVertexData = pVertexHdr->GetVertexData();
|
||||
vertexdata.pTangentData = pVertexHdr->GetTangentData();
|
||||
|
||||
if ( !vertexdata.pVertexData )
|
||||
if ( !vertexdata.GetVertexData() )
|
||||
return NULL;
|
||||
|
||||
return &vertexdata;
|
||||
@@ -2056,12 +2138,20 @@ struct studiohdr2_t
|
||||
int m_nBoneFlexDriverIndex;
|
||||
inline mstudioboneflexdriver_t *pBoneFlexDriver( int i ) const { Assert( i >= 0 && i < m_nBoneFlexDriverCount ); return (mstudioboneflexdriver_t *)(((byte *)this) + m_nBoneFlexDriverIndex) + i; }
|
||||
|
||||
int reserved[56];
|
||||
mutable serializedstudioptr_t< void > virtualModel;
|
||||
mutable serializedstudioptr_t< void > animblockModel;
|
||||
|
||||
serializedstudioptr_t< void> pVertexBase;
|
||||
serializedstudioptr_t< void> pIndexBase;
|
||||
|
||||
int reserved[48];
|
||||
};
|
||||
|
||||
struct studiohdr_t
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
studiohdr_t() = default;
|
||||
|
||||
int id;
|
||||
int version;
|
||||
|
||||
@@ -2077,10 +2167,10 @@ struct studiohdr_t
|
||||
Vector illumposition; // illumination center
|
||||
|
||||
Vector hull_min; // ideal movement hull size
|
||||
Vector hull_max;
|
||||
Vector hull_max;
|
||||
|
||||
Vector view_bbmin; // clipping bounding box
|
||||
Vector view_bbmax;
|
||||
Vector view_bbmax;
|
||||
|
||||
int flags;
|
||||
|
||||
@@ -2259,7 +2349,7 @@ struct studiohdr_t
|
||||
const studiohdr_t *FindModel( void **cache, char const *modelname ) const;
|
||||
|
||||
// implementation specific back pointer to virtual data
|
||||
mutable void *virtualModel;
|
||||
int unused_virtualModel;
|
||||
virtualmodel_t *GetVirtualModel( void ) const;
|
||||
|
||||
// for demand loaded animation blocks
|
||||
@@ -2268,7 +2358,8 @@ struct studiohdr_t
|
||||
int numanimblocks;
|
||||
int animblockindex;
|
||||
inline mstudioanimblock_t *pAnimBlock( int i ) const { Assert( i > 0 && i < numanimblocks); return (mstudioanimblock_t *)(((byte *)this) + animblockindex) + i; };
|
||||
mutable void *animblockModel;
|
||||
|
||||
int unused_animblockModel;
|
||||
byte * GetAnimBlock( int i ) const;
|
||||
|
||||
int bonetablebynameindex;
|
||||
@@ -2276,8 +2367,8 @@ struct studiohdr_t
|
||||
|
||||
// used by tools only that don't cache, but persist mdl's peer data
|
||||
// engine uses virtualModel to back link to cache pointers
|
||||
void *pVertexBase;
|
||||
void *pIndexBase;
|
||||
int unused_pVertexBase;
|
||||
int unused_pIndexBase;
|
||||
|
||||
// if STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT is set,
|
||||
// this value is used to calculate directional components of lighting
|
||||
@@ -2323,15 +2414,19 @@ struct studiohdr_t
|
||||
inline mstudiolinearbone_t *pLinearBones() const { return studiohdr2index ? pStudioHdr2()->pLinearBones() : NULL; }
|
||||
|
||||
inline int BoneFlexDriverCount() const { return studiohdr2index ? pStudioHdr2()->m_nBoneFlexDriverCount : 0; }
|
||||
inline const mstudioboneflexdriver_t* BoneFlexDriver( int i ) const { Assert( i >= 0 && i < BoneFlexDriverCount() ); return studiohdr2index ? pStudioHdr2()->pBoneFlexDriver( i ) : NULL; }
|
||||
inline const mstudioboneflexdriver_t* BoneFlexDriver( int i ) const { Assert( i >= 0 && i < BoneFlexDriverCount() ); return studiohdr2index > 0 ? pStudioHdr2()->pBoneFlexDriver( i ) : NULL; }
|
||||
|
||||
void* VirtualModel() const { return studiohdr2index ? (void *)( pStudioHdr2()->virtualModel ) : nullptr; }
|
||||
void SetVirtualModel( void* ptr ) { Assert( studiohdr2index ); if ( studiohdr2index ) { pStudioHdr2()->virtualModel = ptr; } else { Msg("go fuck urself!\n"); } }
|
||||
void* VertexBase() const { return studiohdr2index ? (void *)( pStudioHdr2()->pVertexBase ) : nullptr; }
|
||||
void SetVertexBase( void* pVertexBase ) const { Assert( studiohdr2index ); if ( studiohdr2index ) { pStudioHdr2()->pVertexBase = pVertexBase; } }
|
||||
void* IndexBase() const { return studiohdr2index ? ( void * ) ( pStudioHdr2()->pIndexBase ) : nullptr; }
|
||||
void SetIndexBase( void* pIndexBase ) const { Assert( studiohdr2index ); if ( studiohdr2index ) { pStudioHdr2()->pIndexBase = pIndexBase; } }
|
||||
|
||||
// NOTE: No room to add stuff? Up the .mdl file format version
|
||||
// [and move all fields in studiohdr2_t into studiohdr_t and kill studiohdr2_t],
|
||||
// or add your stuff to studiohdr2_t. See NumSrcBoneTransforms/SrcBoneTransform for the pattern to use.
|
||||
int unused2[1];
|
||||
|
||||
studiohdr_t() {}
|
||||
|
||||
private:
|
||||
// No copy constructors allowed
|
||||
studiohdr_t(const studiohdr_t& vOther);
|
||||
@@ -2339,8 +2434,6 @@ private:
|
||||
friend struct virtualmodel_t;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3014,6 +3107,7 @@ inline bool Studio_ConvertStudioHdrToNewVersion( studiohdr_t *pStudioHdr )
|
||||
return true;
|
||||
|
||||
bool bResult = true;
|
||||
|
||||
if (version < 46)
|
||||
{
|
||||
// some of the anim index data is incompatible
|
||||
|
||||
@@ -171,17 +171,24 @@ typedef float vec_t;
|
||||
// This assumes the ANSI/IEEE 754-1985 standard
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline unsigned long& FloatBits( vec_t& f )
|
||||
// MoeMod : fix reinterpret_cast UB - Maybe fail with strict alias
|
||||
union FloatCast_u
|
||||
{
|
||||
return *reinterpret_cast<unsigned long*>(&f);
|
||||
vec_t f;
|
||||
unsigned int i;
|
||||
};
|
||||
|
||||
inline unsigned int& FloatBits( vec_t& f )
|
||||
{
|
||||
return reinterpret_cast<FloatCast_u *>(&f)->i;
|
||||
}
|
||||
|
||||
inline unsigned long const& FloatBits( vec_t const& f )
|
||||
inline unsigned int const& FloatBits( vec_t const& f )
|
||||
{
|
||||
return *reinterpret_cast<unsigned long const*>(&f);
|
||||
return reinterpret_cast<FloatCast_u const*>(&f)->i;
|
||||
}
|
||||
|
||||
inline vec_t BitsToFloat( unsigned long i )
|
||||
inline vec_t BitsToFloat( unsigned int i )
|
||||
{
|
||||
vec_t f;
|
||||
memcpy( &f, &i, sizeof(f));
|
||||
@@ -193,7 +200,7 @@ inline bool IsFinite( vec_t f )
|
||||
return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
|
||||
}
|
||||
|
||||
inline unsigned long FloatAbsBits( vec_t f )
|
||||
inline unsigned int FloatAbsBits( vec_t f )
|
||||
{
|
||||
return FloatBits(f) & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,14 @@
|
||||
|
||||
class Color;
|
||||
|
||||
class IDbgLogger
|
||||
{
|
||||
public:
|
||||
virtual void Init(const char *logfile) = 0;
|
||||
virtual void Write(const char *data) = 0;
|
||||
};
|
||||
|
||||
PLATFORM_INTERFACE IDbgLogger *DebugLogger();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Usage model for the Dbg library
|
||||
|
||||
+10
-5
@@ -96,8 +96,8 @@ public:
|
||||
virtual bool IsDebugHeap() = 0;
|
||||
|
||||
virtual void GetActualDbgInfo( const char *&pFileName, int &nLine ) = 0;
|
||||
virtual void RegisterAllocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0;
|
||||
virtual void RegisterDeallocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0;
|
||||
virtual void RegisterAllocation( const char *pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime ) = 0;
|
||||
virtual void RegisterDeallocation( const char *pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime ) = 0;
|
||||
|
||||
virtual int GetVersion() = 0;
|
||||
|
||||
@@ -473,9 +473,14 @@ inline void MemAlloc_CheckAlloc( void *ptr, size_t nSize )
|
||||
}
|
||||
|
||||
#if defined( OSX )
|
||||
// Mac always aligns allocs, don't need to call posix_memalign which doesn't exist in 10.5.8 which TF2 still needs to run on
|
||||
//inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; posix_memalign(&pTmp, alignment, size); return pTmp;}
|
||||
inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; pTmp = malloc(size); MemAlloc_CheckAlloc( pTmp, size ); return pTmp;}
|
||||
inline void *memalign(size_t alignment, size_t size) {
|
||||
// MoeMod : 64bit fix
|
||||
if(alignment < sizeof(void *))
|
||||
alignment = sizeof(void *);
|
||||
void *pTmp = nullptr;
|
||||
posix_memalign(&pTmp, alignment, size);
|
||||
return pTmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void *_aligned_malloc( size_t nSize, size_t align ) { void *ptr = memalign( align, nSize ); MemAlloc_CheckAlloc( ptr, nSize ); return ptr; }
|
||||
|
||||
@@ -29,7 +29,11 @@
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#ifdef OSX
|
||||
#include <malloc/malloc.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "commonmacros.h"
|
||||
#include "memalloc.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//========== Copyright (C) Valve Corporation, All rights reserved. ==========//
|
||||
//
|
||||
// Purpose: CVirtualMemoryManager interface
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef MEM_VIRT_H
|
||||
#define MEM_VIRT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#define VMM_KB ( 1024 )
|
||||
#define VMM_MB ( 1024 * VMM_KB )
|
||||
|
||||
#ifdef _PS3
|
||||
// Total virtual address space reserved by CVirtualMemoryManager on startup:
|
||||
#define VMM_VIRTUAL_SIZE ( 512 * VMM_MB )
|
||||
#define VMM_PAGE_SIZE ( 64 * VMM_KB )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Allocate virtual sections via IMemAlloc::AllocateVirtualMemorySection
|
||||
abstract_class IVirtualMemorySection
|
||||
{
|
||||
public:
|
||||
// Information about memory section
|
||||
virtual void * GetBaseAddress() = 0;
|
||||
virtual size_t GetPageSize() = 0;
|
||||
virtual size_t GetTotalSize() = 0;
|
||||
|
||||
// Functions to manage physical memory mapped to virtual memory
|
||||
virtual bool CommitPages( void *pvBase, size_t numBytes ) = 0;
|
||||
virtual void DecommitPages( void *pvBase, size_t numBytes ) = 0;
|
||||
|
||||
// Release the physical memory and associated virtual address space
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
// Get the IVirtualMemorySection associated with a given memory address (if any):
|
||||
extern IVirtualMemorySection *GetMemorySectionForAddress( void *pAddress );
|
||||
|
||||
|
||||
#endif // MEM_VIRT_H
|
||||
+46
-9
@@ -9,7 +9,7 @@
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
#if defined(__x86_64__) || defined(_WIN64)
|
||||
#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
|
||||
#define PLATFORM_64BITS 1
|
||||
#endif
|
||||
|
||||
@@ -70,7 +70,11 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifdef OSX
|
||||
#include <malloc/malloc.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <new>
|
||||
|
||||
// need this for memset
|
||||
@@ -171,6 +175,9 @@ typedef signed char int8;
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
|
||||
typedef int64 lint64;
|
||||
typedef uint64 ulint64;
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
typedef __int64 intp; // intp is an integer that can accomodate a pointer
|
||||
typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *)
|
||||
@@ -201,13 +208,17 @@ typedef signed char int8;
|
||||
typedef unsigned int uint32;
|
||||
typedef long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
typedef long int lint64;
|
||||
typedef unsigned long int ulint64;
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
typedef long long intp;
|
||||
typedef unsigned long long uintp;
|
||||
#else
|
||||
typedef int intp;
|
||||
typedef unsigned int uintp;
|
||||
#endif
|
||||
#endif
|
||||
typedef void *HWND;
|
||||
|
||||
// Avoid redefinition warnings if a previous header defines this.
|
||||
@@ -429,7 +440,17 @@ typedef void * HINSTANCE;
|
||||
// On OSX, SIGTRAP doesn't really stop the thread cold when debugging.
|
||||
// So if being debugged, use INT3 which is precise.
|
||||
#ifdef OSX
|
||||
#define DebuggerBreak() if ( Plat_IsInDebugSession() ) { __asm ( "int $3" ); } else { raise(SIGTRAP); }
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
#ifdef __clang__
|
||||
#define DebuggerBreak() do { if ( Plat_IsInDebugSession() ) { __builtin_debugtrap(); } else { raise(SIGTRAP); } } while(0)
|
||||
#elif defined __GNUC__
|
||||
#define DebuggerBreak() do { if ( Plat_IsInDebugSession() ) { __builtin_trap(); } else { raise(SIGTRAP); } } while(0)
|
||||
#else
|
||||
#define DebuggerBreak() raise(SIGTRAP)
|
||||
#endif
|
||||
#else
|
||||
#define DebuggerBreak() do { if ( Plat_IsInDebugSession() ) { __asm ( "int $3" ); } else { raise(SIGTRAP); } } while(0)
|
||||
#endif
|
||||
#else
|
||||
#define DebuggerBreak() raise(SIGTRAP)
|
||||
#endif
|
||||
@@ -504,6 +525,16 @@ typedef void * HINSTANCE;
|
||||
#error
|
||||
#endif
|
||||
|
||||
// !!! NOTE: if you get a compile error here, you are using VALIGNOF on an abstract type :NOTE !!!
|
||||
#define VALIGNOF_PORTABLE( type ) ( sizeof( AlignOf_t<type> ) - sizeof( type ) )
|
||||
|
||||
#if defined( COMPILER_GCC ) || defined( COMPILER_MSVC )
|
||||
#define VALIGNOF( type ) __alignof( type )
|
||||
#define VALIGNOF_TEMPLATE_SAFE( type ) VALIGNOF_PORTABLE( type )
|
||||
#else
|
||||
#error "PORT: Code only tested with MSVC! Must validate with new compiler, and use built-in keyword if available."
|
||||
#endif
|
||||
|
||||
// Pull in the /analyze code annotations.
|
||||
#include "annotations.h"
|
||||
|
||||
@@ -600,6 +631,7 @@ typedef void * HINSTANCE;
|
||||
#endif
|
||||
|
||||
// Used for standard calling conventions
|
||||
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#define STDCALL __stdcall
|
||||
#define FASTCALL __fastcall
|
||||
@@ -656,6 +688,11 @@ typedef void * HINSTANCE;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#undef FORCEINLINE
|
||||
#define FORCEINLINE static
|
||||
#endif
|
||||
|
||||
// Remove warnings from warning level 4.
|
||||
#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed
|
||||
#pragma warning(disable : 4100) // warning C4100: 'hwnd' : unreferenced formal parameter
|
||||
@@ -752,7 +789,7 @@ typedef void * HINSTANCE;
|
||||
#define _wtoi(arg) wcstol(arg, NULL, 10)
|
||||
#define _wtoi64(arg) wcstoll(arg, NULL, 10)
|
||||
|
||||
typedef uint32 HMODULE;
|
||||
typedef uintp HMODULE;
|
||||
typedef void *HANDLE;
|
||||
#endif
|
||||
|
||||
@@ -830,7 +867,7 @@ static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#elif defined (__arm__)
|
||||
#elif defined (__arm__) || defined (__aarch64__)
|
||||
inline void SetupFPUControlWord() {}
|
||||
#else
|
||||
inline void SetupFPUControlWord()
|
||||
@@ -1094,12 +1131,12 @@ FORCEINLINE void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex,
|
||||
__storewordbytereverse( dword, dwordIndex<<2, base );
|
||||
}
|
||||
#else
|
||||
FORCEINLINE unsigned long LoadLittleDWord( const unsigned long *base, unsigned int dwordIndex )
|
||||
FORCEINLINE uint32 LoadLittleDWord( const uint32 *base, unsigned int dwordIndex )
|
||||
{
|
||||
return LittleDWord( base[dwordIndex] );
|
||||
}
|
||||
|
||||
FORCEINLINE void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex, unsigned long dword )
|
||||
FORCEINLINE void StoreLittleDWord( uint32 *base, unsigned int dwordIndex, uint32 dword )
|
||||
{
|
||||
base[dwordIndex] = LittleDWord(dword);
|
||||
}
|
||||
@@ -1167,7 +1204,7 @@ PLATFORM_INTERFACE struct tm * Plat_localtime( const time_t *timep, struct tm *
|
||||
|
||||
inline uint64 Plat_Rdtsc()
|
||||
{
|
||||
#if defined( __arm__ ) && defined (POSIX)
|
||||
#if (defined( __arm__ ) || defined( __aarch64__ )) && defined (POSIX)
|
||||
struct timespec t;
|
||||
clock_gettime( CLOCK_REALTIME, &t);
|
||||
return t.tv_sec * 1000000000ULL + t.tv_nsec;
|
||||
@@ -1479,7 +1516,7 @@ inline void ConstructThreeArg( T* pMemory, P1 const& arg1, P2 const& arg2, P3 co
|
||||
template <class T>
|
||||
inline T* CopyConstruct( T* pMemory, T const& src )
|
||||
{
|
||||
return reinterpret_cast<T*>(::new( pMemory ) T(src));
|
||||
return ::new( pMemory ) T(src);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -144,14 +144,15 @@
|
||||
#define timeGetTime timeGetTime__USE_VCR_MODE
|
||||
#if defined( clock )
|
||||
#undef clock
|
||||
#endif
|
||||
#define time time__USE_VCR_MODE
|
||||
#endif
|
||||
// MoeMod : breaks system header
|
||||
//#define time time__USE_VCR_MODE
|
||||
|
||||
|
||||
#if defined( recvfrom )
|
||||
#undef recvfrom
|
||||
#endif
|
||||
#define recvfrom recvfrom__USE_VCR_MODE
|
||||
//#if defined( recvfrom )
|
||||
// #undef recvfrom
|
||||
//#endif
|
||||
//#define recvfrom recvfrom__USE_VCR_MODE
|
||||
|
||||
|
||||
#if defined( GetCursorPos )
|
||||
|
||||
+1201
-396
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,653 @@
|
||||
#ifndef THREADTOOLS_INL
|
||||
#define THREADTOOLS_INL
|
||||
|
||||
// This file is included in threadtools.h for PS3 and threadtools.cpp for all other platforms
|
||||
//
|
||||
// Do not #include other files here
|
||||
|
||||
#ifndef _PS3
|
||||
// this is defined in the .cpp for the PS3 to avoid introducing a dependency for files including the header
|
||||
CTHREADLOCALPTR(CThread) g_pCurThread;
|
||||
|
||||
#define INLINE_ON_PS3
|
||||
#else
|
||||
// Inlining these functions on PS3 (which are called across PRX boundaries) saves us over 1ms per frame
|
||||
#define INLINE_ON_PS3 inline
|
||||
#endif
|
||||
|
||||
INLINE_ON_PS3 CThread::CThread() :
|
||||
#ifdef _WIN32
|
||||
m_hThread( NULL ),
|
||||
m_threadId( 0 ),
|
||||
#elif defined( _PS3 ) || defined(_POSIX)
|
||||
m_threadId( 0 ),
|
||||
m_threadZombieId( 0 ) ,
|
||||
#endif
|
||||
m_result( 0 ),
|
||||
m_flags( 0 )
|
||||
{
|
||||
m_szName[0] = 0;
|
||||
m_NotSuspendedEvent.Set();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
INLINE_ON_PS3 CThread::~CThread()
|
||||
{
|
||||
#ifdef MSVC
|
||||
if (m_hThread)
|
||||
#elif defined(POSIX) && !defined( _PS3 )
|
||||
if ( m_threadId )
|
||||
#endif
|
||||
{
|
||||
if ( IsAlive() )
|
||||
{
|
||||
Msg( "Illegal termination of worker thread! Threads must negotiate an end to the thread before the CThread object is destroyed.\n" );
|
||||
#ifdef _WIN32
|
||||
|
||||
DoNewAssertDialog( __FILE__, __LINE__, "Illegal termination of worker thread! Threads must negotiate an end to the thread before the CThread object is destroyed.\n" );
|
||||
#endif
|
||||
if ( GetCurrentCThread() == this )
|
||||
{
|
||||
Stop(); // BUGBUG: Alfred - this doesn't make sense, this destructor fires from the hosting thread not the thread itself!!
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(POSIX) || defined( _PS3 )
|
||||
if ( m_threadZombieId )
|
||||
{
|
||||
// just clean up zombie threads immediately (the destructor is fired from the hosting thread)
|
||||
Join();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
INLINE_ON_PS3 const char *CThread::GetName()
|
||||
{
|
||||
AUTO_LOCK( m_Lock );
|
||||
if ( !m_szName[0] )
|
||||
{
|
||||
#if defined( _WIN32 )
|
||||
_snprintf( m_szName, sizeof(m_szName) - 1, "Thread(%p/%p)", this, m_hThread );
|
||||
#elif defined( _PS3 )
|
||||
snprintf( m_szName, sizeof(m_szName) - 1, "Thread(%p)", this );
|
||||
#elif defined( POSIX )
|
||||
_snprintf( m_szName, sizeof(m_szName) - 1, "Thread(%p/0x%p)", this, (void*)m_threadId );
|
||||
#endif
|
||||
m_szName[sizeof(m_szName) - 1] = 0;
|
||||
}
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
INLINE_ON_PS3 void CThread::SetName(const char *pszName)
|
||||
{
|
||||
AUTO_LOCK( m_Lock );
|
||||
strncpy( m_szName, pszName, sizeof(m_szName) - 1 );
|
||||
m_szName[sizeof(m_szName) - 1] = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Functions for the other threads
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Start thread running - error if already running
|
||||
INLINE_ON_PS3 bool CThread::Start( unsigned nBytesStack, ThreadPriorityEnum_t nPriority )
|
||||
{
|
||||
AUTO_LOCK( m_Lock );
|
||||
|
||||
if ( IsAlive() )
|
||||
{
|
||||
AssertMsg( 0, "Tried to create a thread that has already been created!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bInitSuccess = false;
|
||||
CThreadEvent createComplete;
|
||||
ThreadInit_t init = { this, &createComplete, &bInitSuccess };
|
||||
|
||||
#if defined( THREAD_PARENT_STACK_TRACE_ENABLED )
|
||||
{
|
||||
int iValidEntries = GetCallStack_Fast( init.ParentStackTrace, ARRAYSIZE( init.ParentStackTrace ), 0 );
|
||||
for( int i = iValidEntries; i < ARRAYSIZE( init.ParentStackTrace ); ++i )
|
||||
{
|
||||
init.ParentStackTrace[i] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
m_hThread = (HANDLE)CreateThread( NULL,
|
||||
nBytesStack,
|
||||
(LPTHREAD_START_ROUTINE)GetThreadProc(),
|
||||
new ThreadInit_t(init),
|
||||
nBytesStack ? STACK_SIZE_PARAM_IS_A_RESERVATION : 0,
|
||||
(LPDWORD)&m_threadId );
|
||||
|
||||
if( nPriority != TP_PRIORITY_DEFAULT )
|
||||
{
|
||||
SetThreadPriority( m_hThread, nPriority );
|
||||
}
|
||||
|
||||
if ( !m_hThread )
|
||||
{
|
||||
AssertMsg1( 0, "Failed to create thread (error 0x%x)", GetLastError() );
|
||||
return false;
|
||||
}
|
||||
#elif PLATFORM_PS3
|
||||
// On the PS3, a stack size of 0 doesn't imply a default stack size, so we need to force it to our
|
||||
// own default size.
|
||||
if ( nBytesStack == 0 )
|
||||
{
|
||||
nBytesStack = PS3_SYS_PPU_THREAD_COMMON_STACK_SIZE;
|
||||
}
|
||||
|
||||
//The thread is about to begin
|
||||
m_threadEnd.Reset();
|
||||
|
||||
// sony documentation:
|
||||
// "If the PPU thread is not joined by sys_ppu_thread_join() after exit,
|
||||
// it should always be created as non-joinable (not specifying
|
||||
// SYS_PPU_THREAD_CREATE_JOINABLE). Otherwise, some resources are left
|
||||
// allocated after termination of the PPU thread as if memory leaks."
|
||||
const char* threadName=m_szName;
|
||||
if ( sys_ppu_thread_create( &m_threadId,
|
||||
(void(*)(uint64_t))GetThreadProc(),
|
||||
(uint64_t)(new ThreadInit_t( init )),
|
||||
nPriority,
|
||||
nBytesStack,
|
||||
SYS_PPU_THREAD_CREATE_JOINABLE ,
|
||||
threadName ) != CELL_OK )
|
||||
{
|
||||
AssertMsg1( 0, "Failed to create thread (error 0x%x)", errno );
|
||||
return false;
|
||||
}
|
||||
|
||||
bInitSuccess = true;
|
||||
#elif POSIX
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init( &attr );
|
||||
pthread_attr_setstacksize( &attr, MAX( nBytesStack, 1024u*1024 ) );
|
||||
//lwss - fix memory leak here
|
||||
m_threadInit = ThreadInit_t( init );
|
||||
//if ( pthread_create( &m_threadId, &attr, (void *(*)(void *))GetThreadProc(), new ThreadInit_t( init ) ) != 0 )
|
||||
if ( pthread_create( &m_threadId, &attr, (void *(*)(void *))GetThreadProc(), &m_threadInit ) != 0 )
|
||||
//lwss end
|
||||
{
|
||||
AssertMsg1( 0, "Failed to create thread (error 0x%x)", GetLastError() );
|
||||
return false;
|
||||
}
|
||||
bInitSuccess = true;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if ( !WaitForCreateComplete( &createComplete ) )
|
||||
{
|
||||
Msg( "Thread failed to initialize\n" );
|
||||
#ifdef _WIN32
|
||||
CloseHandle( m_hThread );
|
||||
m_hThread = NULL;
|
||||
#elif defined( _PS3 )
|
||||
m_threadEnd.Set();
|
||||
m_threadId = NULL;
|
||||
m_threadZombieId = 0;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !bInitSuccess )
|
||||
{
|
||||
Msg( "Thread failed to initialize\n" );
|
||||
#ifdef _WIN32
|
||||
CloseHandle( m_hThread );
|
||||
m_hThread = NULL;
|
||||
#elif defined(POSIX) && !defined( _PS3 )
|
||||
m_threadId = 0;
|
||||
m_threadZombieId = 0;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( !m_hThread )
|
||||
{
|
||||
Msg( "Thread exited immediately\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
AddThreadHandleToIDMap( m_hThread, m_threadId );
|
||||
return !!m_hThread;
|
||||
#elif defined(POSIX)
|
||||
return !!m_threadId;
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//
|
||||
// Return true if the thread has been created and hasn't yet exited
|
||||
//
|
||||
|
||||
INLINE_ON_PS3 bool CThread::IsAlive()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD dwExitCode;
|
||||
return (
|
||||
m_hThread
|
||||
&& GetExitCodeThread(m_hThread, &dwExitCode)
|
||||
&& dwExitCode == STILL_ACTIVE );
|
||||
#elif defined(POSIX)
|
||||
return !!m_threadId;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This method causes the current thread to wait until this thread
|
||||
// is no longer alive.
|
||||
INLINE_ON_PS3 bool CThread::Join( unsigned timeout )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( m_hThread )
|
||||
#elif defined(POSIX)
|
||||
if ( m_threadId || m_threadZombieId )
|
||||
#endif
|
||||
{
|
||||
AssertMsg(GetCurrentCThread() != this, _T("Thread cannot be joined with self"));
|
||||
|
||||
#ifdef _WIN32
|
||||
return ThreadJoin( (ThreadHandle_t)m_hThread, timeout );
|
||||
#elif defined(POSIX)
|
||||
bool ret = ThreadJoin( (ThreadHandle_t)(m_threadId ? m_threadId : m_threadZombieId), timeout );
|
||||
m_threadZombieId = 0;
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
INLINE_ON_PS3 ThreadHandle_t CThread::GetThreadHandle()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (ThreadHandle_t)m_hThread;
|
||||
#else
|
||||
return (ThreadHandle_t)m_threadId;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
INLINE_ON_PS3 int CThread::GetResult()
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Functions for both this, and maybe, and other threads
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Forcibly, abnormally, but relatively cleanly stop the thread
|
||||
//
|
||||
|
||||
INLINE_ON_PS3 void CThread::Stop(int exitCode)
|
||||
{
|
||||
if ( !IsAlive() )
|
||||
return;
|
||||
|
||||
if ( GetCurrentCThread() == this )
|
||||
{
|
||||
#if !defined( _PS3 )
|
||||
m_result = exitCode;
|
||||
if ( !( m_flags & SUPPORT_STOP_PROTOCOL ) )
|
||||
{
|
||||
OnExit();
|
||||
g_pCurThread = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
CloseHandle( m_hThread );
|
||||
RemoveThreadHandleToIDMap( m_hThread );
|
||||
m_hThread = NULL;
|
||||
#else
|
||||
m_threadId = 0;
|
||||
m_threadZombieId = 0;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
throw exitCode;
|
||||
}
|
||||
#else
|
||||
AssertMsg( false, "Called CThread::Stop() for a platform that doesn't have it!\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
AssertMsg( 0, "Only thread can stop self: Use a higher-level protocol");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
// Get the priority
|
||||
INLINE_ON_PS3 int CThread::GetPriority() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return GetThreadPriority(m_hThread);
|
||||
#elif defined( _PS3 )
|
||||
return ThreadGetPriority( (ThreadHandle_t) m_threadId );
|
||||
#elif defined(POSIX)
|
||||
struct sched_param thread_param;
|
||||
int policy;
|
||||
pthread_getschedparam( m_threadId, &policy, &thread_param );
|
||||
return thread_param.sched_priority;
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
// Set the priority
|
||||
INLINE_ON_PS3 bool CThread::SetPriority(int priority)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return ThreadSetPriority( (ThreadHandle_t)m_hThread, priority );
|
||||
#else
|
||||
return ThreadSetPriority( (ThreadHandle_t)m_threadId, priority );
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
// Suspend a thread
|
||||
INLINE_ON_PS3 unsigned CThread::Suspend()
|
||||
{
|
||||
AssertMsg( ThreadGetCurrentId() == (ThreadId_t)m_threadId, "Cannot call CThread::Suspend from outside thread" );
|
||||
|
||||
if ( ThreadGetCurrentId() != (ThreadId_t)m_threadId )
|
||||
{
|
||||
DebuggerBreakIfDebugging();
|
||||
}
|
||||
|
||||
m_NotSuspendedEvent.Reset();
|
||||
m_NotSuspendedEvent.Wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
INLINE_ON_PS3 unsigned CThread::Resume()
|
||||
{
|
||||
if ( m_NotSuspendedEvent.Check() )
|
||||
{
|
||||
DevWarning( "Called Resume() on a thread that is not suspended!\n" );
|
||||
}
|
||||
m_NotSuspendedEvent.Set();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
// Force hard-termination of thread. Used for critical failures.
|
||||
INLINE_ON_PS3 bool CThread::Terminate(int exitCode)
|
||||
{
|
||||
#if defined( _X360 )
|
||||
AssertMsg( 0, "Cannot terminate a thread on the Xbox!" );
|
||||
return false;
|
||||
#elif defined( _WIN32 )
|
||||
// I hope you know what you're doing!
|
||||
if (!TerminateThread(m_hThread, exitCode))
|
||||
return false;
|
||||
CloseHandle( m_hThread );
|
||||
RemoveThreadHandleToIDMap( m_hThread );
|
||||
m_hThread = NULL;
|
||||
#elif defined( _PS3 )
|
||||
m_threadEnd.Set();
|
||||
m_threadId = NULL;
|
||||
#elif defined(POSIX)
|
||||
pthread_kill( m_threadId, SIGKILL );
|
||||
m_threadId = 0;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Global methods
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Get the Thread object that represents the current thread, if any.
|
||||
// Can return NULL if the current thread was not created using
|
||||
// CThread
|
||||
//
|
||||
|
||||
INLINE_ON_PS3 CThread *CThread::GetCurrentCThread()
|
||||
{
|
||||
#ifdef _PS3
|
||||
return GetCurThreadPS3();
|
||||
#else
|
||||
return g_pCurThread;
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//
|
||||
// Offer a context switch. Under Win32, equivalent to Sleep(0)
|
||||
//
|
||||
|
||||
#ifdef Yield
|
||||
#undef Yield
|
||||
#endif
|
||||
INLINE_ON_PS3 void CThread::Yield()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::Sleep(0);
|
||||
#elif defined( _PS3 )
|
||||
// sys_ppu_thread_yield doesn't seem to function properly, so sleep instead.
|
||||
sys_timer_usleep( 60 );
|
||||
#elif defined(POSIX)
|
||||
sched_yield();
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//
|
||||
// This method causes the current thread to yield and not to be
|
||||
// scheduled for further execution until a certain amount of real
|
||||
// time has elapsed, more or less. Duration is in milliseconds
|
||||
|
||||
INLINE_ON_PS3 void CThread::Sleep( unsigned duration )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::Sleep(duration);
|
||||
#elif defined (_PS3)
|
||||
sys_timer_usleep( duration * 1000 );
|
||||
#elif defined(POSIX)
|
||||
usleep( duration * 1000 );
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
// Optional pre-run call, with ability to fail-create. Note Init()
|
||||
// is forced synchronous with Start()
|
||||
INLINE_ON_PS3 bool CThread::Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
#if defined( _PS3 )
|
||||
INLINE_ON_PS3 int CThread::Run()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif // _PS3
|
||||
|
||||
// Called when the thread exits
|
||||
INLINE_ON_PS3 void CThread::OnExit() { }
|
||||
|
||||
// Allow for custom start waiting
|
||||
INLINE_ON_PS3 bool CThread::WaitForCreateComplete( CThreadEvent *pEvent )
|
||||
{
|
||||
// Force serialized thread creation...
|
||||
if (!pEvent->Wait(60000))
|
||||
{
|
||||
AssertMsg( 0, "Probably deadlock or failure waiting for thread to initialize." );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
INLINE_ON_PS3 bool CThread::IsThreadRunning()
|
||||
{
|
||||
#ifdef _PS3
|
||||
// ThreadIsThreadIdRunning() doesn't work on PS3 if the thread is in a zombie state
|
||||
return m_eventTheadExit.Check();
|
||||
#else
|
||||
return ThreadIsThreadIdRunning( (ThreadId_t)m_threadId );
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
INLINE_ON_PS3 CThread::ThreadProc_t CThread::GetThreadProc()
|
||||
{
|
||||
return ThreadProc;
|
||||
}
|
||||
|
||||
INLINE_ON_PS3 void CThread::ThreadProcRunWithMinidumpHandler( void *pv )
|
||||
{
|
||||
ThreadInit_t *pInit = reinterpret_cast<ThreadInit_t*>(pv);
|
||||
pInit->pThread->m_result = pInit->pThread->Run();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
unsigned long STDCALL CThread::ThreadProc(LPVOID pv)
|
||||
#else
|
||||
INLINE_ON_PS3 void* CThread::ThreadProc(LPVOID pv)
|
||||
#endif
|
||||
{
|
||||
// #if defined( POSIX ) || defined( _PS3 )
|
||||
ThreadInit_t *pInit = reinterpret_cast<ThreadInit_t*>(pv);
|
||||
// #else
|
||||
// std::auto_ptr<ThreadInit_t> pInit((ThreadInit_t *)pv);
|
||||
// #endif
|
||||
|
||||
#ifdef _X360
|
||||
// Make sure all threads are consistent w.r.t floating-point math
|
||||
SetupFPUControlWord();
|
||||
#endif
|
||||
AllocateThreadID();
|
||||
|
||||
CThread *pThread = pInit->pThread;
|
||||
#ifdef _PS3
|
||||
SetCurThreadPS3( pThread );
|
||||
#else
|
||||
g_pCurThread = pThread;
|
||||
#endif
|
||||
|
||||
pThread->m_pStackBase = AlignValue( &pThread, 4096 );
|
||||
|
||||
pInit->pThread->m_result = -1;
|
||||
|
||||
#if defined( THREAD_PARENT_STACK_TRACE_ENABLED )
|
||||
CStackTop_ReferenceParentStack stackTop( pInit->ParentStackTrace, ARRAYSIZE( pInit->ParentStackTrace ) );
|
||||
#endif
|
||||
|
||||
bool bInitSuccess = true;
|
||||
if ( pInit->pfInitSuccess )
|
||||
*(pInit->pfInitSuccess) = false;
|
||||
|
||||
#ifdef _PS3
|
||||
*(pInit->pfInitSuccess) = pInit->pThread->Init();
|
||||
#else
|
||||
try
|
||||
{
|
||||
bInitSuccess = pInit->pThread->Init();
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
pInit->pInitCompleteEvent->Set();
|
||||
throw;
|
||||
}
|
||||
#endif // _PS3
|
||||
|
||||
if ( pInit->pfInitSuccess )
|
||||
*(pInit->pfInitSuccess) = bInitSuccess;
|
||||
pInit->pInitCompleteEvent->Set();
|
||||
if (!bInitSuccess)
|
||||
return 0;
|
||||
|
||||
if ( !Plat_IsInDebugSession() && (pInit->pThread->m_flags & SUPPORT_STOP_PROTOCOL) )
|
||||
{
|
||||
#ifndef _PS3
|
||||
try
|
||||
#endif
|
||||
{
|
||||
pInit->pThread->m_result = pInit->pThread->Run();
|
||||
}
|
||||
|
||||
#ifndef _PS3
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined( _WIN32 )
|
||||
CatchAndWriteMiniDumpForVoidPtrFn( ThreadProcRunWithMinidumpHandler, pv, false );
|
||||
#else
|
||||
pInit->pThread->m_result = pInit->pThread->Run();
|
||||
#endif
|
||||
}
|
||||
|
||||
pInit->pThread->OnExit();
|
||||
#ifdef _PS3
|
||||
SetCurThreadPS3( NULL );
|
||||
#else
|
||||
g_pCurThread = NULL;
|
||||
#endif
|
||||
FreeThreadID();
|
||||
|
||||
AUTO_LOCK( pThread->m_Lock );
|
||||
#ifdef _WIN32
|
||||
CloseHandle( pThread->m_hThread );
|
||||
RemoveThreadHandleToIDMap( pThread->m_hThread );
|
||||
pThread->m_hThread = NULL;
|
||||
#elif defined( _PS3 )
|
||||
pThread->m_threadZombieId = pThread->m_threadId;
|
||||
pThread->m_threadEnd.Set();
|
||||
pThread->m_threadId = 0;
|
||||
#elif defined(POSIX)
|
||||
pThread->m_threadZombieId = pThread->m_threadId;
|
||||
pThread->m_threadId = 0;
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
pThread->m_ExitEvent.Set();
|
||||
#ifdef _PS3
|
||||
{
|
||||
pThread->m_Lock.Unlock();
|
||||
sys_ppu_thread_exit( pInit->pThread->m_result );
|
||||
// reacquire the lock in case thread exit didn't actually exit the thread, so that
|
||||
// AUTO_LOCK won't double-unlock the lock (to keep it paired)
|
||||
pThread->m_Lock.Lock();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined( POSIX )|| defined( _PS3 )
|
||||
return (void*)(uintp)pInit->pThread->m_result;
|
||||
#else
|
||||
return pInit->pThread->m_result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // THREADTOOLS_INL
|
||||
+96
-73
@@ -36,15 +36,38 @@
|
||||
|
||||
#if defined( PLATFORM_64BITS )
|
||||
|
||||
#if defined (PLATFORM_WINDOWS)
|
||||
//typedef __m128i int128;
|
||||
//inline int128 int128_zero() { return _mm_setzero_si128(); }
|
||||
#else // PLATFORM_WINDOWS
|
||||
typedef __int128_t int128;
|
||||
#define int128_zero() 0
|
||||
#endif// PLATFORM_WINDOWS
|
||||
|
||||
#define TSLIST_HEAD_ALIGNMENT 16
|
||||
#define TSLIST_NODE_ALIGNMENT 16
|
||||
|
||||
#ifdef POSIX
|
||||
inline bool ThreadInterlockedAssignIf128( int128 volatile * pDest, const int128 &value, const int128 &comparand )
|
||||
{
|
||||
// We do not want the original comparand modified by the swap
|
||||
// so operate on a local copy.
|
||||
int128 local_comparand = comparand;
|
||||
return __sync_bool_compare_and_swap( pDest, local_comparand, value );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool ThreadInterlockedAssignIf64x128( volatile int128 *pDest, const int128 &value, const int128 &comperand )
|
||||
{ return ThreadInterlockedAssignIf128( pDest, value, comperand ); }
|
||||
{
|
||||
return ThreadInterlockedAssignIf128( pDest, value, comperand );
|
||||
}
|
||||
#else
|
||||
#define TSLIST_HEAD_ALIGNMENT 8
|
||||
#define TSLIST_NODE_ALIGNMENT 8
|
||||
inline bool ThreadInterlockedAssignIf64x128( volatile int64 *pDest, const int64 value, const int64 comperand )
|
||||
{ return ThreadInterlockedAssignIf64( pDest, value, comperand ); }
|
||||
{
|
||||
return ThreadInterlockedAssignIf64( pDest, value, comperand );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -99,13 +122,13 @@ union TSLIST_HEAD_ALIGN TSLHead_t
|
||||
// because Sequence can be pretty much random. We could operate on both of them separately,
|
||||
// but it could perhaps (?) lead to problems with store forwarding. I don't know 'cause I didn't
|
||||
// performance-test or design original code, I'm just making it work on PowerPC.
|
||||
#ifdef VALVE_BIG_ENDIAN
|
||||
#ifdef VALVE_BIG_ENDIAN
|
||||
int16 Sequence;
|
||||
int16 Depth;
|
||||
#else
|
||||
#else
|
||||
int16 Depth;
|
||||
int16 Sequence;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef PLATFORM_64BITS
|
||||
int32 Padding;
|
||||
#endif
|
||||
@@ -132,33 +155,33 @@ class CTSListBase
|
||||
public:
|
||||
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new( size_t size )
|
||||
static void * operator new(size_t size)
|
||||
{
|
||||
CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAlignedFileLine( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
|
||||
static void * operator new(size_t size, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
|
||||
CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAlignedFileLine( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void operator delete( void *p)
|
||||
static void operator delete(void *p)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
|
||||
static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
|
||||
static void operator delete(void *p, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
|
||||
private:
|
||||
// These ain't gonna work
|
||||
static void * operator new[] ( size_t size );
|
||||
static void operator delete [] ( void *p);
|
||||
|
||||
static void * operator new[]( size_t size );
|
||||
static void operator delete[]( void *p );
|
||||
|
||||
public:
|
||||
|
||||
CTSListBase()
|
||||
@@ -204,22 +227,22 @@ public:
|
||||
TSLHead_t oldHead;
|
||||
TSLHead_t newHead;
|
||||
|
||||
#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
|
||||
#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
|
||||
__lwsync(); // write-release barrier
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
newHead.value.Padding = 0;
|
||||
#endif
|
||||
for (;;)
|
||||
for ( ;; )
|
||||
{
|
||||
oldHead.value64x128 = m_Head.value64x128;
|
||||
pNode->Next = oldHead.value.Next;
|
||||
newHead.value.Next = pNode;
|
||||
|
||||
|
||||
newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence + 0x10001;
|
||||
|
||||
|
||||
|
||||
|
||||
if ( ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) )
|
||||
{
|
||||
break;
|
||||
@@ -248,21 +271,21 @@ public:
|
||||
#ifdef PLATFORM_64BITS
|
||||
newHead.value.Padding = 0;
|
||||
#endif
|
||||
for (;;)
|
||||
for ( ;; )
|
||||
{
|
||||
oldHead.value64x128 = m_Head.value64x128;
|
||||
if ( !oldHead.value.Next )
|
||||
return NULL;
|
||||
|
||||
newHead.value.Next = oldHead.value.Next->Next;
|
||||
newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence - 1;
|
||||
newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence - 1;
|
||||
|
||||
|
||||
if ( ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) )
|
||||
{
|
||||
#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
|
||||
__lwsync(); // read-acquire barrier
|
||||
#endif
|
||||
#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
|
||||
__lwsync(); // read-acquire barrier
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
ThreadPause();
|
||||
@@ -301,7 +324,7 @@ public:
|
||||
// I didn't construct this code. In any case, leaving it as is on big-endian
|
||||
newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence & 0xffff0000;
|
||||
|
||||
} while( !ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) );
|
||||
} while ( !ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) );
|
||||
|
||||
return (TSLNodeBase_t *)oldHead.value.Next;
|
||||
#endif
|
||||
@@ -315,7 +338,7 @@ public:
|
||||
int Count() const
|
||||
{
|
||||
#ifdef USE_NATIVE_SLIST
|
||||
return QueryDepthSList( const_cast<TSLHead_t*>( &m_Head ) );
|
||||
return QueryDepthSList( const_cast<TSLHead_t*>(&m_Head) );
|
||||
#else
|
||||
return m_Head.value.Depth;
|
||||
#endif
|
||||
@@ -349,7 +372,7 @@ public:
|
||||
// similar to CTSSimpleList except that it allocates it's own pool objects
|
||||
// and frees them on destruct. Also it does not overlay the TSNodeBase_t memory
|
||||
// on T's memory
|
||||
template< class T >
|
||||
template< class T >
|
||||
class TSLIST_HEAD_ALIGN CTSPool : public CTSListBase
|
||||
{
|
||||
// packs the node and the item (T) into a single struct and pools those
|
||||
@@ -380,7 +403,7 @@ public:
|
||||
void PutObject( T *pInfo )
|
||||
{
|
||||
char *pElem = (char *)pInfo;
|
||||
pElem -= offsetof(simpleTSPoolStruct_t,elem);
|
||||
pElem -= offsetof( simpleTSPoolStruct_t, elem );
|
||||
simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)pElem;
|
||||
|
||||
CTSListBase::Push( pNode );
|
||||
@@ -414,25 +437,25 @@ public:
|
||||
Node_t( const T &init ) : elem( init ) {}
|
||||
T elem;
|
||||
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new( size_t size )
|
||||
{
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_NODE_ALIGNMENT, __FILE__, __LINE__ );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
|
||||
static void * operator new(size_t size)
|
||||
{
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_NODE_ALIGNMENT, pFileName, nLine );
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAlignedFileLine( size, TSLIST_NODE_ALIGNMENT, __FILE__, __LINE__ );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void operator delete( void *p)
|
||||
{
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new(size_t size, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAlignedFileLine( size, TSLIST_NODE_ALIGNMENT, pFileName, nLine );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void operator delete(void *p)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
|
||||
}
|
||||
static void operator delete(void *p, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
@@ -476,7 +499,7 @@ public:
|
||||
Push( new Node_t( init ) );
|
||||
}
|
||||
|
||||
bool PopItem( T *pResult)
|
||||
bool PopItem( T *pResult )
|
||||
{
|
||||
Node_t *pNode = Pop();
|
||||
if ( !pNode )
|
||||
@@ -564,7 +587,7 @@ public:
|
||||
Push( pNode );
|
||||
}
|
||||
|
||||
bool PopItem( T *pResult)
|
||||
bool PopItem( T *pResult )
|
||||
{
|
||||
Node_t *pNode = Pop();
|
||||
if ( !pNode )
|
||||
@@ -608,37 +631,37 @@ class TSLIST_HEAD_ALIGN CTSQueue
|
||||
public:
|
||||
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new( size_t size )
|
||||
static void * operator new(size_t size)
|
||||
{
|
||||
CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAlignedFileLine( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
|
||||
static void * operator new(size_t size, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
|
||||
CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAlignedFileLine( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void operator delete( void *p)
|
||||
static void operator delete(void *p)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
|
||||
static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
|
||||
static void operator delete(void *p, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
|
||||
private:
|
||||
// These ain't gonna work
|
||||
static void * operator new[] ( size_t size ) throw()
|
||||
static void * operator new[]( size_t size ) throw()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void operator delete [] ( void *p)
|
||||
static void operator delete []( void *p )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -647,24 +670,24 @@ public:
|
||||
struct TSLIST_NODE_ALIGN Node_t
|
||||
{
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new( size_t size )
|
||||
static void * operator new(size_t size)
|
||||
{
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAlignedFileLine( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
|
||||
static void * operator new(size_t size, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
|
||||
Node_t *pNode = (Node_t *)MemAlloc_AllocAlignedFileLine( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void operator delete( void *p)
|
||||
static void operator delete(void *p)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
|
||||
static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
|
||||
static void operator delete(void *p, int nBlockUse, const char *pFileName, int nLine)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
@@ -679,13 +702,13 @@ public:
|
||||
union TSLIST_HEAD_ALIGN NodeLink_t
|
||||
{
|
||||
// override new/delete so we can guarantee 8-byte aligned allocs
|
||||
static void * operator new( size_t size )
|
||||
static void * operator new(size_t size)
|
||||
{
|
||||
NodeLink_t *pNode = (NodeLink_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
NodeLink_t *pNode = (NodeLink_t *)MemAlloc_AllocAlignedFileLine( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void operator delete( void *p)
|
||||
static void operator delete(void *p)
|
||||
{
|
||||
MemAlloc_FreeAligned( p );
|
||||
}
|
||||
@@ -740,12 +763,12 @@ public:
|
||||
}
|
||||
|
||||
Node_t *pNode;
|
||||
while ( ( pNode = Pop() ) != NULL )
|
||||
while ( (pNode = Pop()) != NULL )
|
||||
{
|
||||
delete pNode;
|
||||
}
|
||||
|
||||
while ( ( pNode = (Node_t *)m_FreeNodes.Pop() ) != NULL )
|
||||
while ( (pNode = (Node_t *)m_FreeNodes.Pop()) != NULL )
|
||||
{
|
||||
delete pNode;
|
||||
}
|
||||
@@ -765,7 +788,7 @@ public:
|
||||
}
|
||||
|
||||
Node_t *pNode;
|
||||
while ( ( pNode = Pop() ) != NULL )
|
||||
while ( (pNode = Pop()) != NULL )
|
||||
{
|
||||
m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
|
||||
}
|
||||
@@ -846,7 +869,7 @@ public:
|
||||
|
||||
pNode->pNext = End();
|
||||
|
||||
for (;;)
|
||||
for ( ;; )
|
||||
{
|
||||
oldTail.value.sequence = m_Tail.value.sequence;
|
||||
oldTail.value.pNode = m_Tail.value.pNode;
|
||||
@@ -870,7 +893,7 @@ public:
|
||||
|
||||
Node_t *Pop()
|
||||
{
|
||||
#define TSQUEUE_BAD_NODE_LINK ( (Node_t *)INT_TO_POINTER( 0xdeadbeef ) )
|
||||
#define TSQUEUE_BAD_NODE_LINK ( (Node_t *)INT_TO_POINTER( 0xdeadbeef ) )
|
||||
NodeLink_t * volatile pHead = &m_Head;
|
||||
NodeLink_t * volatile pTail = &m_Tail;
|
||||
Node_t * volatile * pHeadNode = &m_Head.value.pNode;
|
||||
@@ -883,17 +906,17 @@ public:
|
||||
intp tailSequence;
|
||||
T elem;
|
||||
|
||||
for (;;)
|
||||
for ( ;; )
|
||||
{
|
||||
head.value.sequence = *pHeadSequence; // must grab sequence first, which allows condition below to ensure pNext is valid
|
||||
ThreadMemoryBarrier(); // need a barrier to prevent reordering of these assignments
|
||||
head.value.pNode = *pHeadNode;
|
||||
tailSequence = pTail->value.sequence;
|
||||
pNext = head.value.pNode->pNext;
|
||||
head.value.pNode = *pHeadNode;
|
||||
tailSequence = pTail->value.sequence;
|
||||
pNext = head.value.pNode->pNext;
|
||||
|
||||
// Checking pNext only to force optimizer to not reorder the assignment
|
||||
// to pNext and the compare of the sequence
|
||||
if ( !pNext || head.value.sequence != *pHeadSequence )
|
||||
if ( !pNext || head.value.sequence != *pHeadSequence )
|
||||
continue;
|
||||
|
||||
if ( bTestOptimizer )
|
||||
@@ -916,7 +939,7 @@ public:
|
||||
FinishPush( pNext, oldTail );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if ( pNext != End() )
|
||||
{
|
||||
elem = pNext->elem; // NOTE: next could be a freed node here, by design
|
||||
@@ -991,7 +1014,7 @@ private:
|
||||
NodeLink_t m_Tail;
|
||||
|
||||
CInterlockedInt m_Count;
|
||||
|
||||
|
||||
CTSListBase m_FreeNodes;
|
||||
} TSLIST_NODE_ALIGN_POST;
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ typedef struct VCR_s
|
||||
void *lpStartAddress,
|
||||
void *lpParameter,
|
||||
unsigned long dwCreationFlags,
|
||||
unsigned long *lpThreadID );
|
||||
uintp *lpThreadID );
|
||||
|
||||
unsigned long (*Hook_WaitForSingleObject)(
|
||||
void *handle,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#if !( defined( _X360 ) && defined( _CERT ) )
|
||||
#define VPROF_ENABLED
|
||||
#endif
|
||||
// TODO(nillerusr): make stubbed vprofile
|
||||
|
||||
#if defined(_X360) && defined(VPROF_ENABLED)
|
||||
#include "tier0/pmc360.h"
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#define tmBeginTimeSpanAt(...)
|
||||
#define tmEndTimeSpanAt(...)
|
||||
#define tmLeave(...)
|
||||
#define TM_MESSAGE(...)
|
||||
#define TM_ENTER(...)
|
||||
#define TM_LEAVE(...)
|
||||
#define TM_ZONE(...)
|
||||
#define TM_ZONE_DEFAULT(...)
|
||||
#define TM_ZONE_DEFAULT_PARAM(...)
|
||||
#define TelemetryTick(...)
|
||||
@@ -28,4 +32,6 @@
|
||||
#define tmTryLock(...)
|
||||
#define tmSetLockState(...)
|
||||
|
||||
typedef unsigned long long TmU64;
|
||||
|
||||
#endif // VPROF_TELEMETRY_H
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// Temporarily turn off Valve defines
|
||||
#include "tier0/valve_off.h"
|
||||
|
||||
#if !defined(_WCHAR_T_DEFINED) && !defined(GNUC)
|
||||
#if !defined(_WCHAR_T_DEFINED) && !defined( __WCHAR_TYPE__ ) && !defined(GNUC)
|
||||
typedef unsigned short wchar_t;
|
||||
#define _WCHAR_T_DEFINED
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@ class CUtlBuffer;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Invalid command handle
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef int CommandHandle_t;
|
||||
typedef intp CommandHandle_t;
|
||||
enum
|
||||
{
|
||||
COMMAND_BUFFER_INVALID_COMMAND_HANDLE = 0
|
||||
@@ -100,11 +100,11 @@ private:
|
||||
};
|
||||
|
||||
// Insert a command into the command queue at the appropriate time
|
||||
void InsertCommandAtAppropriateTime( int hCommand );
|
||||
void InsertCommandAtAppropriateTime( CommandHandle_t hCommand );
|
||||
|
||||
// Insert a command into the command queue
|
||||
// Only happens if it's inserted while processing other commands
|
||||
void InsertImmediateCommand( int hCommand );
|
||||
void InsertImmediateCommand( CommandHandle_t hCommand );
|
||||
|
||||
// Insert a command into the command queue
|
||||
bool InsertCommand( const char *pArgS, int nCommandSize, int nTick );
|
||||
@@ -125,7 +125,7 @@ private:
|
||||
int m_nCurrentTick;
|
||||
int m_nLastTickToProcess;
|
||||
int m_nWaitDelayTicks;
|
||||
int m_hNextCommand;
|
||||
CommandHandle_t m_hNextCommand;
|
||||
int m_nMaxArgSBufferLength;
|
||||
bool m_bIsProcessingCommands;
|
||||
bool m_bWaitEnabled;
|
||||
|
||||
+11
-11
@@ -115,7 +115,7 @@ public:
|
||||
void SetName( const char *setName);
|
||||
|
||||
// gets the name as a unique int
|
||||
int GetNameSymbol() const { return m_iKeyName; }
|
||||
intp GetNameSymbol() const { return m_iKeyName; }
|
||||
|
||||
// File access. Set UsesEscapeSequences true, if resource file/buffer uses Escape Sequences (eg \n, \t)
|
||||
void UsesEscapeSequences(bool state); // default false
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
// Find a keyValue, create it if it is not found.
|
||||
// Set bCreate to true to create the key if it doesn't already exist (which ensures a valid pointer will be returned)
|
||||
KeyValues *FindKey(const char *keyName, bool bCreate = false);
|
||||
KeyValues *FindKey(int keySymbol) const;
|
||||
KeyValues *FindKey(intp keySymbol) const;
|
||||
KeyValues *CreateNewKey(); // creates a new key, with an autogenerated name. name is guaranteed to be an integer, of value 1 higher than the highest other integer key name
|
||||
void AddSubKey( KeyValues *pSubkey ); // Adds a subkey. Make sure the subkey isn't a child of some other keyvalues
|
||||
void RemoveSubKey(KeyValues *subKey); // removes a subkey from the list, DOES NOT DELETE IT
|
||||
@@ -311,7 +311,7 @@ private:
|
||||
void FreeAllocatedValue();
|
||||
void AllocateValueBlock(int size);
|
||||
|
||||
int m_iKeyName; // keyname is a symbol defined in KeyValuesSystem
|
||||
intp m_iKeyName; // keyname is a symbol defined in KeyValuesSystem
|
||||
|
||||
// These are needed out of the union because the API returns string pointers
|
||||
char *m_sValue;
|
||||
@@ -338,22 +338,22 @@ private:
|
||||
private:
|
||||
// Statics to implement the optional growable string table
|
||||
// Function pointers that will determine which mode we are in
|
||||
static int (*s_pfGetSymbolForString)( const char *name, bool bCreate );
|
||||
static const char *(*s_pfGetStringForSymbol)( int symbol );
|
||||
static intp (*s_pfGetSymbolForString)( const char *name, bool bCreate );
|
||||
static const char *(*s_pfGetStringForSymbol)( intp symbol );
|
||||
static CKeyValuesGrowableStringTable *s_pGrowableStringTable;
|
||||
|
||||
public:
|
||||
// Functions that invoke the default behavior
|
||||
static int GetSymbolForStringClassic( const char *name, bool bCreate = true );
|
||||
static const char *GetStringForSymbolClassic( int symbol );
|
||||
static intp GetSymbolForStringClassic( const char *name, bool bCreate = true );
|
||||
static const char *GetStringForSymbolClassic( intp symbol );
|
||||
|
||||
// Functions that use the growable string table
|
||||
static int GetSymbolForStringGrowable( const char *name, bool bCreate = true );
|
||||
static const char *GetStringForSymbolGrowable( int symbol );
|
||||
static intp GetSymbolForStringGrowable( const char *name, bool bCreate = true );
|
||||
static const char *GetStringForSymbolGrowable( intp symbol );
|
||||
|
||||
// Functions to get external access to whichever of the above functions we're going to call.
|
||||
static int CallGetSymbolForString( const char *name, bool bCreate = true ) { return s_pfGetSymbolForString( name, bCreate ); }
|
||||
static const char *CallGetStringForSymbol( int symbol ) { return s_pfGetStringForSymbol( symbol ); }
|
||||
static intp CallGetSymbolForString( const char *name, bool bCreate = true ) { return s_pfGetSymbolForString( name, bCreate ); }
|
||||
static const char *CallGetStringForSymbol( intp symbol ) { return s_pfGetStringForSymbol( symbol ); }
|
||||
};
|
||||
|
||||
typedef KeyValues::AutoDelete KeyValuesAD;
|
||||
|
||||
+15
-15
@@ -225,7 +225,7 @@ public:
|
||||
void WriteByte(int val);
|
||||
void WriteShort(int val);
|
||||
void WriteWord(int val);
|
||||
void WriteLong(long val);
|
||||
void WriteLong(int32 val);
|
||||
void WriteLongLong(int64 val);
|
||||
void WriteFloat(float val);
|
||||
bool WriteBytes( const void *pBuf, int nBytes );
|
||||
@@ -255,7 +255,7 @@ public:
|
||||
|
||||
public:
|
||||
// The current buffer.
|
||||
unsigned long* RESTRICT m_pData;
|
||||
uint32* RESTRICT m_pData;
|
||||
int m_nDataBytes;
|
||||
int m_nDataBits;
|
||||
|
||||
@@ -342,7 +342,7 @@ BITBUF_INLINE void bf_write::WriteOneBitNoCheck(int nValue)
|
||||
else
|
||||
m_pData[m_iCurBit >> 5] &= ~(1u << (m_iCurBit & 31));
|
||||
#else
|
||||
extern unsigned long g_LittleBits[32];
|
||||
extern uint32 g_LittleBits[32];
|
||||
if(nValue)
|
||||
m_pData[m_iCurBit >> 5] |= g_LittleBits[m_iCurBit & 31];
|
||||
else
|
||||
@@ -379,7 +379,7 @@ inline void bf_write::WriteOneBitAt( int iBit, int nValue )
|
||||
else
|
||||
m_pData[iBit >> 5] &= ~(1u << (iBit & 31));
|
||||
#else
|
||||
extern unsigned long g_LittleBits[32];
|
||||
extern uint32 g_LittleBits[32];
|
||||
if(nValue)
|
||||
m_pData[iBit >> 5] |= g_LittleBits[iBit & 31];
|
||||
else
|
||||
@@ -393,7 +393,7 @@ BITBUF_INLINE void bf_write::WriteUBitLong( unsigned int curData, int numbits, b
|
||||
// Make sure it doesn't overflow.
|
||||
if ( bCheckRange && numbits < 32 )
|
||||
{
|
||||
if ( curData >= (unsigned long)(1 << numbits) )
|
||||
if ( curData >= (uint32)(1 << numbits) )
|
||||
{
|
||||
CallErrorHandler( BITBUFERROR_VALUE_OUT_OF_RANGE, GetDebugName() );
|
||||
}
|
||||
@@ -414,8 +414,8 @@ BITBUF_INLINE void bf_write::WriteUBitLong( unsigned int curData, int numbits, b
|
||||
m_iCurBit += numbits;
|
||||
|
||||
// Mask in a dword.
|
||||
Assert( (iDWord*4 + sizeof(long)) <= (unsigned int)m_nDataBytes );
|
||||
unsigned long * RESTRICT pOut = &m_pData[iDWord];
|
||||
Assert( (iDWord*4 + sizeof(int32)) <= (unsigned int)m_nDataBytes );
|
||||
uint32 * RESTRICT pOut = &m_pData[iDWord];
|
||||
|
||||
// Rotate data into dword alignment
|
||||
curData = (curData << iCurBitMasked) | (curData >> (32 - iCurBitMasked));
|
||||
@@ -427,8 +427,8 @@ BITBUF_INLINE void bf_write::WriteUBitLong( unsigned int curData, int numbits, b
|
||||
|
||||
// Only look beyond current word if necessary (avoid access violation)
|
||||
int i = mask2 & 1;
|
||||
unsigned long dword1 = LoadLittleDWord( pOut, 0 );
|
||||
unsigned long dword2 = LoadLittleDWord( pOut, i );
|
||||
uint32 dword1 = LoadLittleDWord( pOut, 0 );
|
||||
uint32 dword2 = LoadLittleDWord( pOut, i );
|
||||
|
||||
// Drop bits into place
|
||||
dword1 ^= ( mask1 & ( curData ^ dword1 ) );
|
||||
@@ -467,7 +467,7 @@ BITBUF_INLINE void bf_write::WriteBitFloat(float val)
|
||||
{
|
||||
int32 intVal;
|
||||
|
||||
Assert(sizeof(long) == sizeof(float));
|
||||
Assert(sizeof(int32) == sizeof(float));
|
||||
Assert(sizeof(float) == 4);
|
||||
|
||||
Q_memcpy( &intVal, &val, sizeof(intVal));
|
||||
@@ -603,7 +603,7 @@ public:
|
||||
BITBUF_INLINE int ReadByte() { return ReadUBitLong(8); }
|
||||
BITBUF_INLINE int ReadShort() { return (short)ReadUBitLong(16); }
|
||||
BITBUF_INLINE int ReadWord() { return ReadUBitLong(16); }
|
||||
BITBUF_INLINE long ReadLong() { return ReadUBitLong(32); }
|
||||
BITBUF_INLINE int32 ReadLong() { return ReadUBitLong(32); }
|
||||
int64 ReadLongLong();
|
||||
float ReadFloat();
|
||||
bool ReadBytes(void *pOut, int nBytes);
|
||||
@@ -728,7 +728,7 @@ inline bool bf_read::CheckForOverflow(int nBits)
|
||||
inline int bf_read::ReadOneBitNoCheck()
|
||||
{
|
||||
#if VALVE_LITTLE_ENDIAN
|
||||
unsigned int value = ((unsigned long * RESTRICT)m_pData)[m_iCurBit >> 5] >> (m_iCurBit & 31);
|
||||
unsigned int value = ((uint32 * RESTRICT)m_pData)[m_iCurBit >> 5] >> (m_iCurBit & 31);
|
||||
#else
|
||||
unsigned char value = m_pData[m_iCurBit >> 3] >> (m_iCurBit & 7);
|
||||
#endif
|
||||
@@ -787,12 +787,12 @@ BITBUF_INLINE unsigned int bf_read::ReadUBitLong( int numbits ) RESTRICT
|
||||
#if __i386__
|
||||
unsigned int bitmask = (2 << (numbits-1)) - 1;
|
||||
#else
|
||||
extern unsigned long g_ExtraMasks[33];
|
||||
extern uint32 g_ExtraMasks[33];
|
||||
unsigned int bitmask = g_ExtraMasks[numbits];
|
||||
#endif
|
||||
|
||||
unsigned int dw1 = LoadLittleDWord( (unsigned long* RESTRICT)m_pData, iWordOffset1 ) >> iStartBit;
|
||||
unsigned int dw2 = LoadLittleDWord( (unsigned long* RESTRICT)m_pData, iWordOffset2 ) << (32 - iStartBit);
|
||||
unsigned int dw1 = LoadLittleDWord( (uint32* RESTRICT)m_pData, iWordOffset1 ) >> iStartBit;
|
||||
unsigned int dw2 = LoadLittleDWord( (uint32* RESTRICT)m_pData, iWordOffset2 ) << (32 - iStartBit);
|
||||
|
||||
return (dw1 | dw2) & bitmask;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -65,6 +65,8 @@ public:
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void SetFreeOnDestruct( bool value ) { m_freeOnDestruct = value; }
|
||||
|
||||
// Debugging only!!!!
|
||||
void GetLRUHandleList( CUtlVector< memhandle_t >& list );
|
||||
void GetLockHandleList( CUtlVector< memhandle_t >& list );
|
||||
@@ -77,6 +79,7 @@ protected:
|
||||
void *GetResource_NoLock( memhandle_t handle );
|
||||
void *GetResource_NoLockNoLRUTouch( memhandle_t handle );
|
||||
void *LockResource( memhandle_t handle );
|
||||
void *LockResourceReturnCount( int *pCount, memhandle_t handle );
|
||||
|
||||
// NOTE: you must call this from the destructor of the derived class! (will assert otherwise)
|
||||
void FreeAllLists() { FlushAll(); m_listsAreFreed = true; }
|
||||
@@ -123,7 +126,8 @@ protected:
|
||||
unsigned short m_lockList;
|
||||
unsigned short m_freeList;
|
||||
unsigned short m_listsAreFreed : 1;
|
||||
unsigned short m_unused : 15;
|
||||
unsigned short m_freeOnDestruct : 1;
|
||||
unsigned short m_unused : 14;
|
||||
|
||||
};
|
||||
|
||||
@@ -139,7 +143,10 @@ public:
|
||||
~CDataManager<STORAGE_TYPE, CREATE_PARAMS, LOCK_TYPE, MUTEX_TYPE>()
|
||||
{
|
||||
// NOTE: This must be called in all implementations of CDataManager
|
||||
FreeAllLists();
|
||||
if ( m_freeOnDestruct )
|
||||
{
|
||||
FreeAllLists();
|
||||
}
|
||||
}
|
||||
|
||||
// Use GetData() to translate pointer to LOCK_TYPE
|
||||
@@ -154,6 +161,17 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOCK_TYPE LockResourceReturnCount( int *pCount, memhandle_t hMem )
|
||||
{
|
||||
void *pLock = BaseClass::LockResourceReturnCount( pCount, hMem );
|
||||
if ( pLock )
|
||||
{
|
||||
return StoragePointer(pLock)->GetData();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Use GetData() to translate pointer to LOCK_TYPE
|
||||
LOCK_TYPE GetResource_NoLock( memhandle_t hMem )
|
||||
{
|
||||
@@ -181,8 +199,9 @@ public:
|
||||
memhandle_t CreateResource( const CREATE_PARAMS &createParams, bool bCreateLocked = false )
|
||||
{
|
||||
BaseClass::EnsureCapacity(STORAGE_TYPE::EstimatedSize(createParams));
|
||||
unsigned short memoryIndex = BaseClass::CreateHandle( bCreateLocked );
|
||||
STORAGE_TYPE *pStore = STORAGE_TYPE::CreateResource( createParams );
|
||||
AUTO_LOCK_( CDataManagerBase, *this );
|
||||
unsigned short memoryIndex = BaseClass::CreateHandle( bCreateLocked );
|
||||
return BaseClass::StoreResourceInHandle( memoryIndex, pStore, pStore->Size() );
|
||||
}
|
||||
|
||||
@@ -251,7 +270,7 @@ private:
|
||||
|
||||
inline unsigned short CDataManagerBase::FromHandle( memhandle_t handle )
|
||||
{
|
||||
unsigned int fullWord = (unsigned int)handle;
|
||||
unsigned int fullWord = (unsigned int)reinterpret_cast<uintp>( handle );
|
||||
unsigned short serial = fullWord>>16;
|
||||
unsigned short index = fullWord & 0xFFFF;
|
||||
index--;
|
||||
|
||||
+163
-66
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -30,27 +30,19 @@
|
||||
|
||||
typedef void (*MemoryPoolReportFunc_t)( PRINTF_FORMAT_STRING char const* pMsg, ... );
|
||||
|
||||
// Ways a memory pool can grow when it needs to make a new blob:
|
||||
enum MemoryPoolGrowType_t
|
||||
{
|
||||
UTLMEMORYPOOL_GROW_NONE=0, // Don't allow new blobs.
|
||||
UTLMEMORYPOOL_GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates
|
||||
// get larger and larger each time it allocates one).
|
||||
UTLMEMORYPOOL_GROW_SLOW=2 // New blob size is numElements.
|
||||
};
|
||||
|
||||
class CUtlMemoryPool
|
||||
{
|
||||
public:
|
||||
// !KLUDGE! For legacy code support, import the global enum into this scope
|
||||
// Ways the memory pool can grow when it needs to make a new blob.
|
||||
enum MemoryPoolGrowType_t
|
||||
{
|
||||
GROW_NONE=UTLMEMORYPOOL_GROW_NONE,
|
||||
GROW_FAST=UTLMEMORYPOOL_GROW_FAST,
|
||||
GROW_SLOW=UTLMEMORYPOOL_GROW_SLOW
|
||||
GROW_NONE=0, // Don't allow new blobs.
|
||||
GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates
|
||||
// get larger and larger each time it allocates one).
|
||||
GROW_SLOW=2 // New blob size is numElements.
|
||||
};
|
||||
|
||||
CUtlMemoryPool( int blockSize, int numElements, int growMode = UTLMEMORYPOOL_GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 );
|
||||
CUtlMemoryPool( int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 );
|
||||
~CUtlMemoryPool();
|
||||
|
||||
void* Alloc(); // Allocate the element size you specified in the constructor.
|
||||
@@ -66,8 +58,12 @@ public:
|
||||
static void SetErrorReportFunc( MemoryPoolReportFunc_t func );
|
||||
|
||||
// returns number of allocated blocks
|
||||
int Count() { return m_BlocksAllocated; }
|
||||
int PeakCount() { return m_PeakAlloc; }
|
||||
int Count() const { return m_BlocksAllocated; }
|
||||
int PeakCount() const { return m_PeakAlloc; }
|
||||
int BlockSize() const { return m_BlockSize; }
|
||||
int Size() const;
|
||||
|
||||
bool IsAllocationWithinPool( void *pMem ) const;
|
||||
|
||||
protected:
|
||||
class CBlob
|
||||
@@ -89,14 +85,13 @@ protected:
|
||||
|
||||
int m_GrowMode; // GROW_ enum.
|
||||
|
||||
// Put m_BlocksAllocated in front of m_pHeadOfFreeList for better
|
||||
// packing on 64-bit where pointers are 8-byte aligned.
|
||||
int m_BlocksAllocated;
|
||||
// FIXME: Change m_ppMemBlob into a growable array?
|
||||
void *m_pHeadOfFreeList;
|
||||
int m_PeakAlloc;
|
||||
unsigned short m_nAlignment;
|
||||
unsigned short m_NumBlobs;
|
||||
// Group up pointers at the end of the class to avoid padding bloat
|
||||
// FIXME: Change m_ppMemBlob into a growable array?
|
||||
void *m_pHeadOfFreeList;
|
||||
const char * m_pszAllocOwner;
|
||||
// CBlob could be not a multiple of 4 bytes so stuff it at the end here to keep us otherwise aligned
|
||||
CBlob m_BlobHead;
|
||||
@@ -106,12 +101,12 @@ protected:
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Multi-thread/Thread Safe Memory Class
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMemoryPoolMT : public CUtlMemoryPool
|
||||
{
|
||||
public:
|
||||
CMemoryPoolMT(int blockSize, int numElements, int growMode = UTLMEMORYPOOL_GROW_FAST, const char *pszAllocOwner = NULL) : CUtlMemoryPool( blockSize, numElements, growMode, pszAllocOwner) {}
|
||||
CMemoryPoolMT( int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0) : CUtlMemoryPool( blockSize, numElements, growMode, pszAllocOwner, nAlignment ) {}
|
||||
|
||||
|
||||
void* Alloc() { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::Alloc(); }
|
||||
@@ -136,13 +131,7 @@ class CClassMemoryPool : public CUtlMemoryPool
|
||||
{
|
||||
public:
|
||||
CClassMemoryPool(int numElements, int growMode = GROW_FAST, int nAlignment = 0 ) :
|
||||
CUtlMemoryPool( sizeof(T), numElements, growMode, MEM_ALLOC_CLASSNAME(T), nAlignment ) {
|
||||
#ifdef PLATFORM_64BITS
|
||||
COMPILE_TIME_ASSERT( sizeof(CUtlMemoryPool) == 64 );
|
||||
#else
|
||||
COMPILE_TIME_ASSERT( sizeof(CUtlMemoryPool) == 48 );
|
||||
#endif
|
||||
}
|
||||
CUtlMemoryPool( sizeof(T), numElements, growMode, MEM_ALLOC_CLASSNAME(T), nAlignment ) {}
|
||||
|
||||
T* Alloc();
|
||||
T* AllocZero();
|
||||
@@ -151,16 +140,15 @@ public:
|
||||
void Clear();
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Specialized pool for aligned data management (e.g., Xbox cubemaps)
|
||||
// Specialized pool for aligned data management (e.g., Xbox textures)
|
||||
//-----------------------------------------------------------------------------
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, int COMPACT_THRESHOLD = 4 >
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE = false, int COMPACT_THRESHOLD = 4 >
|
||||
class CAlignedMemPool
|
||||
{
|
||||
enum
|
||||
{
|
||||
BLOCK_SIZE = ALIGN_VALUE( ITEM_SIZE, ALIGNMENT ) > 8 ? ALIGN_VALUE( ITEM_SIZE, ALIGNMENT ) : 8
|
||||
BLOCK_SIZE = COMPILETIME_MAX( ALIGN_VALUE( ITEM_SIZE, ALIGNMENT ), 8 ),
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -172,13 +160,13 @@ public:
|
||||
static int __cdecl CompareChunk( void * const *ppLeft, void * const *ppRight );
|
||||
void Compact();
|
||||
|
||||
int NumTotal() { return m_Chunks.Count() * ( CHUNK_SIZE / BLOCK_SIZE ); }
|
||||
int NumAllocated() { return NumTotal() - m_nFree; }
|
||||
int NumFree() { return m_nFree; }
|
||||
int NumTotal() { AUTO_LOCK( m_mutex ); return m_Chunks.Count() * ( CHUNK_SIZE / BLOCK_SIZE ); }
|
||||
int NumAllocated() { AUTO_LOCK( m_mutex ); return NumTotal() - m_nFree; }
|
||||
int NumFree() { AUTO_LOCK( m_mutex ); return m_nFree; }
|
||||
|
||||
int BytesTotal() { return NumTotal() * BLOCK_SIZE; }
|
||||
int BytesAllocated() { return NumAllocated() * BLOCK_SIZE; }
|
||||
int BytesFree() { return NumFree() * BLOCK_SIZE; }
|
||||
int BytesTotal() { AUTO_LOCK( m_mutex ); return NumTotal() * BLOCK_SIZE; }
|
||||
int BytesAllocated() { AUTO_LOCK( m_mutex ); return NumAllocated() * BLOCK_SIZE; }
|
||||
int BytesFree() { AUTO_LOCK( m_mutex ); return NumFree() * BLOCK_SIZE; }
|
||||
|
||||
int ItemSize() { return ITEM_SIZE; }
|
||||
int BlockSize() { return BLOCK_SIZE; }
|
||||
@@ -195,7 +183,9 @@ private:
|
||||
FreeBlock_t * m_pFirstFree;
|
||||
int m_nFree;
|
||||
CAllocator m_Allocator;
|
||||
float m_TimeLastCompact;
|
||||
double m_TimeLastCompact;
|
||||
|
||||
CThreadFastMutex m_mutex;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -226,7 +216,7 @@ public:
|
||||
|
||||
void Purge()
|
||||
{
|
||||
T *p;
|
||||
T *p = NULL;
|
||||
while ( m_AvailableObjects.PopItem( &p ) )
|
||||
{
|
||||
delete p;
|
||||
@@ -235,7 +225,7 @@ public:
|
||||
|
||||
T *GetObject( bool bCreateNewIfEmpty = bDefCreateNewIfEmpty )
|
||||
{
|
||||
T *p;
|
||||
T *p = NULL;
|
||||
if ( !m_AvailableObjects.PopItem( &p ) )
|
||||
{
|
||||
p = ( bCreateNewIfEmpty ) ? new T : NULL;
|
||||
@@ -253,6 +243,98 @@ private:
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixed budget pool with overflow to malloc
|
||||
//-----------------------------------------------------------------------------
|
||||
template <size_t PROVIDED_ITEM_SIZE, int ITEM_COUNT>
|
||||
class CFixedBudgetMemoryPool
|
||||
{
|
||||
public:
|
||||
CFixedBudgetMemoryPool()
|
||||
{
|
||||
m_pBase = m_pLimit = 0;
|
||||
COMPILE_TIME_ASSERT( ITEM_SIZE % 4 == 0 );
|
||||
}
|
||||
|
||||
bool Owns( void *p )
|
||||
{
|
||||
return ( p >= m_pBase && p < m_pLimit );
|
||||
}
|
||||
|
||||
void *Alloc()
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
#ifndef USE_MEM_DEBUG
|
||||
if ( !m_pBase )
|
||||
{
|
||||
LOCAL_THREAD_LOCK();
|
||||
if ( !m_pBase )
|
||||
{
|
||||
byte *pMemory = m_pBase = (byte *)malloc( ITEM_COUNT * ITEM_SIZE );
|
||||
m_pLimit = m_pBase + ( ITEM_COUNT * ITEM_SIZE );
|
||||
|
||||
for ( int i = 0; i < ITEM_COUNT; i++ )
|
||||
{
|
||||
m_freeList.Push( (TSLNodeBase_t *)pMemory );
|
||||
pMemory += ITEM_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *p = m_freeList.Pop();
|
||||
if ( p )
|
||||
return p;
|
||||
#endif
|
||||
return malloc( ITEM_SIZE );
|
||||
}
|
||||
|
||||
void Free( void *p )
|
||||
{
|
||||
#ifndef USE_MEM_DEBUG
|
||||
if ( Owns( p ) )
|
||||
m_freeList.Push( (TSLNodeBase_t *)p );
|
||||
else
|
||||
#endif
|
||||
free( p );
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
#ifndef USE_MEM_DEBUG
|
||||
if ( m_pBase )
|
||||
{
|
||||
free( m_pBase );
|
||||
}
|
||||
m_pBase = m_pLimit = 0;
|
||||
Construct( &m_freeList );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsEmpty()
|
||||
{
|
||||
#ifndef USE_MEM_DEBUG
|
||||
if ( m_pBase && m_freeList.Count() != ITEM_COUNT )
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
ITEM_SIZE = ALIGN_VALUE( PROVIDED_ITEM_SIZE, TSLIST_NODE_ALIGNMENT )
|
||||
};
|
||||
|
||||
CTSListBase m_freeList;
|
||||
byte *m_pBase;
|
||||
byte *m_pLimit;
|
||||
};
|
||||
|
||||
#define BIND_TO_FIXED_BUDGET_POOL( poolName ) \
|
||||
inline void* operator new( size_t size ) { return poolName.Alloc(); } \
|
||||
inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { return poolName.Alloc(); } \
|
||||
inline void operator delete( void* p ) { poolName.Free(p); } \
|
||||
inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { poolName.Free(p); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template< class T >
|
||||
@@ -261,7 +343,7 @@ inline T* CClassMemoryPool<T>::Alloc()
|
||||
T *pRet;
|
||||
|
||||
{
|
||||
MEM_ALLOC_CREDIT_(MEM_ALLOC_CLASSNAME(T));
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
pRet = (T*)CUtlMemoryPool::Alloc();
|
||||
}
|
||||
|
||||
@@ -278,7 +360,7 @@ inline T* CClassMemoryPool<T>::AllocZero()
|
||||
T *pRet;
|
||||
|
||||
{
|
||||
MEM_ALLOC_CREDIT_(MEM_ALLOC_CLASSNAME(T));
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
pRet = (T*)CUtlMemoryPool::AllocZero();
|
||||
}
|
||||
|
||||
@@ -303,7 +385,7 @@ inline void CClassMemoryPool<T>::Free(T *pMem)
|
||||
template< class T >
|
||||
inline void CClassMemoryPool<T>::Clear()
|
||||
{
|
||||
CUtlRBTree<void *> freeBlocks;
|
||||
CUtlRBTree<void *, int> freeBlocks;
|
||||
SetDefLessFunc( freeBlocks );
|
||||
|
||||
void *pCurFree = m_pHeadOfFreeList;
|
||||
@@ -315,8 +397,9 @@ inline void CClassMemoryPool<T>::Clear()
|
||||
|
||||
for( CBlob *pCur=m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur=pCur->m_pNext )
|
||||
{
|
||||
T *p = (T *)pCur->m_Data;
|
||||
T *pLimit = (T *)(pCur->m_Data + pCur->m_NumBytes);
|
||||
int nElements = pCur->m_NumBytes / this->m_BlockSize;
|
||||
T *p = ( T * ) AlignValue( pCur->m_Data, this->m_nAlignment );
|
||||
T *pLimit = p + nElements;
|
||||
while ( p < pLimit )
|
||||
{
|
||||
if ( freeBlocks.Find( p ) == freeBlocks.InvalidIndex() )
|
||||
@@ -331,6 +414,9 @@ inline void CClassMemoryPool<T>::Clear()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macros that make it simple to make a class use a fixed-size allocator
|
||||
// Put DECLARE_FIXEDSIZE_ALLOCATOR in the private section of a class,
|
||||
@@ -346,7 +432,7 @@ inline void CClassMemoryPool<T>::Clear()
|
||||
static CUtlMemoryPool s_Allocator
|
||||
|
||||
#define DEFINE_FIXEDSIZE_ALLOCATOR( _class, _initsize, _grow ) \
|
||||
CUtlMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool")
|
||||
CUtlMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool", alignof(_class))
|
||||
|
||||
#define DEFINE_FIXEDSIZE_ALLOCATOR_ALIGNED( _class, _initsize, _grow, _alignment ) \
|
||||
CUtlMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool", _alignment )
|
||||
@@ -361,7 +447,7 @@ inline void CClassMemoryPool<T>::Clear()
|
||||
static CMemoryPoolMT s_Allocator
|
||||
|
||||
#define DEFINE_FIXEDSIZE_ALLOCATOR_MT( _class, _initsize, _grow ) \
|
||||
CMemoryPoolMT _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool")
|
||||
CMemoryPoolMT _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool", alignof(_class))
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macros that make it simple to make a class use a fixed-size allocator
|
||||
@@ -382,21 +468,30 @@ inline void CClassMemoryPool<T>::Clear()
|
||||
CUtlMemoryPool* _class::s_pAllocator = _allocator
|
||||
|
||||
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, int COMPACT_THRESHOLD >
|
||||
inline CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPACT_THRESHOLD>::CAlignedMemPool()
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
|
||||
inline CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::CAlignedMemPool()
|
||||
: m_pFirstFree( 0 ),
|
||||
m_nFree( 0 ),
|
||||
m_TimeLastCompact( 0 )
|
||||
{
|
||||
COMPILE_TIME_ASSERT( sizeof( FreeBlock_t ) >= BLOCK_SIZE );
|
||||
COMPILE_TIME_ASSERT( ALIGN_VALUE( sizeof( FreeBlock_t ), ALIGNMENT ) == sizeof( FreeBlock_t ) );
|
||||
// These COMPILE_TIME_ASSERT checks need to be in individual scopes to avoid build breaks
|
||||
// on MacOS and Linux due to a gcc bug.
|
||||
{ COMPILE_TIME_ASSERT( sizeof( FreeBlock_t ) >= BLOCK_SIZE ); }
|
||||
{ COMPILE_TIME_ASSERT( ALIGN_VALUE( sizeof( FreeBlock_t ), ALIGNMENT ) == sizeof( FreeBlock_t ) ); }
|
||||
}
|
||||
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, int COMPACT_THRESHOLD >
|
||||
inline void *CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPACT_THRESHOLD>::Alloc()
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
|
||||
inline void *CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::Alloc()
|
||||
{
|
||||
AUTO_LOCK( m_mutex );
|
||||
|
||||
if ( !m_pFirstFree )
|
||||
{
|
||||
if ( !GROWMODE && m_Chunks.Count() )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FreeBlock_t *pNew = (FreeBlock_t *)m_Allocator.Alloc( CHUNK_SIZE );
|
||||
Assert( (unsigned)pNew % ALIGNMENT == 0 );
|
||||
m_Chunks.AddToTail( pNew );
|
||||
@@ -417,9 +512,11 @@ inline void *CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPA
|
||||
return p;
|
||||
}
|
||||
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, int COMPACT_THRESHOLD >
|
||||
inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPACT_THRESHOLD>::Free( void *p )
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
|
||||
inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::Free( void *p )
|
||||
{
|
||||
AUTO_LOCK( m_mutex );
|
||||
|
||||
// Insertion sort to encourage allocation clusters in chunks
|
||||
FreeBlock_t *pFree = ((FreeBlock_t *)p);
|
||||
FreeBlock_t *pCur = m_pFirstFree;
|
||||
@@ -445,9 +542,9 @@ inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPAC
|
||||
|
||||
if ( m_nFree >= ( CHUNK_SIZE / BLOCK_SIZE ) * COMPACT_THRESHOLD )
|
||||
{
|
||||
float time = Plat_FloatTime();
|
||||
float compactTime = ( m_nFree >= ( CHUNK_SIZE / BLOCK_SIZE ) * COMPACT_THRESHOLD * 4 ) ? 15.0 : 30.0;
|
||||
if ( m_TimeLastCompact > time || m_TimeLastCompact + compactTime < Plat_FloatTime() )
|
||||
double time = Plat_FloatTime();
|
||||
double compactTime = ( m_nFree >= ( CHUNK_SIZE / BLOCK_SIZE ) * COMPACT_THRESHOLD * 4 ) ? 15.0 : 30.0;
|
||||
if ( m_TimeLastCompact > time || m_TimeLastCompact + compactTime < time )
|
||||
{
|
||||
Compact();
|
||||
m_TimeLastCompact = time;
|
||||
@@ -455,14 +552,14 @@ inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPAC
|
||||
}
|
||||
}
|
||||
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, int COMPACT_THRESHOLD >
|
||||
inline int __cdecl CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPACT_THRESHOLD>::CompareChunk( void * const *ppLeft, void * const *ppRight )
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
|
||||
inline int __cdecl CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::CompareChunk( void * const *ppLeft, void * const *ppRight )
|
||||
{
|
||||
return ((unsigned)*ppLeft) - ((unsigned)*ppRight);
|
||||
return static_cast<int>( (intp)*ppLeft - (intp)*ppRight );
|
||||
}
|
||||
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, int COMPACT_THRESHOLD >
|
||||
inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, COMPACT_THRESHOLD>::Compact()
|
||||
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
|
||||
inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::Compact()
|
||||
{
|
||||
FreeBlock_t *pCur = m_pFirstFree;
|
||||
FreeBlock_t *pPrev = NULL;
|
||||
|
||||
@@ -34,7 +34,7 @@ inline void RangeCheck( const T &value, int minValue, int maxValue )
|
||||
if ( ThreadInMainThread() && g_bDoRangeChecks )
|
||||
{
|
||||
// Ignore the min/max stuff for now.. just make sure it's not a NAN.
|
||||
Assert( _finite( value ) );
|
||||
Assert( IsFinite( value ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -193,8 +193,8 @@ public:
|
||||
class CRefMT
|
||||
{
|
||||
public:
|
||||
static int Increment( int *p) { return ThreadInterlockedIncrement( (long *)p ); }
|
||||
static int Decrement( int *p) { return ThreadInterlockedDecrement( (long *)p ); }
|
||||
static int Increment( int *p) { return ThreadInterlockedIncrement( (int32 *)p ); }
|
||||
static int Decrement( int *p) { return ThreadInterlockedDecrement( (int32 *)p ); }
|
||||
};
|
||||
|
||||
class CRefST
|
||||
|
||||
+431
-11
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -14,21 +14,33 @@
|
||||
|
||||
#include "utlrbtree.h"
|
||||
#include "utlvector.h"
|
||||
#include "utlbuffer.h"
|
||||
#include "generichash.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Allocates memory for strings, checking for duplicates first,
|
||||
// reusing exising strings if duplicate found.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum StringPoolCase_t
|
||||
{
|
||||
StringPoolCaseInsensitive,
|
||||
StringPoolCaseSensitive
|
||||
};
|
||||
|
||||
class CStringPool
|
||||
{
|
||||
public:
|
||||
CStringPool();
|
||||
CStringPool( StringPoolCase_t caseSensitivity = StringPoolCaseInsensitive );
|
||||
~CStringPool();
|
||||
|
||||
unsigned int Count() const;
|
||||
|
||||
const char * Allocate( const char *pszValue );
|
||||
// This feature is deliberately not supported because it's pretty dangerous
|
||||
// given current uses of CStringPool, which assume they can copy string pointers without
|
||||
// any refcounts.
|
||||
//void Free( const char *pszValue );
|
||||
void FreeAll();
|
||||
|
||||
// searches for a string already in the pool
|
||||
@@ -48,14 +60,15 @@ protected:
|
||||
//
|
||||
// At some point this should replace CStringPool
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCountedStringPool
|
||||
template<class T>
|
||||
class CCountedStringPoolBase
|
||||
{
|
||||
public: // HACK, hash_item_t structure should not be public.
|
||||
|
||||
struct hash_item_t
|
||||
{
|
||||
char* pString;
|
||||
unsigned short nNextElement;
|
||||
T nNextElement;
|
||||
unsigned char nReferenceCount;
|
||||
unsigned char pad;
|
||||
};
|
||||
@@ -67,13 +80,14 @@ public: // HACK, hash_item_t structure should not be public.
|
||||
HASH_TABLE_SIZE = 1024
|
||||
};
|
||||
|
||||
CUtlVector<unsigned short> m_HashTable; // Points to each element
|
||||
CUtlVector<T> m_HashTable; // Points to each element
|
||||
CUtlVector<hash_item_t> m_Elements;
|
||||
unsigned short m_FreeListStart;
|
||||
T m_FreeListStart;
|
||||
StringPoolCase_t m_caseSensitivity;
|
||||
|
||||
public:
|
||||
CCountedStringPool();
|
||||
virtual ~CCountedStringPool();
|
||||
CCountedStringPoolBase( StringPoolCase_t caseSensitivity = StringPoolCaseInsensitive );
|
||||
virtual ~CCountedStringPoolBase();
|
||||
|
||||
void FreeAll();
|
||||
|
||||
@@ -82,10 +96,416 @@ public:
|
||||
void DereferenceString( const char* pIntrinsic );
|
||||
|
||||
// These are only reliable if there are less than 64k strings in your string pool
|
||||
unsigned short FindStringHandle( const char* pIntrinsic );
|
||||
unsigned short ReferenceStringHandle( const char* pIntrinsic );
|
||||
char *HandleToString( unsigned short handle );
|
||||
T FindStringHandle( const char* pIntrinsic );
|
||||
T ReferenceStringHandle( const char* pIntrinsic );
|
||||
char *HandleToString( T handle );
|
||||
void SpewStrings();
|
||||
unsigned Hash( const char *pszKey );
|
||||
|
||||
bool SaveToBuffer( CUtlBuffer &buffer );
|
||||
bool RestoreFromBuffer( CUtlBuffer &buffer );
|
||||
|
||||
// Debug helper method to validate that we didn't overflow
|
||||
void VerifyNotOverflowed( unsigned int value );
|
||||
};
|
||||
|
||||
typedef CCountedStringPoolBase<unsigned short> CCountedStringPool;
|
||||
|
||||
template<class T>
|
||||
inline CCountedStringPoolBase<T>::CCountedStringPoolBase( StringPoolCase_t caseSensitivity )
|
||||
{
|
||||
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;
|
||||
|
||||
m_caseSensitivity = caseSensitivity;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline CCountedStringPoolBase<T>::~CCountedStringPoolBase()
|
||||
{
|
||||
FreeAll();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void CCountedStringPoolBase<T>::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.RemoveAll();
|
||||
m_Elements.AddToTail();
|
||||
m_Elements[0].pString = NULL;
|
||||
m_Elements[0].nReferenceCount = 0;
|
||||
m_Elements[0].nNextElement = INVALID_ELEMENT;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline unsigned CCountedStringPoolBase<T>::Hash( const char *pszKey )
|
||||
{
|
||||
if ( m_caseSensitivity == StringPoolCaseInsensitive )
|
||||
{
|
||||
return HashStringCaseless( pszKey );
|
||||
}
|
||||
return HashString( pszKey );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T CCountedStringPoolBase<T>::FindStringHandle( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return INVALID_ELEMENT;
|
||||
|
||||
T nHashBucketIndex = ( Hash( pIntrinsic ) %HASH_TABLE_SIZE);
|
||||
T 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;
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline char* CCountedStringPoolBase<T>::FindString( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return NULL;
|
||||
|
||||
// Yes, this will be NULL on failure.
|
||||
return m_Elements[FindStringHandle(pIntrinsic)].pString;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T CCountedStringPoolBase<T>::ReferenceStringHandle( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return INVALID_ELEMENT;
|
||||
|
||||
T nHashBucketIndex = ( Hash( pIntrinsic ) % HASH_TABLE_SIZE);
|
||||
T 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
|
||||
{
|
||||
unsigned int newElement = m_Elements.AddToTail();
|
||||
VerifyNotOverflowed( newElement );
|
||||
nCurrentBucket = newElement;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void CCountedStringPoolBase<unsigned short>::VerifyNotOverflowed( unsigned int value ) { Assert( value < 0xffff ); }
|
||||
|
||||
template<>
|
||||
inline void CCountedStringPoolBase<unsigned int>::VerifyNotOverflowed( unsigned int value ) {}
|
||||
|
||||
template<class T>
|
||||
inline char* CCountedStringPoolBase<T>::ReferenceString( const char* pIntrinsic )
|
||||
{
|
||||
if(!pIntrinsic)
|
||||
return NULL;
|
||||
|
||||
return m_Elements[ReferenceStringHandle( pIntrinsic)].pString;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void CCountedStringPoolBase<T>::DereferenceString( const char* pIntrinsic )
|
||||
{
|
||||
// If we get a NULL pointer, just return
|
||||
if (!pIntrinsic)
|
||||
return;
|
||||
|
||||
T nHashBucketIndex = (Hash( pIntrinsic ) % m_HashTable.Count());
|
||||
T nCurrentBucket = m_HashTable[ nHashBucketIndex ];
|
||||
|
||||
// If there isn't anything in the bucket, just return.
|
||||
if ( nCurrentBucket == INVALID_ELEMENT )
|
||||
return;
|
||||
|
||||
for( T 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;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline char* CCountedStringPoolBase<T>::HandleToString( T handle )
|
||||
{
|
||||
return m_Elements[handle].pString;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void CCountedStringPoolBase<T>::SpewStrings()
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < m_Elements.Count(); i++ )
|
||||
{
|
||||
char* string = m_Elements[i].pString;
|
||||
|
||||
Msg("String %d: ref:%d %s\n", i, m_Elements[i].nReferenceCount, string == NULL? "EMPTY - ok for slot zero only!" : string);
|
||||
}
|
||||
|
||||
Msg("\n%d total counted strings.", m_Elements.Count());
|
||||
}
|
||||
|
||||
#define STRING_POOL_VERSION MAKEID( 'C', 'S', 'P', '1' )
|
||||
#define MAX_STRING_SAVE 1024
|
||||
|
||||
template<>
|
||||
inline bool CCountedStringPoolBase<unsigned short>::SaveToBuffer( CUtlBuffer &buffer )
|
||||
{
|
||||
if ( m_Elements.Count() <= 1 )
|
||||
{
|
||||
// pool is empty, saving nothing
|
||||
// caller can check put position of buffer to detect
|
||||
return true;
|
||||
}
|
||||
|
||||
// signature/version
|
||||
buffer.PutInt( STRING_POOL_VERSION );
|
||||
|
||||
buffer.PutUnsignedShort( m_FreeListStart );
|
||||
|
||||
buffer.PutInt( m_HashTable.Count() );
|
||||
for ( int i = 0; i < m_HashTable.Count(); i++ )
|
||||
{
|
||||
buffer.PutUnsignedShort( m_HashTable[i] );
|
||||
}
|
||||
|
||||
buffer.PutInt( m_Elements.Count() );
|
||||
for ( int i = 1; i < m_Elements.Count(); i++ )
|
||||
{
|
||||
buffer.PutUnsignedShort( m_Elements[i].nNextElement );
|
||||
buffer.PutUnsignedChar( m_Elements[i].nReferenceCount );
|
||||
|
||||
const char *pString = m_Elements[i].pString;
|
||||
if ( strlen( pString ) >= MAX_STRING_SAVE )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
buffer.PutString( pString ? pString : "" );
|
||||
}
|
||||
|
||||
return buffer.IsValid();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool CCountedStringPoolBase<unsigned short>::RestoreFromBuffer( CUtlBuffer &buffer )
|
||||
{
|
||||
int signature = buffer.GetInt();
|
||||
if ( signature != STRING_POOL_VERSION )
|
||||
{
|
||||
// wrong version
|
||||
return false;
|
||||
}
|
||||
|
||||
FreeAll();
|
||||
|
||||
m_FreeListStart = buffer.GetUnsignedShort();
|
||||
|
||||
int hashCount = buffer.GetInt();
|
||||
m_HashTable.SetCount( hashCount );
|
||||
|
||||
for ( int i = 0; i < hashCount; i++ )
|
||||
{
|
||||
m_HashTable[i] = buffer.GetUnsignedShort();
|
||||
}
|
||||
|
||||
int tableCount = buffer.GetInt();
|
||||
if ( tableCount > 1 )
|
||||
{
|
||||
m_Elements.AddMultipleToTail( tableCount-1 );
|
||||
}
|
||||
|
||||
char tempString[MAX_STRING_SAVE];
|
||||
for ( int i = 1; i < tableCount; i++ )
|
||||
{
|
||||
m_Elements[i].nNextElement = buffer.GetUnsignedShort();
|
||||
m_Elements[i].nReferenceCount = buffer.GetUnsignedChar();
|
||||
buffer.GetString( tempString, sizeof( tempString ) );
|
||||
m_Elements[i].pString = strdup( tempString );
|
||||
}
|
||||
|
||||
return buffer.IsValid();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool CCountedStringPoolBase<unsigned int>::SaveToBuffer( CUtlBuffer &buffer )
|
||||
{
|
||||
if ( m_Elements.Count() <= 1 )
|
||||
{
|
||||
// pool is empty, saving nothing
|
||||
// caller can check put position of buffer to detect
|
||||
return true;
|
||||
}
|
||||
|
||||
// signature/version
|
||||
buffer.PutInt( STRING_POOL_VERSION );
|
||||
|
||||
buffer.PutUnsignedInt( m_FreeListStart );
|
||||
|
||||
buffer.PutInt( m_HashTable.Count() );
|
||||
for ( int i = 0; i < m_HashTable.Count(); i++ )
|
||||
{
|
||||
buffer.PutUnsignedInt( m_HashTable[i] );
|
||||
}
|
||||
|
||||
buffer.PutInt( m_Elements.Count() );
|
||||
for ( int i = 1; i < m_Elements.Count(); i++ )
|
||||
{
|
||||
buffer.PutUnsignedInt( m_Elements[i].nNextElement );
|
||||
buffer.PutUnsignedChar( m_Elements[i].nReferenceCount );
|
||||
|
||||
const char *pString = m_Elements[i].pString;
|
||||
if ( strlen( pString ) >= MAX_STRING_SAVE )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
buffer.PutString( pString ? pString : "" );
|
||||
}
|
||||
|
||||
return buffer.IsValid();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool CCountedStringPoolBase<unsigned int>::RestoreFromBuffer( CUtlBuffer &buffer )
|
||||
{
|
||||
int signature = buffer.GetInt();
|
||||
if ( signature != STRING_POOL_VERSION )
|
||||
{
|
||||
// wrong version
|
||||
return false;
|
||||
}
|
||||
|
||||
FreeAll();
|
||||
|
||||
m_FreeListStart = buffer.GetUnsignedInt();
|
||||
|
||||
int hashCount = buffer.GetInt();
|
||||
m_HashTable.SetCount( hashCount );
|
||||
|
||||
for ( int i = 0; i < hashCount; i++ )
|
||||
{
|
||||
m_HashTable[i] = buffer.GetUnsignedInt();
|
||||
}
|
||||
|
||||
int tableCount = buffer.GetInt();
|
||||
if ( tableCount > 1 )
|
||||
{
|
||||
m_Elements.AddMultipleToTail( tableCount-1 );
|
||||
}
|
||||
|
||||
char tempString[MAX_STRING_SAVE];
|
||||
for ( int i = 1; i < tableCount; i++ )
|
||||
{
|
||||
m_Elements[i].nNextElement = buffer.GetUnsignedInt();
|
||||
m_Elements[i].nReferenceCount = buffer.GetUnsignedChar();
|
||||
buffer.GetString( tempString, sizeof( tempString ) );
|
||||
m_Elements[i].pString = strdup( tempString );
|
||||
}
|
||||
|
||||
return buffer.IsValid();
|
||||
}
|
||||
#endif // STRINGPOOL_H
|
||||
|
||||
@@ -30,8 +30,7 @@ class IProcessUtils;
|
||||
// allowing link libraries to access tier1 library interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// These are marked DLL_EXPORT for Linux.
|
||||
DLL_EXPORT ICvar *cvar;
|
||||
extern ICvar *cvar;
|
||||
extern ICvar *g_pCVar;
|
||||
extern IProcessUtils *g_pProcessUtils;
|
||||
|
||||
|
||||
+462
-83
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -14,6 +14,8 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "unitlib/unitlib.h" // just here for tests - remove before checking in!!!
|
||||
|
||||
#include "tier1/utlmemory.h"
|
||||
#include "tier1/byteswap.h"
|
||||
#include <stdarg.h>
|
||||
@@ -102,11 +104,48 @@ CUtlCharConversion *GetNoEscCharConversion();
|
||||
SetOverflowFuncs( static_cast <UtlBufferOverflowFunc_t>( _get ), static_cast <UtlBufferOverflowFunc_t>( _put ) )
|
||||
|
||||
|
||||
|
||||
typedef unsigned short ushort;
|
||||
|
||||
template < class A >
|
||||
static const char *GetFmtStr( int nRadix = 10, bool bPrint = true ) { Assert( 0 ); return ""; }
|
||||
#if defined( LINUX ) || defined( __clang__ ) || ( defined( _MSC_VER ) && _MSC_VER >= 1900 )
|
||||
template <> const char *GetFmtStr< short > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hd"; }
|
||||
template <> const char *GetFmtStr< ushort > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hu"; }
|
||||
template <> const char *GetFmtStr< int > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%d"; }
|
||||
template <> const char *GetFmtStr< uint > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 || nRadix == 16 ); return nRadix == 16 ? "%x" : "%u"; }
|
||||
template <> const char *GetFmtStr< int64 > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%lld"; }
|
||||
template <> const char *GetFmtStr< float > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%f"; }
|
||||
template <> const char *GetFmtStr< double > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return bPrint ? "%.15lf" : "%lf"; } // force Printf to print DBL_DIG=15 digits of precision for doubles - defaults to FLT_DIG=6
|
||||
#else
|
||||
template <> static const char *GetFmtStr< short > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hd"; }
|
||||
template <> static const char *GetFmtStr< ushort > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hu"; }
|
||||
template <> static const char *GetFmtStr< int > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%d"; }
|
||||
template <> static const char *GetFmtStr< uint > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 || nRadix == 16 ); return nRadix == 16 ? "%x" : "%u"; }
|
||||
template <> static const char *GetFmtStr< int64 > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%lld"; }
|
||||
template <> static const char *GetFmtStr< float > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%f"; }
|
||||
template <> static const char *GetFmtStr< double > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return bPrint ? "%.15lf" : "%lf"; } // force Printf to print DBL_DIG=15 digits of precision for doubles - defaults to FLT_DIG=6
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command parsing..
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlBuffer
|
||||
{
|
||||
// Brian has on his todo list to revisit this as there are issues in some cases with CUtlVector using operator = instead of copy construtor in InsertMultiple, etc.
|
||||
// The unsafe case is something like this:
|
||||
// CUtlVector< CUtlBuffer > vecFoo;
|
||||
//
|
||||
// CUtlBuffer buf;
|
||||
// buf.Put( xxx );
|
||||
// vecFoo.Insert( buf );
|
||||
//
|
||||
// This will cause memory corruption when vecFoo is cleared
|
||||
//
|
||||
//private:
|
||||
// // Disallow copying
|
||||
// CUtlBuffer( const CUtlBuffer & );// { Assert( 0 ); }
|
||||
// CUtlBuffer &operator=( const CUtlBuffer & );// { Assert( 0 ); return *this; }
|
||||
|
||||
public:
|
||||
enum SeekType_t
|
||||
{
|
||||
@@ -132,7 +171,19 @@ public:
|
||||
CUtlBuffer( int growSize = 0, int initSize = 0, int nFlags = 0 );
|
||||
CUtlBuffer( const void* pBuffer, int size, int nFlags = 0 );
|
||||
// This one isn't actually defined so that we catch contructors that are trying to pass a bool in as the third param.
|
||||
CUtlBuffer( const void *pBuffer, int size, bool crap );
|
||||
CUtlBuffer( const void *pBuffer, int size, bool crap ) = delete;
|
||||
|
||||
// UtlBuffer objects should not be copyable; we do a slow copy if you use this but it asserts.
|
||||
// (REI: I'd like to delete these but we have some python bindings that currently rely on being able to copy these objects)
|
||||
CUtlBuffer( const CUtlBuffer& ); // = delete;
|
||||
CUtlBuffer& operator= ( const CUtlBuffer& ); // = delete;
|
||||
|
||||
#if VALVE_CPP11
|
||||
// UtlBuffer is non-copyable (same as CUtlMemory), but it is moveable. We would like to declare these with '= default'
|
||||
// but unfortunately VS2013 isn't fully C++11 compliant, so we have to manually declare these in the boilerplate way.
|
||||
CUtlBuffer( CUtlBuffer&& moveFrom ); // = default;
|
||||
CUtlBuffer& operator= ( CUtlBuffer&& moveFrom ); // = default;
|
||||
#endif
|
||||
|
||||
unsigned char GetFlags() const;
|
||||
|
||||
@@ -143,11 +194,15 @@ public:
|
||||
// Makes sure we've got at least this much memory
|
||||
void EnsureCapacity( int num );
|
||||
|
||||
// Access for direct read into buffer
|
||||
void * AccessForDirectRead( int nBytes );
|
||||
|
||||
// Attaches the buffer to external memory....
|
||||
void SetExternalBuffer( void* pMemory, int nSize, int nInitialPut, int nFlags = 0 );
|
||||
bool IsExternallyAllocated() const;
|
||||
// Takes ownership of the passed memory, including freeing it when this buffer is destroyed.
|
||||
void AssumeMemory( void *pMemory, int nSize, int nInitialPut, int nFlags = 0 );
|
||||
void *Detach();
|
||||
void* DetachMemory();
|
||||
|
||||
// copies data from another buffer
|
||||
void CopyBuffer( const CUtlBuffer &buffer );
|
||||
@@ -156,9 +211,10 @@ public:
|
||||
void Swap( CUtlBuffer &buf );
|
||||
void Swap( CUtlMemory<uint8> &mem );
|
||||
|
||||
|
||||
FORCEINLINE void ActivateByteSwappingIfBigEndian( void )
|
||||
{
|
||||
if ( IsX360() )
|
||||
if ( ( IsX360() || IsPS3() ) )
|
||||
ActivateByteSwapping( true );
|
||||
}
|
||||
|
||||
@@ -174,6 +230,9 @@ public:
|
||||
// Clears out the buffer; frees memory
|
||||
void Purge();
|
||||
|
||||
// Dump the buffer to stdout
|
||||
void Spew( );
|
||||
|
||||
// Read stuff out.
|
||||
// Binary mode: it'll just read the bits directly in, and characters will be
|
||||
// read for strings until a null character is reached.
|
||||
@@ -185,22 +244,25 @@ public:
|
||||
unsigned short GetUnsignedShort( );
|
||||
int GetInt( );
|
||||
int64 GetInt64( );
|
||||
int GetIntHex( );
|
||||
unsigned int GetIntHex( );
|
||||
unsigned int GetUnsignedInt( );
|
||||
uint64 GetUnsignedInt64( );
|
||||
float GetFloat( );
|
||||
double GetDouble( );
|
||||
template <size_t maxLenInChars> void GetString( char( &pString )[maxLenInChars] )
|
||||
{
|
||||
GetStringInternal( pString, maxLenInChars );
|
||||
}
|
||||
void * GetPtr();
|
||||
void GetString( char* pString, int nMaxChars );
|
||||
bool Get( void* pMem, int size );
|
||||
void GetLine( char* pLine, int nMaxChars );
|
||||
|
||||
void GetStringManualCharCount( char *pString, size_t maxLenInChars )
|
||||
{
|
||||
GetStringInternal( pString, maxLenInChars );
|
||||
GetString( pString, maxLenInChars );
|
||||
}
|
||||
|
||||
void Get( void* pMem, int size );
|
||||
void GetLine( char* pLine, int nMaxChars = 0 );
|
||||
template <size_t maxLenInChars> void GetString( char( &pString )[maxLenInChars] )
|
||||
{
|
||||
GetString( pString, maxLenInChars );
|
||||
}
|
||||
|
||||
// Used for getting objects that have a byteswap datadesc defined
|
||||
template <typename T> void GetObjects( T *dest, int count = 1 );
|
||||
@@ -232,7 +294,7 @@ public:
|
||||
|
||||
// Just like scanf, but doesn't work in binary mode
|
||||
int Scanf( SCANF_FORMAT_STRING const char* pFmt, ... );
|
||||
int VaScanf( const char* pFmt, va_list list );
|
||||
int VaScanf( const char* pFmt, va_list list );
|
||||
|
||||
// Eats white space, advances Get index
|
||||
void EatWhiteSpace();
|
||||
@@ -264,15 +326,16 @@ public:
|
||||
// PutString will not write a terminating character
|
||||
void PutChar( char c );
|
||||
void PutUnsignedChar( unsigned char uc );
|
||||
void PutUint64( uint64 ub );
|
||||
void PutInt16( int16 s16 );
|
||||
void PutShort( short s );
|
||||
void PutUnsignedShort( unsigned short us );
|
||||
void PutInt( int i );
|
||||
void PutInt64( int64 i );
|
||||
void PutUnsignedInt( unsigned int u );
|
||||
void PutUnsignedInt64( uint64 u );
|
||||
void PutUint64( uint64 u );
|
||||
void PutFloat( float f );
|
||||
void PutDouble( double d );
|
||||
void PutPtr( void * ); // Writes the pointer, not the pointed to
|
||||
void PutString( const char* pString );
|
||||
void Put( const void* pMem, int size );
|
||||
|
||||
@@ -311,8 +374,8 @@ public:
|
||||
// Buffer base
|
||||
const void* Base() const;
|
||||
void* Base();
|
||||
// Returns the base as a const char*, only valid in text mode.
|
||||
const char *String() const;
|
||||
|
||||
const void* String() const;
|
||||
|
||||
// memory allocation size, does *not* reflect size written or read,
|
||||
// use TellPut or TellGet for that
|
||||
@@ -345,6 +408,12 @@ public:
|
||||
// Temporarily disables pretty print
|
||||
void EnableTabs( bool bEnable );
|
||||
|
||||
#if !defined( _GAMECONSOLE )
|
||||
// Swap my internal memory with another buffer,
|
||||
// and copy all of its other members
|
||||
void SwapCopy( CUtlBuffer &other ) ;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// error flags
|
||||
enum
|
||||
@@ -364,7 +433,10 @@ protected:
|
||||
bool CheckPut( int size );
|
||||
bool CheckGet( int size );
|
||||
|
||||
// NOTE: Pass in nPut here even though it is just a copy of m_Put. This is almost always called immediately
|
||||
// after modifying m_Put and this lets it stay in a register
|
||||
void AddNullTermination( );
|
||||
void AddNullTermination( int nPut );
|
||||
|
||||
// Methods to help with pretty-printing
|
||||
bool WasLastCharacterCR();
|
||||
@@ -393,16 +465,18 @@ protected:
|
||||
// Call this to peek arbitrarily long into memory. It doesn't fail unless
|
||||
// it can't read *anything* new
|
||||
bool CheckArbitraryPeekGet( int nOffset, int &nIncrement );
|
||||
void GetStringInternal( char *pString, size_t maxLenInChars );
|
||||
|
||||
template <typename T> void GetType( T& dest, const char *pszFmt );
|
||||
template <typename T> void GetType( T& dest );
|
||||
template <typename T> void GetTypeBin( T& dest );
|
||||
template <typename T> bool GetTypeText( T &value, int nRadix = 10 );
|
||||
template <typename T> void GetObject( T *src );
|
||||
|
||||
template <typename T> void PutType( T src, const char *pszFmt );
|
||||
template <typename T> void PutType( T src );
|
||||
template <typename T> void PutTypeBin( T src );
|
||||
template <typename T> void PutObject( T *src );
|
||||
|
||||
// be sure to also update the copy constructor
|
||||
// and SwapCopy() when adding members.
|
||||
CUtlMemory<unsigned char> m_Memory;
|
||||
int m_Get;
|
||||
int m_Put;
|
||||
@@ -410,7 +484,7 @@ protected:
|
||||
unsigned char m_Error;
|
||||
unsigned char m_Flags;
|
||||
unsigned char m_Reserved;
|
||||
#if defined( _X360 )
|
||||
#if defined( _GAMECONSOLE )
|
||||
unsigned char pad;
|
||||
#endif
|
||||
|
||||
@@ -598,7 +672,7 @@ inline void CUtlBuffer::GetObject( T *dest )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy( dest, PeekGet(), sizeof( T ) );
|
||||
memcpy( dest, PeekGet(), sizeof( T ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -608,7 +682,7 @@ inline void CUtlBuffer::GetObject( T *dest )
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_memset( dest, 0, sizeof(T) );
|
||||
Q_memset( &dest, 0, sizeof(T) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,18 +704,19 @@ inline void CUtlBuffer::GetTypeBin( T &dest )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy(&dest, PeekGet(), sizeof(T) );
|
||||
memcpy(&dest, PeekGet(), sizeof(T) );
|
||||
dest = *(T *)PeekGet();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<T>( &dest, (T*)PeekGet() );
|
||||
}
|
||||
m_Get += sizeof(T);
|
||||
}
|
||||
m_Get += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -649,8 +724,8 @@ inline void CUtlBuffer::GetTypeBin< float >( float &dest )
|
||||
{
|
||||
if ( CheckGet( sizeof( float ) ) )
|
||||
{
|
||||
uintptr_t pData = (uintptr_t)PeekGet();
|
||||
if ( IsX360() && ( pData & 0x03 ) )
|
||||
uintp pData = (uintp)PeekGet();
|
||||
if ( ( IsX360() || IsPS3() ) && ( pData & 0x03 ) )
|
||||
{
|
||||
// handle unaligned read
|
||||
((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0];
|
||||
@@ -661,22 +736,148 @@ inline void CUtlBuffer::GetTypeBin< float >( float &dest )
|
||||
else
|
||||
{
|
||||
// aligned read
|
||||
Q_memcpy( &dest, (void*)pData, sizeof(float) );
|
||||
dest = *(float *)pData;
|
||||
}
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian< float >( &dest, &dest );
|
||||
}
|
||||
m_Get += sizeof( float );
|
||||
}
|
||||
m_Get += sizeof( float );
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void CUtlBuffer::GetTypeBin< double >( double &dest )
|
||||
{
|
||||
if ( CheckGet( sizeof( double ) ) )
|
||||
{
|
||||
uintp pData = (uintp)PeekGet();
|
||||
if ( ( IsX360() || IsPS3() ) && ( pData & 0x07 ) )
|
||||
{
|
||||
// handle unaligned read
|
||||
((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0];
|
||||
((unsigned char*)&dest)[1] = ((unsigned char*)pData)[1];
|
||||
((unsigned char*)&dest)[2] = ((unsigned char*)pData)[2];
|
||||
((unsigned char*)&dest)[3] = ((unsigned char*)pData)[3];
|
||||
((unsigned char*)&dest)[4] = ((unsigned char*)pData)[4];
|
||||
((unsigned char*)&dest)[5] = ((unsigned char*)pData)[5];
|
||||
((unsigned char*)&dest)[6] = ((unsigned char*)pData)[6];
|
||||
((unsigned char*)&dest)[7] = ((unsigned char*)pData)[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
// aligned read
|
||||
dest = *(double *)pData;
|
||||
}
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian< double >( &dest, &dest );
|
||||
}
|
||||
m_Get += sizeof( double );
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template < class T >
|
||||
inline T StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
Assert( 0 );
|
||||
*ppEnd = pString;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int8 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( int8 )strtol( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint8 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( uint8 )strtoul( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int16 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( int16 )strtol( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint16 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( uint16 )strtoul( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int32 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( int32 )strtol( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint32 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
return ( uint32 )strtoul( pString, ppEnd, nRadix );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64 StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
#if defined(_PS3) || defined(POSIX)
|
||||
return ( int64 )strtoll( pString, ppEnd, nRadix );
|
||||
#else // !_PS3
|
||||
return ( int64 )_strtoi64( pString, ppEnd, nRadix );
|
||||
#endif // _PS3
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
NOTE_UNUSED( nRadix );
|
||||
return ( float )strtod( pString, ppEnd );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double StringToNumber( char *pString, char **ppEnd, int nRadix )
|
||||
{
|
||||
NOTE_UNUSED( nRadix );
|
||||
return ( double )strtod( pString, ppEnd );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool CUtlBuffer::GetTypeText( T &value, int nRadix /*= 10*/ )
|
||||
{
|
||||
// NOTE: This is not bullet-proof; it assumes numbers are < 128 characters
|
||||
int nLength = 128;
|
||||
if ( !CheckArbitraryPeekGet( 0, nLength ) )
|
||||
{
|
||||
value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
char *pStart = (char*)PeekGet();
|
||||
char* pEnd = pStart;
|
||||
value = StringToNumber< T >( pStart, &pEnd, nRadix );
|
||||
|
||||
int nBytesRead = (int)( pEnd - pStart );
|
||||
if ( nBytesRead == 0 )
|
||||
return false;
|
||||
|
||||
m_Get += nBytesRead;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void CUtlBuffer::GetType( T &dest, const char *pszFmt )
|
||||
inline void CUtlBuffer::GetType( T &dest )
|
||||
{
|
||||
if (!IsText())
|
||||
{
|
||||
@@ -684,81 +885,115 @@ inline void CUtlBuffer::GetType( T &dest, const char *pszFmt )
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = 0;
|
||||
Scanf( pszFmt, &dest );
|
||||
GetTypeText( dest );
|
||||
}
|
||||
}
|
||||
|
||||
inline char CUtlBuffer::GetChar( )
|
||||
{
|
||||
// LEGACY WARNING: this behaves differently than GetUnsignedChar()
|
||||
char c;
|
||||
GetType( c, "%c" );
|
||||
GetTypeBin( c ); // always reads as binary
|
||||
return c;
|
||||
}
|
||||
|
||||
inline unsigned char CUtlBuffer::GetUnsignedChar( )
|
||||
{
|
||||
// LEGACY WARNING: this behaves differently than GetChar()
|
||||
unsigned char c;
|
||||
GetType( c, "%u" );
|
||||
if (!IsText())
|
||||
{
|
||||
GetTypeBin( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
c = ( unsigned char )GetUnsignedShort();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
inline short CUtlBuffer::GetShort( )
|
||||
{
|
||||
short s;
|
||||
GetType( s, "%d" );
|
||||
GetType( s );
|
||||
return s;
|
||||
}
|
||||
|
||||
inline unsigned short CUtlBuffer::GetUnsignedShort( )
|
||||
{
|
||||
unsigned short s;
|
||||
GetType( s, "%u" );
|
||||
GetType( s );
|
||||
return s;
|
||||
}
|
||||
|
||||
inline int CUtlBuffer::GetInt( )
|
||||
{
|
||||
int i;
|
||||
GetType( i, "%d" );
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
inline int64 CUtlBuffer::GetInt64( )
|
||||
{
|
||||
int64 i;
|
||||
GetType( i, "%lld" );
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
inline int CUtlBuffer::GetIntHex( )
|
||||
inline unsigned int CUtlBuffer::GetIntHex( )
|
||||
{
|
||||
int i;
|
||||
GetType( i, "%x" );
|
||||
uint i;
|
||||
if (!IsText())
|
||||
{
|
||||
GetTypeBin( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
GetTypeText( i, 16 );
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline unsigned int CUtlBuffer::GetUnsignedInt( )
|
||||
{
|
||||
unsigned int u;
|
||||
GetType( u, "%u" );
|
||||
return u;
|
||||
unsigned int i;
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
inline uint64 CUtlBuffer::GetUnsignedInt64()
|
||||
{
|
||||
uint64 i;
|
||||
GetType( i );
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
inline float CUtlBuffer::GetFloat( )
|
||||
{
|
||||
float f;
|
||||
GetType( f, "%f" );
|
||||
GetType( f );
|
||||
return f;
|
||||
}
|
||||
|
||||
inline double CUtlBuffer::GetDouble( )
|
||||
{
|
||||
double d;
|
||||
GetType( d, "%f" );
|
||||
GetType( d );
|
||||
return d;
|
||||
}
|
||||
|
||||
inline void *CUtlBuffer::GetPtr( )
|
||||
{
|
||||
void *p;
|
||||
// LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
|
||||
#if !defined(X64BITS) && !defined(PLATFORM_64BITS)
|
||||
p = ( void* )GetUnsignedInt();
|
||||
#else
|
||||
p = ( void* )GetInt64();
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Where am I writing?
|
||||
@@ -816,14 +1051,14 @@ inline void CUtlBuffer::PutObject( T *src )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy( PeekPut(), src, sizeof( T ) );
|
||||
memcpy( PeekPut(), src, sizeof( T ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Byteswap.SwapFieldsToTargetEndian<T>( (T*)PeekPut(), src );
|
||||
}
|
||||
m_Put += sizeof(T);
|
||||
AddNullTermination();
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,19 +1080,93 @@ inline void CUtlBuffer::PutTypeBin( T src )
|
||||
{
|
||||
if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
|
||||
{
|
||||
Q_memcpy( PeekPut(), &src, sizeof( T ) );
|
||||
memcpy( PeekPut(), &src, sizeof( T ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<T>( (T*)PeekPut(), &src );
|
||||
}
|
||||
m_Put += sizeof(T);
|
||||
AddNullTermination();
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
|
||||
#if defined( _GAMECONSOLE )
|
||||
template <>
|
||||
inline void CUtlBuffer::PutTypeBin< float >( float src )
|
||||
{
|
||||
if ( CheckPut( sizeof( src ) ) )
|
||||
{
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<float>( &src, &src );
|
||||
}
|
||||
|
||||
//
|
||||
// Write the data
|
||||
//
|
||||
unsigned pData = (unsigned)PeekPut();
|
||||
if ( pData & 0x03 )
|
||||
{
|
||||
// handle unaligned write
|
||||
byte* dst = (byte*)pData;
|
||||
byte* srcPtr = (byte*)&src;
|
||||
dst[0] = srcPtr[0];
|
||||
dst[1] = srcPtr[1];
|
||||
dst[2] = srcPtr[2];
|
||||
dst[3] = srcPtr[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(float *)pData = src;
|
||||
}
|
||||
|
||||
m_Put += sizeof(float);
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void CUtlBuffer::PutTypeBin< double >( double src )
|
||||
{
|
||||
if ( CheckPut( sizeof( src ) ) )
|
||||
{
|
||||
if ( m_Byteswap.IsSwappingBytes() )
|
||||
{
|
||||
m_Byteswap.SwapBufferToTargetEndian<double>( &src, &src );
|
||||
}
|
||||
|
||||
//
|
||||
// Write the data
|
||||
//
|
||||
unsigned pData = (unsigned)PeekPut();
|
||||
if ( pData & 0x07 )
|
||||
{
|
||||
// handle unaligned write
|
||||
byte* dst = (byte*)pData;
|
||||
byte* srcPtr = (byte*)&src;
|
||||
dst[0] = srcPtr[0];
|
||||
dst[1] = srcPtr[1];
|
||||
dst[2] = srcPtr[2];
|
||||
dst[3] = srcPtr[3];
|
||||
dst[4] = srcPtr[4];
|
||||
dst[5] = srcPtr[5];
|
||||
dst[6] = srcPtr[6];
|
||||
dst[7] = srcPtr[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(double *)pData = src;
|
||||
}
|
||||
|
||||
m_Put += sizeof(double);
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline void CUtlBuffer::PutType( T src, const char *pszFmt )
|
||||
inline void CUtlBuffer::PutType( T src )
|
||||
{
|
||||
if (!IsText())
|
||||
{
|
||||
@@ -865,7 +1174,7 @@ inline void CUtlBuffer::PutType( T src, const char *pszFmt )
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf( pszFmt, src );
|
||||
Printf( GetFmtStr< T >(), src );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -933,54 +1242,73 @@ inline void CUtlBuffer::PutChar( char c )
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedChar( unsigned char c )
|
||||
{
|
||||
PutType( c, "%u" );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUint64( uint64 ub )
|
||||
{
|
||||
PutType( ub, "%llu" );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutInt16( int16 s16 )
|
||||
{
|
||||
PutType( s16, "%d" );
|
||||
if (!IsText())
|
||||
{
|
||||
PutTypeBin( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
PutUnsignedShort( c );
|
||||
}
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutShort( short s )
|
||||
{
|
||||
PutType( s, "%d" );
|
||||
PutType( s );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedShort( unsigned short s )
|
||||
{
|
||||
PutType( s, "%u" );
|
||||
PutType( s );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutInt( int i )
|
||||
{
|
||||
PutType( i, "%d" );
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutInt64( int64 i )
|
||||
{
|
||||
PutType( i, "%llu" );
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedInt( unsigned int u )
|
||||
{
|
||||
PutType( u, "%u" );
|
||||
PutType( u );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUnsignedInt64( uint64 i )
|
||||
{
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutUint64( uint64 i )
|
||||
{
|
||||
PutType( i );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutFloat( float f )
|
||||
{
|
||||
PutType( f, "%f" );
|
||||
PutType( f );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutDouble( double d )
|
||||
{
|
||||
PutType( d, "%f" );
|
||||
PutType( d );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::PutPtr( void *p )
|
||||
{
|
||||
// LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
|
||||
if (!IsText())
|
||||
{
|
||||
PutTypeBin( p );
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf( "0x%p", p );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Am I a text buffer?
|
||||
@@ -1030,26 +1358,25 @@ inline bool CUtlBuffer::IsReadOnly() const
|
||||
//-----------------------------------------------------------------------------
|
||||
// Buffer base and size
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const void* CUtlBuffer::Base() const
|
||||
{
|
||||
return m_Memory.Base();
|
||||
inline const void* CUtlBuffer::Base() const
|
||||
{
|
||||
return m_Memory.Base();
|
||||
}
|
||||
|
||||
inline void* CUtlBuffer::Base()
|
||||
{
|
||||
return m_Memory.Base();
|
||||
return m_Memory.Base();
|
||||
}
|
||||
|
||||
// Returns the base as a const char*, only valid in text mode.
|
||||
inline const char *CUtlBuffer::String() const
|
||||
inline const void* CUtlBuffer::String() const
|
||||
{
|
||||
Assert( IsText() );
|
||||
return reinterpret_cast<const char*>( m_Memory.Base() );
|
||||
}
|
||||
|
||||
inline int CUtlBuffer::Size() const
|
||||
{
|
||||
return m_Memory.NumAllocated();
|
||||
inline int CUtlBuffer::Size() const
|
||||
{
|
||||
return m_Memory.NumAllocated();
|
||||
}
|
||||
|
||||
|
||||
@@ -1063,7 +1390,7 @@ inline void CUtlBuffer::Clear()
|
||||
m_Error = 0;
|
||||
m_nOffset = 0;
|
||||
m_nMaxPut = -1;
|
||||
AddNullTermination();
|
||||
AddNullTermination( m_Put );
|
||||
}
|
||||
|
||||
inline void CUtlBuffer::Purge()
|
||||
@@ -1076,6 +1403,58 @@ inline void CUtlBuffer::Purge()
|
||||
m_Memory.Purge();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void *CUtlBuffer::AccessForDirectRead( int nBytes )
|
||||
{
|
||||
Assert( m_Get == 0 && m_Put == 0 && m_nMaxPut == 0 );
|
||||
EnsureCapacity( nBytes );
|
||||
m_nMaxPut = nBytes;
|
||||
return Base();
|
||||
}
|
||||
|
||||
inline void *CUtlBuffer::Detach()
|
||||
{
|
||||
void *p = m_Memory.Detach();
|
||||
Clear();
|
||||
return p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void CUtlBuffer::Spew( )
|
||||
{
|
||||
SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
|
||||
char pTmpLine[1024];
|
||||
while( IsValid() && GetBytesRemaining() )
|
||||
{
|
||||
V_memset( pTmpLine, 0, sizeof(pTmpLine) );
|
||||
Get( pTmpLine, MIN( ( size_t )GetBytesRemaining(), sizeof(pTmpLine)-1 ) );
|
||||
Msg( _T( "%s" ), pTmpLine );
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(_GAMECONSOLE)
|
||||
inline void CUtlBuffer::SwapCopy( CUtlBuffer &other )
|
||||
{
|
||||
m_Get = other.m_Get;
|
||||
m_Put = other.m_Put;
|
||||
m_Error = other.m_Error;
|
||||
m_Flags = other.m_Flags;
|
||||
m_Reserved = other.m_Reserved;
|
||||
m_nTab = other.m_nTab;
|
||||
m_nMaxPut = other.m_nMaxPut;
|
||||
m_nOffset = other.m_nOffset;
|
||||
m_GetOverflowFunc = other.m_GetOverflowFunc;
|
||||
m_PutOverflowFunc = other.m_PutOverflowFunc;
|
||||
m_Byteswap = other.m_Byteswap;
|
||||
|
||||
m_Memory.Swap( other.m_Memory );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void CUtlBuffer::CopyBuffer( const CUtlBuffer &buffer )
|
||||
{
|
||||
CopyBuffer( buffer.Base(), buffer.TellPut() );
|
||||
|
||||
@@ -59,13 +59,21 @@ public:
|
||||
private:
|
||||
struct HandleType_t
|
||||
{
|
||||
// MoeMod : use union to fix strict alias bug
|
||||
HandleType_t( unsigned int i, unsigned int s ) : nIndex( i ), nSerial( s )
|
||||
{
|
||||
Assert( i < ( 1 << HandleBits ) );
|
||||
Assert( s < ( 1 << ( 31 - HandleBits ) ) );
|
||||
}
|
||||
unsigned int nIndex : HandleBits;
|
||||
unsigned int nSerial : 31 - HandleBits;
|
||||
HandleType_t( UtlHandle_t handle ) : handle(handle) {}
|
||||
|
||||
union {
|
||||
UtlHandle_t handle;
|
||||
struct {
|
||||
unsigned int nIndex : HandleBits;
|
||||
unsigned int nSerial : 31 - HandleBits;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct EntryType_t
|
||||
@@ -186,7 +194,7 @@ bool CUtlHandleTable<T, HandleBits>::IsHandleValid( UtlHandle_t handle ) const
|
||||
return false;
|
||||
|
||||
unsigned int nIndex = GetListIndex( handle );
|
||||
AssertOnce( nIndex < ( unsigned int )m_list.Count() );
|
||||
//AssertOnce( nIndex < ( unsigned int )m_list.Count() );
|
||||
if ( nIndex >= ( unsigned int )m_list.Count() )
|
||||
return false;
|
||||
|
||||
@@ -241,20 +249,26 @@ int CUtlHandleTable<T, HandleBits>::GetIndexFromHandle( UtlHandle_t h ) const
|
||||
template< class T, int HandleBits >
|
||||
unsigned int CUtlHandleTable<T, HandleBits>::GetSerialNumber( UtlHandle_t handle )
|
||||
{
|
||||
return ( ( HandleType_t* )&handle )->nSerial;
|
||||
//return ( ( HandleType_t* )&handle )->nSerial;
|
||||
//return (handle >> HandleBits) & ((1 << (32 - HandleBits)) - 1);
|
||||
return HandleType_t(handle).nSerial;
|
||||
}
|
||||
|
||||
template< class T, int HandleBits >
|
||||
unsigned int CUtlHandleTable<T, HandleBits>::GetListIndex( UtlHandle_t handle )
|
||||
{
|
||||
return ( ( HandleType_t* )&handle )->nIndex;
|
||||
//return ( ( HandleType_t* )&handle )->nIndex;
|
||||
//return handle & ((1 << HandleBits) - 1);
|
||||
return HandleType_t(handle).nIndex;
|
||||
}
|
||||
|
||||
template< class T, int HandleBits >
|
||||
UtlHandle_t CUtlHandleTable<T, HandleBits>::CreateHandle( unsigned int nSerial, unsigned int nIndex )
|
||||
{
|
||||
HandleType_t h( nIndex, nSerial );
|
||||
return *( UtlHandle_t* )&h;
|
||||
//return *( UtlHandle_t* )&h;
|
||||
//return (nIndex & ((1 << HandleBits) - 1)) | (nSerial << HandleBits);
|
||||
return h.handle;
|
||||
}
|
||||
|
||||
|
||||
@@ -268,7 +282,7 @@ const typename CUtlHandleTable<T, HandleBits>::EntryType_t *CUtlHandleTable<T, H
|
||||
return NULL;
|
||||
|
||||
unsigned int nIndex = GetListIndex( handle );
|
||||
Assert( nIndex < ( unsigned int )m_list.Count() );
|
||||
//Assert( nIndex < ( unsigned int )m_list.Count() );
|
||||
if ( nIndex >= ( unsigned int )m_list.Count() )
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -461,7 +461,7 @@ inline void CUtlHash<Data, C, K>::Log( const char *filename )
|
||||
// Number of buckets must be a power of 2.
|
||||
// Key must be 32-bits (unsigned int).
|
||||
//
|
||||
typedef int UtlHashFastHandle_t;
|
||||
typedef intp UtlHashFastHandle_t;
|
||||
|
||||
#define UTLHASH_POOL_SCALAR 2
|
||||
|
||||
@@ -617,7 +617,7 @@ template<class Data, class HashFuncs> inline UtlHashFastHandle_t CUtlHashFast<Da
|
||||
template<class Data, class HashFuncs> inline UtlHashFastHandle_t CUtlHashFast<Data,HashFuncs>::FastInsert( unsigned int uiKey, const Data &data )
|
||||
{
|
||||
// Get a new element from the pool.
|
||||
int iHashData = m_aDataPool.Alloc( true );
|
||||
intp iHashData = m_aDataPool.Alloc( true );
|
||||
HashFastData_t *pHashData = &m_aDataPool[iHashData];
|
||||
if ( !pHashData )
|
||||
return InvalidHandle();
|
||||
@@ -671,7 +671,7 @@ template<class Data, class HashFuncs> inline UtlHashFastHandle_t CUtlHashFast<Da
|
||||
// hash the "key" - get the correct hash table "bucket"
|
||||
int iBucket = HashFuncs::Hash( uiKey, m_uiBucketMask );
|
||||
|
||||
for ( int iElement = m_aBuckets[iBucket]; iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next( iElement ) )
|
||||
for ( intp iElement = m_aBuckets[iBucket]; iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next( iElement ) )
|
||||
{
|
||||
if ( m_aDataPool[iElement].m_uiKey == uiKey )
|
||||
return iElement;
|
||||
@@ -719,7 +719,7 @@ template<class Data, class HashFuncs> inline Data const &CUtlHashFast<Data,HashF
|
||||
// Number of buckets must be a power of 2.
|
||||
// Key must be 32-bits (unsigned int).
|
||||
//
|
||||
typedef int UtlHashFixedHandle_t;
|
||||
typedef intp UtlHashFixedHandle_t;
|
||||
|
||||
template <int NUM_BUCKETS>
|
||||
class CUtlHashFixedGenericHash
|
||||
@@ -753,7 +753,7 @@ public:
|
||||
void Purge( void );
|
||||
|
||||
// Invalid handle.
|
||||
static UtlHashFixedHandle_t InvalidHandle( void ) { return ( UtlHashFixedHandle_t )~0; }
|
||||
static UtlHashFixedHandle_t InvalidHandle( void ) { return ( UtlHashFixedHandle_t )-1; }
|
||||
|
||||
// Size.
|
||||
int Count( void );
|
||||
@@ -858,7 +858,7 @@ template<class Data, int NUM_BUCKETS, class HashFuncs> inline UtlHashFixedHandle
|
||||
pHashData->m_Data = data;
|
||||
|
||||
m_nElements++;
|
||||
return (UtlHashFixedHandle_t)pHashData;
|
||||
return (UtlHashFixedHandle_t)(intp)pHashData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -895,7 +895,7 @@ template<class Data, int NUM_BUCKETS, class HashFuncs> inline UtlHashFixedHandle
|
||||
for ( UtlPtrLinkedListIndex_t iElement = bucket.Head(); iElement != bucket.InvalidIndex(); iElement = bucket.Next( iElement ) )
|
||||
{
|
||||
if ( bucket[iElement].m_uiKey == uiKey )
|
||||
return (UtlHashFixedHandle_t)iElement;
|
||||
return (UtlHashFixedHandle_t)(intp)iElement;
|
||||
}
|
||||
|
||||
return InvalidHandle();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Linked list container class
|
||||
//
|
||||
@@ -24,7 +24,10 @@
|
||||
|
||||
// This is a useful macro to iterate from head to tail in a linked list.
|
||||
#define FOR_EACH_LL( listName, iteratorName ) \
|
||||
for( int iteratorName=(listName).Head(); (listName).IsUtlLinkedList && iteratorName != (listName).InvalidIndex(); iteratorName = (listName).Next( iteratorName ) )
|
||||
for( auto iteratorName=(listName).Head(); (listName).IsUtlLinkedList && iteratorName != (listName).InvalidIndex(); iteratorName = (listName).Next( iteratorName ) )
|
||||
|
||||
#define FOR_EACH_LL_BACK( listName, iteratorName ) \
|
||||
for( auto iteratorName=(listName).Tail(); (listName).IsUtlLinkedList && iteratorName != (listName).InvalidIndex(); iteratorName = (listName).Previous( iteratorName ) )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class CUtlLinkedList:
|
||||
@@ -65,12 +68,15 @@ public:
|
||||
typedef S IndexType_t; // should really be called IndexStorageType_t, but that would be a huge change
|
||||
typedef I IndexLocalType_t;
|
||||
typedef M MemoryAllocator_t;
|
||||
static const bool IsUtlLinkedList = true; // Used to match this at compiletime
|
||||
enum { IsUtlLinkedList = true }; // Used to match this at compiletime
|
||||
|
||||
// constructor, destructor
|
||||
CUtlLinkedList( int growSize = 0, int initSize = 0 );
|
||||
~CUtlLinkedList();
|
||||
|
||||
CUtlLinkedList( const CUtlLinkedList& ) = delete;
|
||||
CUtlLinkedList& operator=( const CUtlLinkedList& ) = delete;
|
||||
|
||||
// gets particular elements
|
||||
T& Element( I i );
|
||||
T const& Element( I i ) const;
|
||||
@@ -348,16 +354,13 @@ protected:
|
||||
typedef UtlLinkedListElem_t<T, S> ListElem_t;
|
||||
|
||||
// constructs the class
|
||||
I AllocInternal( bool multilist = false );
|
||||
I AllocInternal( bool multilist = false ) RESTRICT;
|
||||
void ConstructList();
|
||||
|
||||
// Gets at the list element....
|
||||
ListElem_t& InternalElement( I i ) { return m_Memory[i]; }
|
||||
ListElem_t const& InternalElement( I i ) const { return m_Memory[i]; }
|
||||
|
||||
// copy constructors not allowed
|
||||
CUtlLinkedList( CUtlLinkedList<T, S, ML, I, M> const& list ) { Assert(0); }
|
||||
|
||||
M m_Memory;
|
||||
I m_Head;
|
||||
I m_Tail;
|
||||
@@ -379,42 +382,35 @@ protected:
|
||||
{
|
||||
m_pElements = m_Memory.Base();
|
||||
}
|
||||
|
||||
private:
|
||||
// Faster version of Next that can only be used from tested code internal
|
||||
// to this class, such as Find(). It avoids the cost of checking the index
|
||||
// validity, which is a big win on debug builds.
|
||||
I PrivateNext( I i ) const;
|
||||
};
|
||||
|
||||
|
||||
// this is kind of ugly, but until C++ gets templatized typedefs in C++0x, it's our only choice
|
||||
template < class T >
|
||||
class CUtlFixedLinkedList : public CUtlLinkedList< T, int, true, int, CUtlFixedMemory< UtlLinkedListElem_t< T, int > > >
|
||||
class CUtlFixedLinkedList : public CUtlLinkedList< T, intp, true, intp, CUtlFixedMemory< UtlLinkedListElem_t< T, intp > > >
|
||||
{
|
||||
public:
|
||||
CUtlFixedLinkedList( int growSize = 0, int initSize = 0 )
|
||||
: CUtlLinkedList< T, int, true, int, CUtlFixedMemory< UtlLinkedListElem_t< T, int > > >( growSize, initSize ) {}
|
||||
: CUtlLinkedList< T, intp, true, intp, CUtlFixedMemory< UtlLinkedListElem_t< T, intp > > >( growSize, initSize ) {}
|
||||
|
||||
typedef CUtlLinkedList< T, int, true, int, CUtlFixedMemory< UtlLinkedListElem_t< T, int > > > BaseClass;
|
||||
bool IsValidIndex( int i ) const
|
||||
bool IsValidIndex( intp i ) const
|
||||
{
|
||||
if ( !BaseClass::Memory().IsIdxValid( i ) )
|
||||
if ( !this->Memory().IsIdxValid( i ) )
|
||||
return false;
|
||||
|
||||
#ifdef _DEBUG // it's safe to skip this here, since the only way to get indices after m_LastAlloc is to use MaxElementIndex
|
||||
if ( BaseClass::Memory().IsIdxAfter( i, this->m_LastAlloc ) )
|
||||
if ( this->Memory().IsIdxAfter( i, this->m_LastAlloc ) )
|
||||
{
|
||||
Assert( 0 );
|
||||
return false; // don't read values that have been allocated, but not constructed
|
||||
}
|
||||
#endif
|
||||
|
||||
return ( BaseClass::Memory()[ i ].m_Previous != i ) || ( BaseClass::Memory()[ i ].m_Next == i );
|
||||
return ( this->Memory()[ i ].m_Previous != i ) || ( this->Memory()[ i ].m_Next == i );
|
||||
}
|
||||
|
||||
private:
|
||||
int MaxElementIndex() const { Assert( 0 ); return BaseClass::InvalidIndex(); } // fixedmemory containers don't support iteration from 0..maxelements-1
|
||||
int MaxElementIndex() const { Assert( 0 ); return this->InvalidIndex(); } // fixedmemory containers don't support iteration from 0..maxelements-1
|
||||
void ResetDbgInfo() {}
|
||||
};
|
||||
|
||||
@@ -438,8 +434,10 @@ template <class T, class S, bool ML, class I, class M>
|
||||
CUtlLinkedList<T,S,ML,I,M>::CUtlLinkedList( int growSize, int initSize ) :
|
||||
m_Memory( growSize, initSize ), m_LastAlloc( m_Memory.InvalidIterator() )
|
||||
{
|
||||
#if !defined( PLATFORM_WINDOWS_PC64 ) && !defined( PLATFORM_64BITS )
|
||||
// Prevent signed non-int datatypes
|
||||
COMPILE_TIME_ASSERT( sizeof(S) == 4 || ( ( (S)-1 ) > 0 ) );
|
||||
#endif
|
||||
ConstructList();
|
||||
ResetDbgInfo();
|
||||
}
|
||||
@@ -539,21 +537,13 @@ inline I CUtlLinkedList<T,S,ML,I,M>::Next( I i ) const
|
||||
return InternalElement(i).m_Next;
|
||||
}
|
||||
|
||||
template <class T, class S, bool ML, class I, class M>
|
||||
inline I CUtlLinkedList<T,S,ML,I,M>::PrivateNext( I i ) const
|
||||
{
|
||||
return InternalElement(i).m_Next;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Are nodes in the list or valid?
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning( disable: 4310 ) // Allows "(I)(S)M::INVALID_INDEX" below
|
||||
#endif
|
||||
template <class T, class S, bool ML, class I, class M>
|
||||
inline bool CUtlLinkedList<T,S,ML,I,M>::IndexInRange( I index ) // Static method
|
||||
{
|
||||
@@ -564,17 +554,17 @@ inline bool CUtlLinkedList<T,S,ML,I,M>::IndexInRange( I index ) // Static method
|
||||
|
||||
// Do some static checks here:
|
||||
// 'I' needs to be able to store 'S'
|
||||
COMPILE_TIME_ASSERT( sizeof(I) >= sizeof(S) );
|
||||
// These COMPILE_TIME_ASSERT checks need to be in individual scopes to avoid build breaks
|
||||
// on MacOS and Linux due to a gcc bug.
|
||||
{ COMPILE_TIME_ASSERT( sizeof(I) >= sizeof(S) ); }
|
||||
// 'S' should be unsigned (to avoid signed arithmetic errors for plausibly exhaustible ranges)
|
||||
COMPILE_TIME_ASSERT( ( sizeof(S) > 2 ) || ( ( (S)-1 ) > 0 ) );
|
||||
{ COMPILE_TIME_ASSERT( ( sizeof(S) > 2 ) || ( ( (S)-1 ) > 0 ) ); }
|
||||
// M::INVALID_INDEX should be storable in S to avoid ambiguities (e.g. with 65536)
|
||||
COMPILE_TIME_ASSERT( ( M::INVALID_INDEX == -1 ) || ( M::INVALID_INDEX == (S)M::INVALID_INDEX ) );
|
||||
{ COMPILE_TIME_ASSERT( ( M::INVALID_INDEX == -1 ) || ( M::INVALID_INDEX == (S)M::INVALID_INDEX ) ); }
|
||||
|
||||
return ( ( (S)index == index ) && ( (S)index != InvalidIndex() ) );
|
||||
}
|
||||
#ifdef _WIN32
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class T, class S, bool ML, class I, class M>
|
||||
inline bool CUtlLinkedList<T,S,ML,I,M>::IsValidIndex( I i ) const
|
||||
@@ -664,7 +654,7 @@ void CUtlLinkedList<T,S,ML,I,M>::PurgeAndDeleteElements()
|
||||
// Node allocation/deallocation
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class S, bool ML, class I, class M>
|
||||
I CUtlLinkedList<T,S,ML,I,M>::AllocInternal( bool multilist )
|
||||
I CUtlLinkedList<T,S,ML,I,M>::AllocInternal( bool multilist ) RESTRICT
|
||||
{
|
||||
Assert( !multilist || ML );
|
||||
#ifdef MULTILIST_PEDANTIC_ASSERTS
|
||||
@@ -859,9 +849,7 @@ inline I CUtlLinkedList<T,S,ML,I,M>::AddToTail( T const& src )
|
||||
template<class T, class S, bool ML, class I, class M>
|
||||
I CUtlLinkedList<T,S,ML,I,M>::Find( const T &src ) const
|
||||
{
|
||||
// Cache the invalidIndex to avoid two levels of function calls on each iteration.
|
||||
I invalidIndex = InvalidIndex();
|
||||
for ( I i=Head(); i != invalidIndex; i = PrivateNext( i ) )
|
||||
for ( I i=Head(); i != InvalidIndex(); i = Next( i ) )
|
||||
{
|
||||
if ( Element( i ) == src )
|
||||
return i;
|
||||
|
||||
+97
-39
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -17,22 +17,21 @@
|
||||
#include "tier0/dbg.h"
|
||||
#include <string.h>
|
||||
#include "tier0/platform.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
#include "tier0/memalloc.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning (disable:4100)
|
||||
#pragma warning (disable:4514)
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifdef UTLMEMORY_TRACK
|
||||
#define UTLMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "Sum of all UtlMemory", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 )
|
||||
#define UTLMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "Sum of all UtlMemory", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 )
|
||||
#define UTLMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "||Sum of all UtlMemory||", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 )
|
||||
#define UTLMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "||Sum of all UtlMemory||", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 )
|
||||
#else
|
||||
#define UTLMEMORY_TRACK_ALLOC() ((void)0)
|
||||
#define UTLMEMORY_TRACK_FREE() ((void)0)
|
||||
@@ -46,6 +45,8 @@
|
||||
template< class T, class I = int >
|
||||
class CUtlMemory
|
||||
{
|
||||
template< class A, class B> friend class CUtlVector;
|
||||
template< class A, size_t B> friend class CUtlVectorFixedGrowableCompat;
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlMemory( int nGrowSize = 0, int nInitSize = 0 );
|
||||
@@ -53,6 +54,12 @@ public:
|
||||
CUtlMemory( const T* pMemory, int numElements );
|
||||
~CUtlMemory();
|
||||
|
||||
CUtlMemory( const CUtlMemory& ) = delete;
|
||||
CUtlMemory& operator=( const CUtlMemory& ) = delete;
|
||||
|
||||
CUtlMemory( CUtlMemory&& moveFrom );
|
||||
CUtlMemory& operator=( CUtlMemory&& moveFrom );
|
||||
|
||||
// Set the size by which the memory grows
|
||||
void Init( int nGrowSize = 0, int nInitSize = 0 );
|
||||
|
||||
@@ -92,8 +99,9 @@ public:
|
||||
// Attaches the buffer to external memory....
|
||||
void SetExternalBuffer( T* pMemory, int numElements );
|
||||
void SetExternalBuffer( const T* pMemory, int numElements );
|
||||
// Takes ownership of the passed memory, including freeing it when this buffer is destroyed.
|
||||
void AssumeMemory( T *pMemory, int nSize );
|
||||
T* Detach();
|
||||
void *DetachMemory();
|
||||
|
||||
// Fast swap
|
||||
void Swap( CUtlMemory< T, I > &mem );
|
||||
@@ -212,8 +220,7 @@ public:
|
||||
CUtlMemoryFixed( T* pMemory, int numElements ) { Assert( 0 ); }
|
||||
|
||||
// Can we use this index?
|
||||
// Use unsigned math to improve performance
|
||||
bool IsIdxValid( int i ) const { return (size_t)i < SIZE; }
|
||||
bool IsIdxValid( int i ) const { return (i >= 0) && (i < SIZE); }
|
||||
|
||||
// Specify the invalid ('null') index that we'll only return on failure
|
||||
static const int INVALID_INDEX = -1; // For use with COMPILE_TIME_ASSERT
|
||||
@@ -224,11 +231,10 @@ public:
|
||||
const T* Base() const { if ( nAlignment == 0 ) return (T*)(&m_Memory[0]); else return (T*)AlignValue( &m_Memory[0], nAlignment ); }
|
||||
|
||||
// element access
|
||||
// Use unsigned math and inlined checks to improve performance.
|
||||
T& operator[]( int i ) { Assert( (size_t)i < SIZE ); return Base()[i]; }
|
||||
const T& operator[]( int i ) const { Assert( (size_t)i < SIZE ); return Base()[i]; }
|
||||
T& Element( int i ) { Assert( (size_t)i < SIZE ); return Base()[i]; }
|
||||
const T& Element( int i ) const { Assert( (size_t)i < SIZE ); return Base()[i]; }
|
||||
T& operator[]( int i ) { Assert( IsIdxValid(i) ); return Base()[i]; }
|
||||
const T& operator[]( int i ) const { Assert( IsIdxValid(i) ); return Base()[i]; }
|
||||
T& Element( int i ) { Assert( IsIdxValid(i) ); return Base()[i]; }
|
||||
const T& Element( int i ) const { Assert( IsIdxValid(i) ); return Base()[i]; }
|
||||
|
||||
// Attaches the buffer to external memory....
|
||||
void SetExternalBuffer( T* pMemory, int numElements ) { Assert( 0 ); }
|
||||
@@ -274,12 +280,7 @@ private:
|
||||
char m_Memory[ SIZE*sizeof(T) + nAlignment ];
|
||||
};
|
||||
|
||||
#if defined(POSIX)
|
||||
// From Chris Green: Memory is a little fuzzy but I believe this class did
|
||||
// something fishy with respect to msize and alignment that was OK under our
|
||||
// allocator, the glibc allocator, etc but not the valgrind one (which has no
|
||||
// padding because it detects all forms of head/tail overwrite, including
|
||||
// writing 1 byte past a 1 byte allocation).
|
||||
#ifdef _LINUX
|
||||
#define REMEMBER_ALLOC_SIZE_FOR_VALGRIND 1
|
||||
#endif
|
||||
|
||||
@@ -445,6 +446,44 @@ template< class T, class I >
|
||||
CUtlMemory<T,I>::~CUtlMemory()
|
||||
{
|
||||
Purge();
|
||||
|
||||
#ifdef _DEBUG
|
||||
m_pMemory = reinterpret_cast< T* >( 0xFEFEBAAD );
|
||||
m_nAllocationCount = 0x7BADF00D;
|
||||
#endif
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
CUtlMemory<T,I>::CUtlMemory( CUtlMemory&& moveFrom )
|
||||
: m_pMemory(moveFrom.m_pMemory)
|
||||
, m_nAllocationCount(moveFrom.m_nAllocationCount)
|
||||
, m_nGrowSize(moveFrom.m_nGrowSize)
|
||||
{
|
||||
moveFrom.m_pMemory = nullptr;
|
||||
moveFrom.m_nAllocationCount = 0;
|
||||
moveFrom.m_nGrowSize = 0;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
CUtlMemory<T,I>& CUtlMemory<T,I>::operator=( CUtlMemory&& moveFrom )
|
||||
{
|
||||
// Copy member variables to locals before purge to handle self-assignment
|
||||
T* pMemory = moveFrom.m_pMemory;
|
||||
int nAllocationCount = moveFrom.m_nAllocationCount;
|
||||
int nGrowSize = moveFrom.m_nGrowSize;
|
||||
|
||||
moveFrom.m_pMemory = nullptr;
|
||||
moveFrom.m_nAllocationCount = 0;
|
||||
moveFrom.m_nGrowSize = 0;
|
||||
|
||||
// If this is a self-assignment, Purge() is a no-op here
|
||||
Purge();
|
||||
|
||||
m_pMemory = pMemory;
|
||||
m_nAllocationCount = nAllocationCount;
|
||||
m_nGrowSize = nGrowSize;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
@@ -493,7 +532,7 @@ void CUtlMemory<T,I>::ConvertToGrowableMemory( int nGrowSize )
|
||||
|
||||
int nNumBytes = m_nAllocationCount * sizeof(T);
|
||||
T *pMemory = (T*)malloc( nNumBytes );
|
||||
memcpy( (void*)pMemory, (void*)m_pMemory, nNumBytes );
|
||||
memcpy( pMemory, m_pMemory, nNumBytes );
|
||||
m_pMemory = pMemory;
|
||||
}
|
||||
else
|
||||
@@ -543,6 +582,24 @@ void CUtlMemory<T,I>::AssumeMemory( T* pMemory, int numElements )
|
||||
m_nAllocationCount = numElements;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void *CUtlMemory<T,I>::DetachMemory()
|
||||
{
|
||||
if ( IsExternallyAllocated() )
|
||||
return NULL;
|
||||
|
||||
void *pMemory = m_pMemory;
|
||||
m_pMemory = 0;
|
||||
m_nAllocationCount = 0;
|
||||
return pMemory;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline T* CUtlMemory<T,I>::Detach()
|
||||
{
|
||||
return (T*)DetachMemory();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element access
|
||||
@@ -550,35 +607,31 @@ void CUtlMemory<T,I>::AssumeMemory( T* pMemory, int numElements )
|
||||
template< class T, class I >
|
||||
inline T& CUtlMemory<T,I>::operator[]( I i )
|
||||
{
|
||||
// Avoid function calls in the asserts to improve debug build performance
|
||||
Assert( m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER ); //Assert( !IsReadOnly() );
|
||||
Assert( (uint32)i < (uint32)m_nAllocationCount );
|
||||
return m_pMemory[(uint32)i];
|
||||
Assert( !IsReadOnly() );
|
||||
Assert( IsIdxValid(i) );
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline const T& CUtlMemory<T,I>::operator[]( I i ) const
|
||||
{
|
||||
// Avoid function calls in the asserts to improve debug build performance
|
||||
Assert( (uint32)i < (uint32)m_nAllocationCount );
|
||||
return m_pMemory[(uint32)i];
|
||||
Assert( IsIdxValid(i) );
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline T& CUtlMemory<T,I>::Element( I i )
|
||||
{
|
||||
// Avoid function calls in the asserts to improve debug build performance
|
||||
Assert( m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER ); //Assert( !IsReadOnly() );
|
||||
Assert( (uint32)i < (uint32)m_nAllocationCount );
|
||||
return m_pMemory[(uint32)i];
|
||||
Assert( !IsReadOnly() );
|
||||
Assert( IsIdxValid(i) );
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline const T& CUtlMemory<T,I>::Element( I i ) const
|
||||
{
|
||||
// Avoid function calls in the asserts to improve debug build performance
|
||||
Assert( (uint32)i < (uint32)m_nAllocationCount );
|
||||
return m_pMemory[(uint32)i];
|
||||
Assert( IsIdxValid(i) );
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -651,10 +704,10 @@ inline int CUtlMemory<T,I>::Count() const
|
||||
template< class T, class I >
|
||||
inline bool CUtlMemory<T,I>::IsIdxValid( I i ) const
|
||||
{
|
||||
// If we always cast 'i' and 'm_nAllocationCount' to unsigned then we can
|
||||
// do our range checking with a single comparison instead of two. This gives
|
||||
// a modest speedup in debug builds.
|
||||
return (uint32)i < (uint32)m_nAllocationCount;
|
||||
// GCC warns if I is an unsigned type and we do a ">= 0" against it (since the comparison is always 0).
|
||||
// We get the warning even if we cast inside the expression. It only goes away if we assign to another variable.
|
||||
long x = i;
|
||||
return ( x >= 0 ) && ( x < m_nAllocationCount );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -672,6 +725,11 @@ inline int UtlMemory_CalcNewAllocationCount( int nAllocationCount, int nGrowSize
|
||||
{
|
||||
// Compute an allocation which is at least as big as a cache line...
|
||||
nAllocationCount = (31 + nBytesItem) / nBytesItem;
|
||||
// If the requested amount is larger then compute an allocation which
|
||||
// is exactly the right size. Otherwise we can end up with wasted memory
|
||||
// when CUtlVector::EnsureCount(n) is called.
|
||||
if ( nAllocationCount < nNewSize )
|
||||
nAllocationCount = nNewSize;
|
||||
}
|
||||
|
||||
while (nAllocationCount < nNewSize)
|
||||
|
||||
+137
-25
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Defines a symbol table
|
||||
//
|
||||
@@ -13,9 +13,13 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/threadtools.h"
|
||||
#include "tier1/utlrbtree.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utllinkedlist.h"
|
||||
#include "tier1/stringpool.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -24,6 +28,7 @@
|
||||
class CUtlSymbolTable;
|
||||
class CUtlSymbolTableMT;
|
||||
|
||||
#define FILENAMEHANDLE_INVALID 0
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is a symbol, which is a easier way of dealing with strings.
|
||||
@@ -52,14 +57,19 @@ public:
|
||||
bool IsValid() const { return m_Id != UTL_INVAL_SYMBOL; }
|
||||
|
||||
// Gets at the symbol
|
||||
operator UtlSymId_t const() const { return m_Id; }
|
||||
operator UtlSymId_t () const { return m_Id; }
|
||||
|
||||
// Gets the string associated with the symbol
|
||||
const char* String( ) const;
|
||||
|
||||
// Modules can choose to disable the static symbol table so to prevent accidental use of them.
|
||||
static void DisableStaticSymbolTable();
|
||||
|
||||
|
||||
// Methods with explicit locking mechanism. Only use for optimization reasons.
|
||||
static void LockTableForRead();
|
||||
static void UnlockTableForRead();
|
||||
const char * StringNoLock() const;
|
||||
|
||||
protected:
|
||||
UtlSymId_t m_Id;
|
||||
|
||||
@@ -85,13 +95,17 @@ protected:
|
||||
// of strings to symbols and back. The symbol class itself contains
|
||||
// a static version of this class for creating global strings, but this
|
||||
// class can also be instanced to create local symbol tables.
|
||||
//
|
||||
// This class stores the strings in a series of string pools. The first
|
||||
// two bytes of each string are decorated with a hash to speed up
|
||||
// comparisons.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CUtlSymbolTable
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlSymbolTable( int growSize = 0, int initSize = 32, bool caseInsensitive = false );
|
||||
CUtlSymbolTable( int growSize = 0, int initSize = 16, bool caseInsensitive = false );
|
||||
~CUtlSymbolTable();
|
||||
|
||||
// Finds and/or creates a symbol based on the string
|
||||
@@ -102,6 +116,11 @@ public:
|
||||
|
||||
// Look up the string associated with a particular symbol
|
||||
const char* String( CUtlSymbol id ) const;
|
||||
|
||||
inline bool HasElement(const char* pStr) const
|
||||
{
|
||||
return Find(pStr) != UTL_INVAL_SYMBOL;
|
||||
}
|
||||
|
||||
// Remove all symbols in the table.
|
||||
void RemoveAll();
|
||||
@@ -111,6 +130,10 @@ public:
|
||||
return m_Lookup.Count();
|
||||
}
|
||||
|
||||
// We store one of these at the beginning of every string to speed
|
||||
// up comparisons.
|
||||
typedef unsigned short hashDecoration_t;
|
||||
|
||||
protected:
|
||||
class CStringPoolIndex
|
||||
{
|
||||
@@ -120,10 +143,8 @@ protected:
|
||||
}
|
||||
|
||||
inline CStringPoolIndex( unsigned short iPool, unsigned short iOffset )
|
||||
{
|
||||
m_iPool = iPool;
|
||||
m_iOffset = iOffset;
|
||||
}
|
||||
: m_iPool(iPool), m_iOffset(iOffset)
|
||||
{}
|
||||
|
||||
inline bool operator==( const CStringPoolIndex &other ) const
|
||||
{
|
||||
@@ -158,7 +179,9 @@ protected:
|
||||
};
|
||||
|
||||
CTree m_Lookup;
|
||||
|
||||
bool m_bInsensitive;
|
||||
mutable unsigned short m_nUserSearchStringHash;
|
||||
mutable const char* m_pUserSearchString;
|
||||
|
||||
// stores the string data
|
||||
@@ -167,11 +190,14 @@ protected:
|
||||
private:
|
||||
int FindPoolWithSpace( int len ) const;
|
||||
const char* StringFromIndex( const CStringPoolIndex &index ) const;
|
||||
const char* DecoratedStringFromIndex( const CStringPoolIndex &index ) const;
|
||||
|
||||
friend class CLess;
|
||||
friend class CSymbolHash;
|
||||
|
||||
};
|
||||
|
||||
class CUtlSymbolTableMT : private CUtlSymbolTable
|
||||
class CUtlSymbolTableMT : public CUtlSymbolTable
|
||||
{
|
||||
public:
|
||||
CUtlSymbolTableMT( int growSize = 0, int initSize = 32, bool caseInsensitive = false )
|
||||
@@ -189,9 +215,9 @@ public:
|
||||
|
||||
CUtlSymbol Find( const char* pString ) const
|
||||
{
|
||||
m_lock.LockForRead();
|
||||
m_lock.LockForWrite();
|
||||
CUtlSymbol result = CUtlSymbolTable::Find( pString );
|
||||
m_lock.UnlockRead();
|
||||
m_lock.UnlockWrite();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -202,9 +228,24 @@ public:
|
||||
m_lock.UnlockRead();
|
||||
return pszResult;
|
||||
}
|
||||
|
||||
|
||||
const char * StringNoLock( CUtlSymbol id ) const
|
||||
{
|
||||
return CUtlSymbolTable::String( id );
|
||||
}
|
||||
|
||||
void LockForRead()
|
||||
{
|
||||
m_lock.LockForRead();
|
||||
}
|
||||
|
||||
void UnlockForRead()
|
||||
{
|
||||
m_lock.UnlockRead();
|
||||
}
|
||||
|
||||
private:
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#ifdef WIN32
|
||||
mutable CThreadSpinRWLock m_lock;
|
||||
#else
|
||||
mutable CThreadRWLock m_lock;
|
||||
@@ -225,7 +266,6 @@ private:
|
||||
// The handle is a CUtlSymbol for the dirname and the same for the filename, the accessor
|
||||
// copies them into a static char buffer for return.
|
||||
typedef void* FileNameHandle_t;
|
||||
#define FILENAMEHANDLE_INVALID 0
|
||||
|
||||
// Symbol table for more efficiently storing filenames by breaking paths and filenames apart.
|
||||
// Refactored from BaseFileSystem.h
|
||||
@@ -238,32 +278,104 @@ class CUtlFilenameSymbolTable
|
||||
{
|
||||
FileNameHandleInternal_t()
|
||||
{
|
||||
path = 0;
|
||||
file = 0;
|
||||
COMPILE_TIME_ASSERT( sizeof( *this ) == sizeof( FileNameHandle_t ) );
|
||||
COMPILE_TIME_ASSERT( sizeof( value ) == 4 );
|
||||
value = 0;
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
pad = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We pack the path and file values into a single 32 bit value. We were running
|
||||
// out of space with the two 16 bit values (more than 64k files) so instead of increasing
|
||||
// the total size we split the underlying pool into two (paths and files) and
|
||||
// use a smaller path string pool and a larger file string pool.
|
||||
unsigned int value;
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
// some padding to make sure we are the same size as FileNameHandle_t on 64 bit.
|
||||
unsigned int pad;
|
||||
#endif
|
||||
|
||||
static const unsigned int cNumBitsInPath = 12;
|
||||
static const unsigned int cNumBitsInFile = 32 - cNumBitsInPath;
|
||||
|
||||
static const unsigned int cMaxPathValue = 1 << cNumBitsInPath;
|
||||
static const unsigned int cMaxFileValue = 1 << cNumBitsInFile;
|
||||
|
||||
static const unsigned int cPathBitMask = cMaxPathValue - 1;
|
||||
static const unsigned int cFileBitMask = cMaxFileValue - 1;
|
||||
|
||||
// Part before the final '/' character
|
||||
unsigned short path;
|
||||
unsigned int GetPath() const { return ((value >> cNumBitsInFile) & cPathBitMask); }
|
||||
void SetPath( unsigned int path ) { Assert( path < cMaxPathValue ); value = ((value & cFileBitMask) | ((path & cPathBitMask) << cNumBitsInFile)); }
|
||||
|
||||
// Part after the final '/', including extension
|
||||
unsigned short file;
|
||||
unsigned int GetFile() const { return (value & cFileBitMask); }
|
||||
void SetFile( unsigned int file ) { Assert( file < cMaxFileValue ); value = ((value & (cPathBitMask << cNumBitsInFile)) | (file & cFileBitMask)); }
|
||||
};
|
||||
|
||||
class HashTable;
|
||||
|
||||
public:
|
||||
CUtlFilenameSymbolTable();
|
||||
~CUtlFilenameSymbolTable();
|
||||
FileNameHandle_t FindOrAddFileName( const char *pFileName );
|
||||
FileNameHandle_t FindFileName( const char *pFileName );
|
||||
int PathIndex(const FileNameHandle_t &handle) { return (( const FileNameHandleInternal_t * )&handle)->path; }
|
||||
int PathIndex( const FileNameHandle_t &handle ) { return (( const FileNameHandleInternal_t * )&handle)->GetPath(); }
|
||||
bool String( const FileNameHandle_t& handle, char *buf, int buflen );
|
||||
void RemoveAll();
|
||||
void SpewStrings();
|
||||
bool SaveToBuffer( CUtlBuffer &buffer );
|
||||
bool RestoreFromBuffer( CUtlBuffer &buffer );
|
||||
|
||||
private:
|
||||
//CCountedStringPool m_StringPool;
|
||||
HashTable* m_Strings;
|
||||
CCountedStringPoolBase<unsigned short> m_PathStringPool;
|
||||
CCountedStringPoolBase<unsigned int> m_FileStringPool;
|
||||
mutable CThreadSpinRWLock m_lock;
|
||||
};
|
||||
|
||||
// This creates a simple class that includes the underlying CUtlSymbol
|
||||
// as a private member and then instances a private symbol table to
|
||||
// manage those symbols. Avoids the possibility of the code polluting the
|
||||
// 'global'/default symbol table, while letting the code look like
|
||||
// it's just using = and .String() to look at CUtlSymbol type objects
|
||||
//
|
||||
// NOTE: You can't pass these objects between .dlls in an interface (also true of CUtlSymbol of course)
|
||||
//
|
||||
#define DECLARE_PRIVATE_SYMBOLTYPE( typename ) \
|
||||
class typename \
|
||||
{ \
|
||||
public: \
|
||||
typename(); \
|
||||
typename( const char* pStr ); \
|
||||
typename& operator=( typename const& src ); \
|
||||
bool operator==( typename const& src ) const; \
|
||||
const char* String( ) const; \
|
||||
private: \
|
||||
CUtlSymbol m_SymbolId; \
|
||||
};
|
||||
|
||||
// Put this in the .cpp file that uses the above typename
|
||||
#define IMPLEMENT_PRIVATE_SYMBOLTYPE( typename ) \
|
||||
static CUtlSymbolTable g_##typename##SymbolTable; \
|
||||
typename::typename() \
|
||||
{ \
|
||||
m_SymbolId = UTL_INVAL_SYMBOL; \
|
||||
} \
|
||||
typename::typename( const char* pStr ) \
|
||||
{ \
|
||||
m_SymbolId = g_##typename##SymbolTable.AddString( pStr ); \
|
||||
} \
|
||||
typename& typename::operator=( typename const& src ) \
|
||||
{ \
|
||||
m_SymbolId = src.m_SymbolId; \
|
||||
return *this; \
|
||||
} \
|
||||
bool typename::operator==( typename const& src ) const \
|
||||
{ \
|
||||
return ( m_SymbolId == src.m_SymbolId ); \
|
||||
} \
|
||||
const char* typename::String( ) const \
|
||||
{ \
|
||||
return g_##typename##SymbolTable.String( m_SymbolId ); \
|
||||
}
|
||||
|
||||
#endif // UTLSYMBOL_H
|
||||
|
||||
+13
-13
@@ -25,12 +25,12 @@
|
||||
class IFileReadBinary
|
||||
{
|
||||
public:
|
||||
virtual int open( const char *pFileName ) = 0;
|
||||
virtual int read( void *pOutput, int size, int file ) = 0;
|
||||
virtual void close( int file ) = 0;
|
||||
virtual void seek( int file, int pos ) = 0;
|
||||
virtual unsigned int tell( int file ) = 0;
|
||||
virtual unsigned int size( int file ) = 0;
|
||||
virtual intp open( const char *pFileName ) = 0;
|
||||
virtual int read( void *pOutput, int size, intp file ) = 0;
|
||||
virtual void close( intp file ) = 0;
|
||||
virtual void seek( intp file, int pos ) = 0;
|
||||
virtual unsigned int tell( intp file ) = 0;
|
||||
virtual unsigned int size( intp file ) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
const InFileRIFF & operator=( const InFileRIFF & );
|
||||
|
||||
IFileReadBinary &m_io;
|
||||
int m_file;
|
||||
intp m_file;
|
||||
unsigned int m_riffName;
|
||||
unsigned int m_riffSize;
|
||||
};
|
||||
@@ -99,11 +99,11 @@ private:
|
||||
class IFileWriteBinary
|
||||
{
|
||||
public:
|
||||
virtual int create( const char *pFileName ) = 0;
|
||||
virtual int write( void *pData, int size, int file ) = 0;
|
||||
virtual void close( int file ) = 0;
|
||||
virtual void seek( int file, int pos ) = 0;
|
||||
virtual unsigned int tell( int file ) = 0;
|
||||
virtual intp create( const char *pFileName ) = 0;
|
||||
virtual int write( void *pData, int size, intp file ) = 0;
|
||||
virtual void close( intp file ) = 0;
|
||||
virtual void seek( intp file, int pos ) = 0;
|
||||
virtual unsigned int tell( intp file ) = 0;
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to write a RIFF format file
|
||||
@@ -126,7 +126,7 @@ private:
|
||||
const OutFileRIFF & operator=( const OutFileRIFF & );
|
||||
|
||||
IFileWriteBinary &m_io;
|
||||
int m_file;
|
||||
intp m_file;
|
||||
unsigned int m_riffName;
|
||||
unsigned int m_riffSize;
|
||||
unsigned int m_nNamePos;
|
||||
|
||||
@@ -249,7 +249,7 @@ struct TOGL_CLASS IDirect3DQuery9 : public IDirect3DResource9 //was IUnknown
|
||||
GLMContext *m_ctx;
|
||||
CGLMQuery *m_query;
|
||||
|
||||
uint m_nIssueStartThreadID, m_nIssueEndThreadID;
|
||||
uintp m_nIssueStartThreadID, m_nIssueEndThreadID;
|
||||
uint m_nIssueStartDrawCallIndex, m_nIssueEndDrawCallIndex;
|
||||
uint m_nIssueStartFrameIndex, m_nIssueEndFrameIndex;
|
||||
uint m_nIssueStartQueryCreationCounter, m_nIssueEndQueryCreationCounter;
|
||||
@@ -373,7 +373,7 @@ struct RenderTargetState_t
|
||||
|
||||
static inline bool LessFunc( const RenderTargetState_t &lhs, const RenderTargetState_t &rhs )
|
||||
{
|
||||
COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uint32 ) );
|
||||
COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uintp ) );
|
||||
uint64 lhs0 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[0];
|
||||
uint64 rhs0 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[0];
|
||||
if ( lhs0 < rhs0 )
|
||||
@@ -563,7 +563,7 @@ struct TOGL_CLASS IDirect3DDevice9 : public IUnknown
|
||||
|
||||
void TOGLMETHODCALLTYPE AcquireThreadOwnership( );
|
||||
void TOGLMETHODCALLTYPE ReleaseThreadOwnership( );
|
||||
inline DWORD TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; }
|
||||
inline uintp TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; }
|
||||
|
||||
FORCEINLINE void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHint( uint nMaxReg );
|
||||
void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHintNonInline( uint nMaxReg );
|
||||
|
||||
@@ -993,6 +993,7 @@ typedef enum _D3DTEXTUREADDRESS
|
||||
|
||||
typedef enum _D3DSHADEMODE
|
||||
{
|
||||
D3DSHADE_NONE = 0,
|
||||
D3DSHADE_FLAT = 1,
|
||||
D3DSHADE_GOURAUD = 2,
|
||||
D3DSHADE_PHONG = 3,
|
||||
|
||||
@@ -116,6 +116,8 @@ GL_FUNC_VOID(OpenGL,true,glUniform1iARB,(GLint a,GLint b),(a,b))
|
||||
GL_FUNC_VOID(OpenGL,true,glUniform4fv,(GLint a,GLsizei b,const GLfloat *c),(a,b,c))
|
||||
GL_FUNC(OpenGL,true,GLboolean,glUnmapBuffer,(GLenum a),(a))
|
||||
GL_FUNC_VOID(OpenGL,true,glUseProgram,(GLuint a),(a))
|
||||
GL_FUNC_VOID(OpenGL,true,glUseProgramObjectARB,(GLhandleARB a),(a))
|
||||
GL_FUNC_VOID(OpenGL,true,glValidateProgramARB,(GLhandleARB a),(a))
|
||||
GL_FUNC_VOID(OpenGL,true,glVertex3f,(GLfloat a,GLfloat b,GLfloat c),(a,b,c))
|
||||
GL_FUNC_VOID(OpenGL,true,glVertexAttribPointer,(GLuint a,GLint b,GLenum c,GLboolean d,GLsizei e,const GLvoid *f),(a,b,c,d,e,f))
|
||||
GL_FUNC_VOID(OpenGL,true,glViewport,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d))
|
||||
|
||||
@@ -1534,7 +1534,7 @@ class GLMContext
|
||||
#endif
|
||||
|
||||
FORCEINLINE void SetMaxUsedVertexShaderConstantsHint( uint nMaxConstants );
|
||||
FORCEINLINE DWORD GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; }
|
||||
FORCEINLINE uintp GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; }
|
||||
|
||||
protected:
|
||||
friend class GLMgr; // only GLMgr can make GLMContext objects
|
||||
@@ -1663,7 +1663,7 @@ class GLMContext
|
||||
// members------------------------------------------
|
||||
|
||||
// context
|
||||
DWORD m_nCurOwnerThreadId;
|
||||
uintp m_nCurOwnerThreadId;
|
||||
uint m_nThreadOwnershipReleaseCounter;
|
||||
|
||||
bool m_bUseSamplerObjects;
|
||||
@@ -1934,11 +1934,11 @@ FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuin
|
||||
if ( pIndexBuf->m_bPseudo )
|
||||
{
|
||||
// you have to pass actual address, not offset
|
||||
indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_pPseudoBuf );
|
||||
indicesActual = (void*)( (intp)indicesActual + (intp)pIndexBuf->m_pPseudoBuf );
|
||||
}
|
||||
if (pIndexBuf->m_bUsingPersistentBuffer)
|
||||
{
|
||||
indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_nPersistentBufferStartOffset );
|
||||
indicesActual = (void*)( (intp)indicesActual + (intp)pIndexBuf->m_nPersistentBufferStartOffset );
|
||||
}
|
||||
|
||||
//#if GLMDEBUG
|
||||
|
||||
@@ -34,8 +34,12 @@
|
||||
|
||||
#undef PROTECTED_THINGS_ENABLE
|
||||
|
||||
#ifdef OSX
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/platform.h"
|
||||
|
||||
@@ -373,7 +373,7 @@ struct RenderTargetState_t
|
||||
|
||||
static inline bool LessFunc( const RenderTargetState_t &lhs, const RenderTargetState_t &rhs )
|
||||
{
|
||||
COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uint32 ) );
|
||||
COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uintp ) );
|
||||
uint64 lhs0 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[0];
|
||||
uint64 rhs0 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[0];
|
||||
if ( lhs0 < rhs0 )
|
||||
@@ -563,7 +563,7 @@ struct TOGL_CLASS IDirect3DDevice9 : public IUnknown
|
||||
|
||||
void TOGLMETHODCALLTYPE AcquireThreadOwnership( );
|
||||
void TOGLMETHODCALLTYPE ReleaseThreadOwnership( );
|
||||
inline DWORD TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; }
|
||||
inline uintp TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; }
|
||||
|
||||
FORCEINLINE void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHint( uint nMaxReg );
|
||||
void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHintNonInline( uint nMaxReg );
|
||||
|
||||
@@ -993,6 +993,7 @@ typedef enum _D3DTEXTUREADDRESS
|
||||
|
||||
typedef enum _D3DSHADEMODE
|
||||
{
|
||||
D3DSHADE_NONE = 0,
|
||||
D3DSHADE_FLAT = 1,
|
||||
D3DSHADE_GOURAUD = 2,
|
||||
D3DSHADE_PHONG = 3,
|
||||
@@ -1194,7 +1195,7 @@ typedef enum _D3DVERTEXBLENDFLAGS
|
||||
D3DVBF_3WEIGHTS = 3, // 4 matrix blending
|
||||
D3DVBF_TWEENING = 255, // blending using D3DRS_TWEENFACTOR
|
||||
D3DVBF_0WEIGHTS = 256, // one matrix is used with weight 1.0
|
||||
D3DVBF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
|
||||
D3DVBF_FORCE_DWORD = 0xffffffff, // force 32-bit size enum
|
||||
} D3DVERTEXBLENDFLAGS;
|
||||
|
||||
typedef struct _D3DINDEXBUFFER_DESC
|
||||
@@ -1338,6 +1339,7 @@ typedef struct _D3DCAPS9
|
||||
DWORD FakeSRGBWrite; // 1 for parts which can't support SRGB writes due to driver issues - 0 for others
|
||||
DWORD MixedSizeTargets; // 1 for parts which can mix attachment sizes (RT's color vs depth)
|
||||
DWORD CanDoSRGBReadFromRTs; // 0 when we're on Leopard, 1 when on Snow Leopard
|
||||
DWORD SupportInt16Format;
|
||||
} D3DCAPS9;
|
||||
|
||||
typedef struct _D3DDISPLAYMODE
|
||||
@@ -1531,7 +1533,7 @@ typedef enum _D3DTRANSFORMSTATETYPE
|
||||
D3DTS_VIEW = 2,
|
||||
D3DTS_PROJECTION = 3,
|
||||
D3DTS_TEXTURE0 = 16,
|
||||
D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
|
||||
D3DTS_FORCE_DWORD = 0xffffffff, /* force 32-bit size enum */
|
||||
} D3DTRANSFORMSTATETYPE;
|
||||
|
||||
// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
|
||||
|
||||
@@ -38,18 +38,8 @@
|
||||
#include "interface.h"
|
||||
#include "togles/rendermechanism.h"
|
||||
|
||||
#ifdef LINUX
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback=NULL);
|
||||
|
||||
/*
|
||||
#define GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS 1
|
||||
#define GL_TRACK_API_TIME 1
|
||||
#define GL_DUMP_ALL_API_CALLS 1
|
||||
*/
|
||||
|
||||
#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
|
||||
class CGLExecuteHelperBase
|
||||
{
|
||||
@@ -57,7 +47,7 @@ public:
|
||||
inline void StartCall(const char *pName);
|
||||
inline void StopCall(const char *pName);
|
||||
#if GL_TRACK_API_TIME
|
||||
uint64 m_nStartTime;
|
||||
TmU64 m_nStartTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -313,24 +303,30 @@ public:
|
||||
int m_nOpenGLVersionMinor; // if GL_VERSION is 2.1.0, this will be set to 1.
|
||||
int m_nOpenGLVersionPatch; // if GL_VERSION is 2.1.0, this will be set to 0.
|
||||
bool m_bHave_OpenGL;
|
||||
|
||||
|
||||
char *m_pGLDriverStrings[cGLTotalDriverStrings];
|
||||
GLDriverProvider_t m_nDriverProvider;
|
||||
GLDriverProvider_t m_nDriverProvider;
|
||||
|
||||
#ifdef LOAD_HARDFP
|
||||
#define _APIENTRY __attribute__((pcs("aapcs"))) APIENTRY
|
||||
#else
|
||||
#define _APIENTRY APIENTRY
|
||||
#endif
|
||||
|
||||
#ifdef OSX
|
||||
#define GL_EXT(x,glmajor,glminor) bool m_bHave_##x;
|
||||
#define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (*) arg, ret > fn;
|
||||
#define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (*) arg, void > fn;
|
||||
#else
|
||||
#define _APIENTRY __attribute__((pcs("aapcs"))) APIENTRY
|
||||
#define GL_EXT(x,glmajor,glminor) bool m_bHave_##x;
|
||||
#define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (_APIENTRY *) arg, ret > fn;
|
||||
#define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (_APIENTRY *) arg, void > fn;
|
||||
#endif
|
||||
#include "togles/glfuncs.inl"
|
||||
#undef GL_FUNC_VOID
|
||||
#undef GL_FUNC
|
||||
#undef GL_EXT
|
||||
|
||||
#include "togles/glfuncs.inl"
|
||||
#undef GL_FUNC_VOID
|
||||
#undef GL_FUNC
|
||||
#undef GL_EXT
|
||||
|
||||
bool HasSwapTearExtension() const
|
||||
{
|
||||
@@ -358,30 +354,54 @@ typedef void * (*GL_GetProcAddressCallbackFunc_t)(const char *, bool &, const bo
|
||||
DLL_IMPORT void ClearOpenGLEntryPoints();
|
||||
#endif
|
||||
|
||||
inline uint64 get_nsecs()
|
||||
{
|
||||
struct timespec time={0,0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return time.tv_nsec;
|
||||
}
|
||||
|
||||
#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
|
||||
inline void CGLExecuteHelperBase::StartCall(const char *pName)
|
||||
{
|
||||
(void)pName;
|
||||
m_nStartTime = get_nsecs();
|
||||
|
||||
#if GL_TELEMETRY_ZONES
|
||||
tmEnter( TELEMETRY_LEVEL3, TMZF_NONE, pName );
|
||||
#endif
|
||||
|
||||
#if GL_TRACK_API_TIME
|
||||
m_nStartTime = tmFastTime();
|
||||
#endif
|
||||
|
||||
#if GL_DUMP_ALL_API_CALLS
|
||||
static bool s_bDumpCalls;
|
||||
if ( s_bDumpCalls )
|
||||
{
|
||||
char buf[128];
|
||||
buf[0] = 'G';
|
||||
buf[1] = 'L';
|
||||
buf[2] = ':';
|
||||
size_t l = strlen( pName );
|
||||
memcpy( buf + 3, pName, l );
|
||||
buf[3 + l] = '\n';
|
||||
buf[4 + l] = '\0';
|
||||
Plat_DebugString( buf );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void CGLExecuteHelperBase::StopCall(const char *pName)
|
||||
{
|
||||
if( gGL )
|
||||
{
|
||||
uint64 time = get_nsecs() - m_nStartTime;
|
||||
printf("Function %s finished in %llu\n", pName, time);
|
||||
|
||||
if( strcmp(pName, "glBufferSubData") == 0 && time > 1000000 )
|
||||
DebuggerBreak();
|
||||
}
|
||||
{
|
||||
#if GL_TRACK_API_TIME
|
||||
uint64 nTotalCycles = tmFastTime() - m_nStartTime;
|
||||
#endif
|
||||
|
||||
#if GL_TELEMETRY_ZONES
|
||||
tmLeave( TELEMETRY_LEVEL3 );
|
||||
#endif
|
||||
|
||||
#if GL_TRACK_API_TIME
|
||||
//double flMilliseconds = g_Telemetry.flRDTSCToMilliSeconds * nTotalCycles;
|
||||
if (gGL)
|
||||
{
|
||||
gGL->m_nTotalGLCycles += nTotalCycles;
|
||||
gGL->m_nTotalGLCalls++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -249,3 +249,4 @@ GL_FUNC_VOID(OpenGL,true,glSamplerParameterfv,(GLuint a, GLenum b, const GLfloat
|
||||
GL_FUNC_VOID(GL_QCOM_alpha_test,false,glAlphaFuncQCOM,(GLenum a, GLfloat b),(a,b))
|
||||
GL_FUNC_VOID(OpenGL,true,glClearDepthf,(GLfloat a),(a))
|
||||
GL_FUNC_VOID(OpenGL,true,glDepthRangef,(GLfloat a,GLfloat b),(a,b))
|
||||
GL_FUNC_VOID(OpenGL,true,glGetFramebufferAttachmentParameteriv,(GLenum a,GLenum b,GLenum c,GLint *d),(a,b,c,d))
|
||||
|
||||
@@ -731,16 +731,16 @@ FORCEINLINE void GLContextSet( GLBlendEnableSRGB_t *src )
|
||||
}
|
||||
#endif
|
||||
// this query is not useful unless you have the ARB_framebuffer_srgb ext.
|
||||
//GLint encoding = 0;
|
||||
//pfnglGetFramebufferAttachmentParameteriv( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encoding );
|
||||
// GLint encoding = 0;
|
||||
// gGL->glGetFramebufferAttachmentParameteriv( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encoding );
|
||||
|
||||
glSetEnable( GL_FRAMEBUFFER_SRGB_EXT, src->enable != 0 );
|
||||
}
|
||||
|
||||
FORCEINLINE void GLContextGet( GLBlendEnableSRGB_t *dst )
|
||||
{
|
||||
dst->enable = gGL->glIsEnabled( GL_FRAMEBUFFER_SRGB_EXT );
|
||||
// dst->enable = true; // wtf ?
|
||||
// dst->enable = gGL->glIsEnabled( GL_FRAMEBUFFER_SRGB_EXT );
|
||||
dst->enable = true; // wtf ?
|
||||
}
|
||||
|
||||
FORCEINLINE void GLContextGetDefault( GLBlendEnableSRGB_t *dst )
|
||||
@@ -1448,7 +1448,7 @@ class GLMContext
|
||||
#endif
|
||||
|
||||
FORCEINLINE void SetMaxUsedVertexShaderConstantsHint( uint nMaxConstants );
|
||||
FORCEINLINE DWORD GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; }
|
||||
FORCEINLINE uintp GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; }
|
||||
|
||||
protected:
|
||||
friend class GLMgr; // only GLMgr can make GLMContext objects
|
||||
@@ -1573,7 +1573,7 @@ class GLMContext
|
||||
// members------------------------------------------
|
||||
|
||||
// context
|
||||
DWORD m_nCurOwnerThreadId;
|
||||
uintp m_nCurOwnerThreadId;
|
||||
uint m_nThreadOwnershipReleaseCounter;
|
||||
|
||||
bool m_bUseSamplerObjects;
|
||||
@@ -1838,11 +1838,11 @@ FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuin
|
||||
if ( pIndexBuf->m_bPseudo )
|
||||
{
|
||||
// you have to pass actual address, not offset
|
||||
indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_pPseudoBuf );
|
||||
indicesActual = (void*)( (intp)indicesActual + (intp)pIndexBuf->m_pPseudoBuf );
|
||||
}
|
||||
if (pIndexBuf->m_bUsingPersistentBuffer)
|
||||
{
|
||||
indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_nPersistentBufferStartOffset );
|
||||
indicesActual = (void*)( (intp)indicesActual + (intp)pIndexBuf->m_nPersistentBufferStartOffset );
|
||||
}
|
||||
|
||||
//#if GLMDEBUG
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
|
||||
#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB)
|
||||
|
||||
#ifdef OSX
|
||||
#include <malloc/malloc.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "vallocator.h"
|
||||
#include "basetypes.h"
|
||||
|
||||
|
||||
+12
-2
@@ -14,6 +14,8 @@
|
||||
|
||||
#define null 0L
|
||||
|
||||
#define NeedProportional() (IsAndroid() || CommandLine()->CheckParm("-gameuiproportionality"))
|
||||
|
||||
#ifndef NULL
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
@@ -37,6 +39,14 @@ typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
#ifdef PLATFORM_64BITS
|
||||
typedef long long intp;
|
||||
typedef unsigned long long uintp;
|
||||
#else
|
||||
typedef int intp;
|
||||
typedef unsigned int uintp;
|
||||
#endif
|
||||
|
||||
#ifndef _WCHAR_T_DEFINED
|
||||
// DAL - wchar_t is a built in define in gcc 3.2 with a size of 4 bytes
|
||||
#if !defined( __x86_64__ ) && !defined( __WCHAR_TYPE__ )
|
||||
@@ -52,7 +62,7 @@ namespace vgui
|
||||
{
|
||||
// handle to an internal vgui panel
|
||||
// this is the only handle to a panel that is valid across dll boundaries
|
||||
typedef unsigned int VPANEL;
|
||||
typedef uintp VPANEL;
|
||||
|
||||
// handles to vgui objects
|
||||
// NULL values signify an invalid value
|
||||
@@ -61,7 +71,7 @@ typedef unsigned long HScheme;
|
||||
typedef unsigned long HTexture;
|
||||
typedef unsigned long HCursor;
|
||||
typedef unsigned long HPanel;
|
||||
const HPanel INVALID_PANEL = 0xffffffff;
|
||||
const HPanel INVALID_PANEL = (HPanel)-1;
|
||||
typedef unsigned long HFont;
|
||||
const HFont INVALID_FONT = 0; // the value of an invalid font handle
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class BuildGroup
|
||||
|
||||
public:
|
||||
BuildGroup(Panel *parentPanel, Panel *contextPanel);
|
||||
~BuildGroup();
|
||||
virtual ~BuildGroup();
|
||||
|
||||
// Toggle build mode on/off
|
||||
virtual void SetEnabled(bool state);
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
}
|
||||
|
||||
KeyValues *kv;
|
||||
unsigned int userData;
|
||||
uintp userData;
|
||||
KeyValues *m_pDragData;
|
||||
bool m_bImage;
|
||||
int m_nImageIndex;
|
||||
@@ -115,17 +115,17 @@ public:
|
||||
// DATA HANDLING
|
||||
// data->GetName() is used to uniquely identify an item
|
||||
// data sub items are matched against column header name to be used in the table
|
||||
virtual int AddItem(const KeyValues *data, unsigned int userData, bool bScrollToItem, bool bSortOnAdd); // Takes a copy of the data for use in the table. Returns the index the item is at.
|
||||
virtual int AddItem(const KeyValues *data, uintp userData, bool bScrollToItem, bool bSortOnAdd); // Takes a copy of the data for use in the table. Returns the index the item is at.
|
||||
void SetItemDragData( int itemID, const KeyValues *data ); // Makes a copy of the keyvalues to store in the table. Used when dragging from the table. Only used if the caller enables drag support
|
||||
virtual int GetItemCount( void ); // returns the number of VISIBLE items
|
||||
virtual int GetItem(const char *itemName); // gets the row index of an item by name (data->GetName())
|
||||
virtual KeyValues *GetItem(int itemID); // returns pointer to data the row holds
|
||||
virtual int GetItemCurrentRow(int itemID); // returns -1 if invalid index or item not visible
|
||||
virtual int GetItemIDFromRow(int currentRow); // returns -1 if invalid row
|
||||
virtual unsigned int GetItemUserData(int itemID);
|
||||
virtual uintp GetItemUserData(int itemID);
|
||||
virtual ListPanelItem *GetItemData(int itemID);
|
||||
virtual void SetUserData( int itemID, unsigned int userData );
|
||||
virtual int GetItemIDFromUserData( unsigned int userData );
|
||||
virtual void SetUserData( int itemID, uintp userData );
|
||||
virtual int GetItemIDFromUserData( uintp userData );
|
||||
virtual void ApplyItemChanges(int itemID); // applies any changes to the data, performed by modifying the return of GetItem() above
|
||||
virtual void RemoveItem(int itemID); // removes an item from the table (changing the indices of all following items)
|
||||
virtual void RereadAllItems(); // updates the view with the new data
|
||||
|
||||
@@ -295,8 +295,8 @@ protected:
|
||||
|
||||
void SetCurrentlySelectedItem(MenuItem *item);
|
||||
void SetCurrentlySelectedItem(int itemID);
|
||||
MESSAGE_FUNC_INT( OnCursorEnteredMenuItem, "CursorEnteredMenuItem", VPanel);
|
||||
MESSAGE_FUNC_INT( OnCursorExitedMenuItem, "CursorExitedMenuItem", VPanel);
|
||||
MESSAGE_FUNC_HANDLE( OnCursorEnteredMenuItem, "CursorEnteredMenuItem", menuItem);
|
||||
MESSAGE_FUNC_HANDLE( OnCursorExitedMenuItem, "CursorExitedMenuItem", menuItem);
|
||||
|
||||
void MoveAlongMenuItemList(int direction, int loopCount);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class __virtual_inheritance Panel;
|
||||
#else
|
||||
class Panel;
|
||||
#endif
|
||||
typedef unsigned int VPANEL;
|
||||
typedef uintp VPANEL;
|
||||
|
||||
typedef void (Panel::*MessageFunc_t)(void);
|
||||
|
||||
@@ -222,6 +222,7 @@ public: \
|
||||
#define MESSAGE_FUNC_PTR_WCHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_CONSTWCHARPTR, #p2 ); virtual void name( vgui::Panel *p1, const wchar_t *p2 )
|
||||
#define MESSAGE_FUNC_HANDLE_WCHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_CONSTWCHARPTR, #p2 ); virtual void name( vgui::VPANEL p1, const wchar_t *p2 )
|
||||
#define MESSAGE_FUNC_CHARPTR_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_CONSTCHARPTR, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( const char *p1, const char *p2 )
|
||||
#define MESSAGE_FUNC_HANDLE_HANDLE( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_HANDLE, #p2 ); virtual void name( vgui::VPANEL p1, vgui::VPANEL p2 )
|
||||
|
||||
// unlimited parameters (passed in the whole KeyValues)
|
||||
#define MESSAGE_FUNC_PARAMS( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_KEYVALUES, NULL, 0, 0 ); virtual void name( KeyValues *p1 )
|
||||
|
||||
@@ -27,16 +27,21 @@ class PHandle
|
||||
public:
|
||||
PHandle() : m_iPanelID(INVALID_PANEL) {} //m_iSerialNumber(0), m_pListEntry(0) {}
|
||||
|
||||
Panel *Get();
|
||||
Panel *Get() const;
|
||||
Panel *Set( Panel *pPanel );
|
||||
Panel *Set( HPanel hPanel );
|
||||
|
||||
operator Panel *() { return Get(); }
|
||||
operator Panel *() const { return Get(); }
|
||||
Panel * operator ->() { return Get(); }
|
||||
Panel * operator = (Panel *pPanel) { return Set(pPanel); }
|
||||
|
||||
bool operator == (Panel *pPanel) { return (Get() == pPanel); }
|
||||
operator bool () { return Get() != 0; }
|
||||
//bool operator == (Panel *pPanel) { return (Get() == pPanel); }
|
||||
operator bool () const { return Get() != 0; }
|
||||
|
||||
friend bool operator == ( const PHandle &p1, const PHandle &p2 )
|
||||
{
|
||||
return p1.m_iPanelID == p2.m_iPanelID;
|
||||
}
|
||||
|
||||
private:
|
||||
HPanel m_iPanelID;
|
||||
|
||||
@@ -673,7 +673,7 @@ protected:
|
||||
protected:
|
||||
virtual void OnChildSettingsApplied( KeyValues *pInResourceData, Panel *pChild );
|
||||
|
||||
MESSAGE_FUNC_ENUM_ENUM( OnRequestFocus, "OnRequestFocus", VPANEL, subFocus, VPANEL, defaultPanel);
|
||||
MESSAGE_FUNC_HANDLE_HANDLE( OnRequestFocus, "OnRequestFocus", subFocus, defaultPanel);
|
||||
MESSAGE_FUNC_INT_INT( OnScreenSizeChanged, "OnScreenSizeChanged", oldwide, oldtall );
|
||||
virtual void *QueryInterface(EInterfaceID id);
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#include "vstdlib/vstdlib.h"
|
||||
|
||||
// handle to a KeyValues key name symbol
|
||||
typedef int HKeySymbol;
|
||||
#define INVALID_KEY_SYMBOL (-1)
|
||||
typedef intp HKeySymbol;
|
||||
#define INVALID_KEY_SYMBOL (HKeySymbol)(-1)
|
||||
|
||||
class IBaseFileSystem;
|
||||
class KeyValues;
|
||||
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
// and execute or execute pFunctor right after completing current job and
|
||||
// before looking for another job.
|
||||
//-----------------------------------------------------
|
||||
virtual void ExecuteHighPriorityFunctor( CFunctor *pFunctor ) = 0;
|
||||
// virtual void ExecuteHighPriorityFunctor( CFunctor *pFunctor ) = 0;
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Add an function object to the queue (master thread)
|
||||
@@ -1147,7 +1147,7 @@ private:
|
||||
// Raw thread launching
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline unsigned FunctorExecuteThread( void *pParam )
|
||||
inline uintp FunctorExecuteThread( void *pParam )
|
||||
{
|
||||
CFunctor *pFunctor = (CFunctor *)pParam;
|
||||
(*pFunctor)();
|
||||
@@ -1162,7 +1162,7 @@ inline ThreadHandle_t ThreadExecuteSoloImpl( CFunctor *pFunctor, const char *psz
|
||||
hThread = CreateSimpleThread( FunctorExecuteThread, pFunctor, &threadId );
|
||||
if ( pszName )
|
||||
{
|
||||
ThreadSetDebugName( threadId, pszName );
|
||||
ThreadSetDebugName( (ThreadHandle_t)threadId, pszName );
|
||||
}
|
||||
return hThread;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,11 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#ifdef OSX
|
||||
#include <malloc/malloc.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <memory.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
@@ -1569,7 +1569,7 @@ void CZipFile::SaveDirectory( IWriteStream& stream )
|
||||
free( e->m_pData );
|
||||
|
||||
// temp hackery for the logic below to succeed
|
||||
e->m_pData = (void*)0xFFFFFFFF;
|
||||
e->m_pData = (void*)-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user