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

54
public/BitmapFontFile.h Normal file
View File

@@ -0,0 +1,54 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======
//
// Baked Bitmap fonts
//
//===========================================================================
#ifndef _BITMAPFONTFILE_H_
#define _BITMAPFONTFILE_H_
#include "datamap.h"
#define BITMAPFONT_ID (('T'<<24)|('N'<<16)|('F'<<8)|('V'))
#define BITMAPFONT_VERSION 3
// style flags
#define BF_BOLD 0x0001
#define BF_ITALIC 0x0002
#define BF_OUTLINED 0x0004
#define BF_DROPSHADOW 0x0008
#define BF_BLURRED 0x0010
#define BF_SCANLINES 0x0020
#define BF_ANTIALIASED 0x0040
#define BF_CUSTOM 0x0080
#pragma pack(1) //X360TBD
typedef struct BitmapGlyph_s
{
DECLARE_BYTESWAP_DATADESC();
short x;
short y;
short w;
short h;
short a;
short b;
short c;
} BitmapGlyph_t;
typedef struct BitmapFont_s
{
DECLARE_BYTESWAP_DATADESC();
int m_id;
int m_Version;
short m_PageWidth;
short m_PageHeight;
short m_MaxCharWidth;
short m_MaxCharHeight;
short m_Flags;
short m_Ascent;
short m_NumGlyphs;
unsigned char m_TranslateTable[256];
} BitmapFont_t;
#pragma pack()
#endif

30
public/IGameUIFuncs.h Normal file
View File

@@ -0,0 +1,30 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef IGAMEUIFUNCS_H
#define IGAMEUIFUNCS_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui/KeyCode.h"
abstract_class IGameUIFuncs
{
public:
virtual bool IsKeyDown( const char *keyname, bool& isdown ) = 0;
virtual const char *GetBindingForButtonCode( ButtonCode_t code ) = 0;
virtual ButtonCode_t GetButtonCodeForBind( const char *pBind, int userId = -1 ) = 0;
virtual void GetVideoModes( struct vmode_s **liststart, int *count ) = 0;
virtual void SetFriendsID( uint friendsID, const char *friendsName ) = 0;
virtual void GetDesktopResolution( int &width, int &height ) = 0;
virtual bool IsConnectedToVACSecureServer() = 0;
};
#define VENGINE_GAMEUIFUNCS_VERSION "VENGINE_GAMEUIFUNCS_VERSION005"
#endif // IGAMEUIFUNCS_H

69
public/IHammer.h Normal file
View File

@@ -0,0 +1,69 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: The application object.
//
//=============================================================================//
#ifndef IHAMMER_H
#define IHAMMER_H
#include "appframework/iappsystem.h"
typedef struct tagMSG MSG;
class IStudioDataCache;
//-----------------------------------------------------------------------------
// Return values for RequestNewConfig
//-----------------------------------------------------------------------------
enum RequestRetval_t
{
REQUEST_OK = 0,
REQUEST_QUIT
};
//-----------------------------------------------------------------------------
// Interface used to drive hammer
//-----------------------------------------------------------------------------
#define INTERFACEVERSION_HAMMER "Hammer001"
class IHammer : public IAppSystem
{
public:
virtual bool HammerPreTranslateMessage( MSG * pMsg ) = 0;
virtual bool HammerIsIdleMessage( MSG * pMsg ) = 0;
virtual bool HammerOnIdle( long count ) = 0;
virtual void RunFrame() = 0;
// Returns the mod and the game to initially start up
virtual const char *GetDefaultMod() = 0;
virtual const char *GetDefaultGame() = 0;
virtual bool InitSessionGameConfig( const char *szGameDir ) = 0;
// Request a new config from hammer's config system
virtual RequestRetval_t RequestNewConfig() = 0;
// Returns the full path to the mod and the game to initially start up
virtual const char *GetDefaultModFullPath() = 0;
virtual int MainLoop() = 0;
// When Foundry is using Hammer:
// - Hammer doesn't create its main window.
// - Select windows (like the object properties dialog) are parented to the game's window and share its message pump
// - A CMapView3D is created and renders only entities on top of the game's 3D window
virtual void InitFoundryMode( CreateInterfaceFn factory, void *hGameWnd, const char *szGameDir ) = 0;
// Called when the engine's window took the focus.
virtual void NoteEngineGotFocus() = 0;
// Used in Foundry to show and hide the full Hammer UI.
virtual bool IsHammerVisible() = 0;
virtual void ToggleHammerVisible() = 0;
};
#endif // IHAMMER_H

29
public/OfflineMode.h Normal file
View File

@@ -0,0 +1,29 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <vgui/ISystem.h>
#include <vgui_controls/Controls.h>
#define STEAM_OFFLINE_MODE "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\Offline"
#define STEAM_AFS_MODE "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\OfflineAFS"
#define OFFLINE_FILE "Steam\\cached\\offline_" // first part of filename
inline bool IsSteamInOfflineMode()
{
int offline = 0;
vgui::system()->GetRegistryInteger( STEAM_OFFLINE_MODE, offline );
return ( offline == 1 );
}inline bool IsSteamInAuthenticationFailSafeMode()
{
int offline = 0;
vgui::system()->GetRegistryInteger( STEAM_AFS_MODE, offline );
return ( offline == 1 );
}
inline bool IsSteamGameServerBrowsingEnabled()
{
return (IsSteamInAuthenticationFailSafeMode() || !IsSteamInOfflineMode());
}

65
public/PlayerState.h Normal file
View File

@@ -0,0 +1,65 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef PLAYERSTATE_H
#define PLAYERSTATE_H
#ifdef _WIN32
#pragma once
#endif
#include "edict.h"
#include "networkvar.h"
// Only care about this stuff in game/client .dlls
#if defined( CLIENT_DLL )
#include "predictable_entity.h"
#endif
class CPlayerState
{
public:
DECLARE_CLASS_NOBASE( CPlayerState );
DECLARE_EMBEDDED_NETWORKVAR();
// This virtual method is necessary to generate a vtable in all cases
// (DECLARE_PREDICTABLE will generate a vtable also)!
virtual ~CPlayerState() {}
// true if the player is dead
CNetworkVar( bool, deadflag );
// Viewing angle (player only)
QAngle v_angle;
// The client .dll only cares about deadflag
// the game and engine .dlls need to worry about the rest of this data
#if !defined( CLIENT_DLL )
// Player's network name
string_t netname;
// 0:nothing, 1:force view angles, 2:add avelocity
int fixangle;
// delta angle for fixangle == FIXANGLE_RELATIVE
QAngle anglechange;
// flag to single the HLTV/Replay fake client, not transmitted
bool hltv;
bool replay;
int frags;
int assists;
int deaths;
int score;
#endif
// NOTE: Only care about this stuff in game/client dlls
// Put at end in case it has any effect on size of structure
#if defined( GAME_DLL )
DECLARE_SIMPLE_DATADESC();
#endif
#if defined( CLIENT_DLL )
DECLARE_PREDICTABLE();
#endif
};
#endif // PLAYERSTATE_H

467
public/ScratchPadUtils.cpp Normal file
View File

@@ -0,0 +1,467 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB)
#include "iscratchpad3d.h"
#include "mathlib/mathlib.h"
#include "ScratchPadUtils.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// --------------------------------------------------------------------------------------------------------------------- //
// CScratchPadGraph implementation.
// --------------------------------------------------------------------------------------------------------------------- //
CScratchPadGraph::CScratchPadGraph()
{
m_pPad = NULL;
}
void CScratchPadGraph::Init(
IScratchPad3D *pPad,
Vector vTimeAxis,
float flInchesPerSecond,
Vector vTimeLineColor,
float flTimeOrigin,
float flTimeLabelEveryNSeconds,
Vector vValueAxis,
float flInchesPerValue,
Vector vValueLineColor,
float flValueOrigin
)
{
m_pPad = pPad;
m_vTimeAxis = vTimeAxis;
m_flInchesPerSecond = flInchesPerSecond;
m_vValueAxis = vValueAxis;
m_flInchesPerValue = flInchesPerValue;
m_flTimeLabelEveryNSeconds = flTimeLabelEveryNSeconds;
m_vTimeLineColor = vTimeLineColor;
m_vValueLineColor = vValueLineColor;
m_flTimeOrigin = flTimeOrigin;
m_flValueOrigin = flValueOrigin;
m_nTimeLabelsDrawn = 0;
m_flHighestTime = flTimeOrigin;
m_flHighestValue = flValueOrigin;
}
bool CScratchPadGraph::IsInitted() const
{
return m_pPad != NULL;
}
CScratchPadGraph::LineID CScratchPadGraph::AddLine( Vector vColor )
{
CScratchPadGraph::CLineInfo info;
info.m_bFirst = true;
info.m_vColor = vColor;
return m_LineInfos.AddToTail( info );
}
void CScratchPadGraph::AddSample( LineID iLine, float flTime, float flValue )
{
CScratchPadGraph::CLineInfo *pInfo = &m_LineInfos[iLine];
UpdateTicksAndStuff( flTime, flValue );
if ( !pInfo->m_bFirst )
{
// Draw a line from the last value to the current one.
Vector vStart = GetSamplePosition( pInfo->m_flLastTime, pInfo->m_flLastValue );
Vector vEnd = GetSamplePosition( flTime, flValue );
m_pPad->DrawLine(
CSPVert( vStart, pInfo->m_vColor ),
CSPVert( vEnd, pInfo->m_vColor )
);
}
pInfo->m_flLastTime = flTime;
pInfo->m_flLastValue = flValue;
pInfo->m_bFirst = false;
}
void CScratchPadGraph::AddVerticalLine( float flTime, float flMinValue, float flMaxValue, const CSPColor &vColor )
{
Vector v1 = GetSamplePosition( flTime, flMinValue );
Vector v2 = GetSamplePosition( flTime, flMaxValue );
m_pPad->DrawLine(
CSPVert( v1, vColor ),
CSPVert( v2, vColor ) );
}
void CScratchPadGraph::UpdateTicksAndStuff( float flTime, float flValue )
{
if ( flTime > m_flHighestTime )
{
// Update the left part of the time axis.
Vector vStart = GetSamplePosition( m_flHighestTime, m_flValueOrigin );
Vector vEnd = GetSamplePosition( flTime, m_flValueOrigin );
m_pPad->DrawLine(
CSPVert( vStart, m_vTimeLineColor ),
CSPVert( vEnd, m_vTimeLineColor )
);
m_flHighestTime = flTime;
}
if ( flValue > m_flHighestValue )
{
// Update the left part of the time axis.
Vector vStart = GetSamplePosition( m_flTimeOrigin, m_flHighestValue );
Vector vEnd = GetSamplePosition( m_flTimeOrigin, flValue );
m_pPad->DrawLine(
CSPVert( vStart, m_vValueLineColor ),
CSPVert( vEnd, m_vValueLineColor )
);
// Extend the lines attached to the time labels.
for ( int i=0; i < m_nTimeLabelsDrawn; i++ )
{
float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds;
m_pPad->DrawLine(
CSPVert((const Vector&) GetSamplePosition( flTime, m_flHighestValue )),
CSPVert((const Vector&) GetSamplePosition( flTime, flValue ) )
);
}
m_flHighestValue = flValue;
}
// More text labels?
int iHighestTextLabel = (int)ceil( (flTime - m_flTimeOrigin) / m_flTimeLabelEveryNSeconds + 0.5f );
while ( m_nTimeLabelsDrawn < iHighestTextLabel )
{
CTextParams params;
float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds;
params.m_bSolidBackground = true;
params.m_vPos = GetSamplePosition( flTime, m_flValueOrigin-5 );
params.m_bTwoSided = true;
char str[512];
Q_snprintf( str, sizeof( str ), "time: %.2f", flTime );
m_pPad->DrawText( str, params );
// Now draw the vertical line for the value..
m_pPad->DrawLine(
CSPVert( (const Vector&)GetSamplePosition( flTime, m_flValueOrigin ) ),
CSPVert( (const Vector&)GetSamplePosition( flTime, m_flHighestValue ) )
);
m_nTimeLabelsDrawn++;
}
}
Vector CScratchPadGraph::GetSamplePosition( float flTime, float flValue )
{
Vector vRet =
m_vTimeAxis * ((flTime - m_flTimeOrigin) * m_flInchesPerSecond) +
m_vValueAxis * ((flValue - m_flValueOrigin) * m_flInchesPerValue);
return vRet;
}
// --------------------------------------------------------------------------------------------------------------------- //
// Global functions.
// --------------------------------------------------------------------------------------------------------------------- //
void ScratchPad_DrawLitCone(
IScratchPad3D *pPad,
const Vector &vBaseCenter,
const Vector &vTip,
const Vector &vBrightColor,
const Vector &vDarkColor,
const Vector &vLightDir,
float baseWidth,
int nSegments )
{
// Make orthogonal vectors.
Vector vDir = vTip - vBaseCenter;
VectorNormalize( vDir );
Vector vRight, vUp;
VectorVectors( vDir, vRight, vUp );
vRight *= baseWidth;
vUp *= baseWidth;
// Setup the top and bottom caps.
CSPVertList bottomCap, tri;
bottomCap.m_Verts.SetSize( nSegments );
tri.m_Verts.SetSize( 3 );
float flDot = -vLightDir.Dot( vDir );
Vector topColor, bottomColor;
VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor );
// Draw each quad.
Vector vPrevBottom = vBaseCenter + vRight;
for ( int i=0; i < nSegments; i++ )
{
float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments;
Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle );
Vector vCurBottom = vBaseCenter + vOffset;
const Vector &v1 = vTip;
const Vector &v2 = vPrevBottom;
const Vector &v3 = vCurBottom;
Vector vFaceNormal = (v2 - v1).Cross( v3 - v1 );
VectorNormalize( vFaceNormal );
// Now light it.
flDot = -vLightDir.Dot( vFaceNormal );
Vector vColor;
VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor );
// Draw the quad.
tri.m_Verts[0] = CSPVert( v1, vColor );
tri.m_Verts[1] = CSPVert( v2, vColor );
tri.m_Verts[2] = CSPVert( v3, vColor );
pPad->DrawPolygon( tri );
bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor );
}
pPad->DrawPolygon( bottomCap );
}
void ScratchPad_DrawLitCylinder(
IScratchPad3D *pPad,
const Vector &v1,
const Vector &v2,
const Vector &vBrightColor,
const Vector &vDarkColor,
const Vector &vLightDir,
float width,
int nSegments )
{
// Make orthogonal vectors.
Vector vDir = v2 - v1;
VectorNormalize( vDir );
Vector vRight, vUp;
VectorVectors( vDir, vRight, vUp );
vRight *= width;
vUp *= width;
// Setup the top and bottom caps.
CSPVertList topCap, bottomCap, quad;
topCap.m_Verts.SetSize( nSegments );
bottomCap.m_Verts.SetSize( nSegments );
quad.m_Verts.SetSize( 4 );
float flDot = -vLightDir.Dot( vDir );
Vector topColor, bottomColor;
VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), topColor );
VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor );
// Draw each quad.
Vector vPrevTop = v1 + vRight;
Vector vPrevBottom = v2 + vRight;
for ( int i=0; i < nSegments; i++ )
{
float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments;
Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle );
Vector vCurTop = v1 + vOffset;
Vector vCurBottom = v2 + vOffset;
// Now light it.
VectorNormalize( vOffset );
flDot = -vLightDir.Dot( vOffset );
Vector vColor;
VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor );
// Draw the quad.
quad.m_Verts[0] = CSPVert( vPrevTop, vColor );
quad.m_Verts[1] = CSPVert( vPrevBottom, vColor );
quad.m_Verts[2] = CSPVert( vCurBottom, vColor );
quad.m_Verts[3] = CSPVert( vCurTop, vColor );
pPad->DrawPolygon( quad );
topCap.m_Verts[i] = CSPVert( vCurTop, topColor );
bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor );
}
pPad->DrawPolygon( topCap );
pPad->DrawPolygon( bottomCap );
}
void ScratchPad_DrawArrow(
IScratchPad3D *pPad,
const Vector &vPos,
const Vector &vDirection,
const Vector &vColor,
float flLength,
float flLineWidth,
float flHeadWidth,
int nCylinderSegments,
int nHeadSegments,
float flArrowHeadPercentage
)
{
Vector vNormDir = vDirection;
VectorNormalize( vNormDir );
Vector vConeBase = vPos + vNormDir * (flLength * ( 1 - flArrowHeadPercentage ) );
Vector vConeEnd = vPos + vNormDir * flLength;
Vector vLightDir( -1, -1, -1 );
VectorNormalize( vLightDir ); // could precalculate this
pPad->SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Solid );
pPad->SetRenderState( IScratchPad3D::RS_ZRead, true );
ScratchPad_DrawLitCylinder( pPad, vPos, vConeBase, vColor, vColor*0.25f, vLightDir, flLineWidth, nCylinderSegments );
ScratchPad_DrawLitCone( pPad, vConeBase, vConeEnd, vColor, vColor*0.25f, vLightDir, flHeadWidth, nHeadSegments );
}
void ScratchPad_DrawArrowSimple(
IScratchPad3D *pPad,
const Vector &vPos,
const Vector &vDirection,
const Vector &vColor,
float flLength )
{
ScratchPad_DrawArrow(
pPad,
vPos,
vDirection,
vColor,
flLength,
flLength * 1.0/15,
flLength * 3.0/15,
4,
4 );
}
void ScratchPad_DrawSphere(
IScratchPad3D *pPad,
const Vector &vCenter,
float flRadius,
const Vector &vColor,
int nSubDivs )
{
CUtlVector<Vector> prevPoints;
prevPoints.SetSize( nSubDivs );
// For each vertical slice.. (the top and bottom ones are just a single point).
for ( int iSlice=0; iSlice < nSubDivs; iSlice++ )
{
float flHalfSliceAngle = M_PI * (float)iSlice / (nSubDivs - 1);
if ( iSlice == 0 )
{
prevPoints[0] = vCenter + Vector( 0, 0, flRadius );
for ( int z=1; z < prevPoints.Count(); z++ )
prevPoints[z] = prevPoints[0];
}
else
{
for ( int iSubPt=0; iSubPt < nSubDivs; iSubPt++ )
{
float flHalfAngle = M_PI * (float)iSubPt / (nSubDivs - 1);
float flAngle = flHalfAngle * 2;
Vector pt;
if ( iSlice == (nSubDivs - 1) )
{
pt = vCenter - Vector( 0, 0, flRadius );
}
else
{
pt.x = cos( flAngle ) * sin( flHalfSliceAngle );
pt.y = sin( flAngle ) * sin( flHalfSliceAngle );
pt.z = cos( flHalfSliceAngle );
pt *= flRadius;
pt += vCenter;
}
pPad->DrawLine( CSPVert( pt, vColor ), CSPVert( prevPoints[iSubPt], vColor ) );
prevPoints[iSubPt] = pt;
}
if ( iSlice != (nSubDivs - 1) )
{
for ( int i=0; i < nSubDivs; i++ )
pPad->DrawLine( CSPVert( prevPoints[i], vColor ), CSPVert( prevPoints[(i+1)%nSubDivs], vColor ) );
}
}
}
}
void ScratchPad_DrawAABB(
IScratchPad3D *pPad,
const Vector &vMins,
const Vector &vMaxs,
const Vector &vColor )
{
int vertOrder[4][2] = {{0,0},{1,0},{1,1},{0,1}};
const Vector *vecs[2] = {&vMins, &vMaxs};
Vector vTop, vBottom, vPrevTop, vPrevBottom;
vTop.z = vPrevTop.z = vMaxs.z;
vBottom.z = vPrevBottom.z = vMins.z;
vPrevTop.x = vPrevBottom.x = vecs[vertOrder[3][0]]->x;
vPrevTop.y = vPrevBottom.y = vecs[vertOrder[3][1]]->y;
for ( int i=0; i < 4; i++ )
{
vTop.x = vBottom.x = vecs[vertOrder[i][0]]->x;
vTop.y = vBottom.y = vecs[vertOrder[i][1]]->y;
// Draw the top line.
pPad->DrawLine( CSPVert( vPrevTop, vColor ), CSPVert( vTop, vColor ) );
pPad->DrawLine( CSPVert( vPrevBottom, vColor ), CSPVert( vBottom, vColor ) );
pPad->DrawLine( CSPVert( vTop, vColor ), CSPVert( vBottom, vColor ) );
vPrevTop = vTop;
vPrevBottom = vBottom;
}
}
#endif // !_STATIC_LINKED || _SHARED_LIB

163
public/ScratchPadUtils.h Normal file
View File

@@ -0,0 +1,163 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This module contains helper functions for use with scratch pads.
//
// $NoKeywords: $
//=============================================================================//
#ifndef SCRATCHPADUTILS_H
#define SCRATCHPADUTILS_H
#ifdef _WIN32
#pragma once
#endif
#include "iscratchpad3d.h"
// Use this to make a graph.
class CScratchPadGraph
{
public:
typedef int LineID;
CScratchPadGraph();
// Initialze the orientation and scales of the two axes.
// Axis indices are 0, 1, or 2 for x, y, and z.
void Init(
IScratchPad3D *pPad,
Vector vTimeAxis = Vector(0,-1,0),
float flInchesPerSecond=1,
Vector vTimeLineColor=Vector(0,0,1),
float flTimeOrigin=0, // Where the origin of the graph is.
float flTimeLabelEveryNSeconds=1,
Vector vValueAxis = Vector(0,0,1),
float flInchesPerValue=1,
Vector vValueLineColor=Vector(1,0,0),
float flValueOrigin=0 // Where the origin of the graph is.
);
bool IsInitted() const;
// Add another line into the graph.
LineID AddLine( Vector vColor );
void AddSample( LineID iLine, float flTime, float flValue );
void AddVerticalLine( float flTime, float flMinValue, float flMaxValue, const CSPColor &vColor );
// Get the 3D position of a sample on the graph (so you can draw other things there).
Vector GetSamplePosition( float flTime, float flValue );
private:
void UpdateTicksAndStuff( float flTime, float flValue );
private:
class CLineInfo
{
public:
bool m_bFirst;
float m_flLastTime;
float m_flLastValue;
Vector m_vColor;
};
IScratchPad3D *m_pPad;
CUtlVector<CLineInfo> m_LineInfos;
Vector m_vTimeAxis;
float m_flInchesPerSecond;
Vector m_vValueAxis;
float m_flInchesPerValue;
// How often to make a time label.
float m_flTimeLabelEveryNSeconds;
int m_nTimeLabelsDrawn;
Vector m_vTimeLineColor;
Vector m_vValueLineColor;
float m_flTimeOrigin;
float m_flValueOrigin;
// Used to extend the value border.
float m_flHighestValue;
float m_flHighestTime;
};
// Draw a cone.
void ScratchPad_DrawLitCone(
IScratchPad3D *pPad,
const Vector &vBaseCenter,
const Vector &vTip,
const Vector &vBrightColor,
const Vector &vDarkColor,
const Vector &vLightDir,
float baseWidth,
int nSegments );
// Draw a cylinder.
void ScratchPad_DrawLitCylinder(
IScratchPad3D *pPad,
const Vector &v1,
const Vector &v2,
const Vector &vBrightColor,
const Vector &vDarkColor,
const Vector &vLightDir,
float width,
int nSegments );
// Draw an arrow.
void ScratchPad_DrawArrow(
IScratchPad3D *pPad,
const Vector &vPos,
const Vector &vDirection,
const Vector &vColor,
float flLength=20,
float flLineWidth=3,
float flHeadWidth=8,
int nCylinderSegments=5,
int nHeadSegments=8,
float flArrowHeadPercentage = 0.3f // How much of the line is the arrow head.
);
// Draw an arrow with less parameters.. it generates parameters based on length
// automatically to make the arrow look good.
void ScratchPad_DrawArrowSimple(
IScratchPad3D *pPad,
const Vector &vPos,
const Vector &vDirection,
const Vector &vColor,
float flLength );
void ScratchPad_DrawSphere(
IScratchPad3D *pPad,
const Vector &vCenter,
float flRadius,
const Vector &vColor,
int nSubDivs=7 );
void ScratchPad_DrawAABB(
IScratchPad3D *pPad,
const Vector &vMins,
const Vector &vMaxs,
const Vector &vColor = Vector( 1,1,1 ) );
#endif // SCRATCHPADUTILS_H

View File

@@ -0,0 +1,311 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef ISOUNDEMITTERSYSTEMBASE_H
#define ISOUNDEMITTERSYSTEMBASE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/utldict.h"
#include "soundflags.h"
#include "mathlib/compressed_vector.h"
#include "appframework/iappsystem.h"
#include "tier3/tier3.h"
DECLARE_LOGGING_CHANNEL( LOG_SND_EMITTERSYSTEM );
#define SOUNDGENDER_MACRO "$gender"
#define SOUNDGENDER_MACRO_LENGTH 7 // Length of above including $
class KeyValues;
typedef unsigned int HSOUNDSCRIPTHASH;
#define SOUNDEMITTER_INVALID_HASH (HSOUNDSCRIPTHASH)-1
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
struct CSoundParameters
{
CSoundParameters()
{
channel = CHAN_AUTO; // 0
volume = VOL_NORM; // 1.0f
pitch = PITCH_NORM; // 100
pitchlow = PITCH_NORM;
pitchhigh = PITCH_NORM;
soundlevel = SNDLVL_NORM; // 75dB
soundname[ 0 ] = 0;
play_to_owner_only = false;
count = 0;
delay_msec = 0;
m_nSoundEntryVersion = 1;
m_hSoundScriptHash = SOUNDEMITTER_INVALID_HASH;
m_pOperatorsKV = NULL;
m_nRandomSeed = -1;
m_bHRTFFollowEntity = false;
m_bHRTFBilinear = false;
}
int channel;
float volume;
int pitch;
int pitchlow, pitchhigh;
soundlevel_t soundlevel;
// For weapon sounds...
bool play_to_owner_only;
int count;
char soundname[ 128 ];
int delay_msec;
HSOUNDSCRIPTHASH m_hSoundScriptHash;
int m_nSoundEntryVersion;
KeyValues *m_pOperatorsKV;
int m_nRandomSeed;
bool m_bHRTFFollowEntity;
bool m_bHRTFBilinear;
};
// A bit of a hack, but these are just utility function which are implemented in the SouneParametersInternal.cpp file which all users of this lib also compile
const char *SoundLevelToString( soundlevel_t level );
const char *ChannelToString( int channel );
const char *VolumeToString( float volume );
const char *PitchToString( float pitch );
soundlevel_t TextToSoundLevel( const char *key );
int TextToChannel( const char *name );
enum gender_t
{
GENDER_NONE = 0,
GENDER_MALE,
GENDER_FEMALE,
};
#pragma pack(1)
struct SoundFile
{
SoundFile()
{
symbol = UTL_INVAL_SYMBOL;
gender = GENDER_NONE;
available = true;
COMPILE_TIME_ASSERT( sizeof(SoundFile) == 4 );
}
CUtlSymbol symbol;
byte gender;
byte available;
};
#pragma pack()
#pragma pack(1)
template<typename T>
struct sound_interval_t
{
T start;
T range;
interval_t &ToInterval( interval_t &dest ) const { dest.start = start; dest.range = range; return dest; }
void FromInterval( const interval_t &from ) { start = from.start; range = from.range; }
float Random() const { return RandomFloat( start, start+range ); }
};
#pragma pack()
typedef sound_interval_t<float16_with_assign> volume_interval_t;
typedef sound_interval_t<uint16> soundlevel_interval_t;
typedef sound_interval_t<uint8> pitch_interval_t;
#pragma pack(1)
struct CSoundParametersInternal
{
CSoundParametersInternal();
~CSoundParametersInternal();
void CopyFrom( const CSoundParametersInternal& src );
bool operator == ( const CSoundParametersInternal& other ) const;
const char *VolumeToString( void ) const;
const char *ChannelToString( void ) const;
const char *SoundLevelToString( void ) const;
const char *PitchToString( void ) const;
void VolumeFromString( const char *sz );
void ChannelFromString( const char *sz );
void PitchFromString( const char *sz );
void SoundLevelFromString( const char *sz );
int GetChannel() const { return channel; }
const volume_interval_t &GetVolume() const { return volume; }
const pitch_interval_t &GetPitch() const { return pitch; }
const soundlevel_interval_t &GetSoundLevel() const { return soundlevel; }
int GetDelayMsec() const { return delay_msec; }
int GetSoundEntryVersion() const { return m_nSoundEntryVersion; }
bool OnlyPlayToOwner() const { return play_to_owner_only; }
bool HadMissingWaveFiles() const { return had_missing_wave_files; }
bool UsesGenderToken() const { return uses_gender_token; }
bool ShouldPreload() const { return m_bShouldPreload; }
bool ShouldAutoCache() const { return m_bShouldAutoCache; }
bool HasCached() const { return m_bHasCached; }
bool HasHRTFFollowEntity() const { return m_bHRTFFollowEntity; }
bool HasHRTFBilinear() const { return m_bHRTFBilinear; }
void SetChannel( int newChannel ) { channel = newChannel; }
void SetVolume( float start, float range = 0.0 ) { volume.start = ( uint8 )start; volume.range = ( uint8 )range; }
void SetPitch( float start, float range = 0.0 ) { pitch.start = ( uint8 )start; pitch.range = ( uint8 )range; }
void SetSoundLevel( float start, float range = 0.0 ) { soundlevel.start = ( uint16 )start; soundlevel.range = ( uint16 )range; }
void SetDelayMsec( int delay ) { delay_msec = delay; }
void SetSoundEntryVersion( int gameSoundVersion ) { m_nSoundEntryVersion = gameSoundVersion; }
void SetShouldPreload( bool bShouldPreload ) { m_bShouldPreload = bShouldPreload; }
void SetShouldAutoCache( bool bShouldAutoCache ) { m_bShouldAutoCache = bShouldAutoCache; }
void SetOnlyPlayToOwner( bool b ) { play_to_owner_only = b; }
void SetHadMissingWaveFiles( bool b ) { had_missing_wave_files = b; }
void SetUsesGenderToken( bool b ) { uses_gender_token = b; }
void SetCached( bool b ) { m_bHasCached = b; }
void SetHRTFFollowEntity( bool b ) { m_bHRTFFollowEntity = b; }
void SetHRTFBilinear( bool b ) { m_bHRTFBilinear = b; }
void AddSoundName( const SoundFile &soundFile ) { AddToTail( &m_pSoundNames, &m_nSoundNames, soundFile ); }
int NumSoundNames() const { return m_nSoundNames; }
SoundFile * GetSoundNames() { return ( m_nSoundNames == 1 ) ? (SoundFile *)&m_pSoundNames : m_pSoundNames; }
const SoundFile *GetSoundNames() const { return ( m_nSoundNames == 1 ) ? (SoundFile *)&m_pSoundNames : m_pSoundNames; }
void AddConvertedName( const SoundFile &soundFile ) { AddToTail( &m_pConvertedNames, &m_nConvertedNames, soundFile ); }
int NumConvertedNames() const { return m_nConvertedNames; }
SoundFile * GetConvertedNames() { return ( m_nConvertedNames == 1 ) ? (SoundFile *)&m_pConvertedNames : m_pConvertedNames; }
const SoundFile *GetConvertedNames() const { return ( m_nConvertedNames == 1 ) ? (SoundFile *)&m_pConvertedNames : m_pConvertedNames; }
// Sound Operator System: this should be optimized into something less heavy
KeyValues *GetOperatorsKV( void ) const { return m_pOperatorsKV; }
void SetOperatorsKV( KeyValues *src );
private:
void operator=( const CSoundParametersInternal& src ); // disallow implicit copies
CSoundParametersInternal( const CSoundParametersInternal& src );
void AddToTail( SoundFile **pDest, uint16 *pDestCount, const SoundFile &source );
SoundFile * m_pSoundNames; // 4
SoundFile * m_pConvertedNames; // 8
uint16 m_nSoundNames; // 10
uint16 m_nConvertedNames; // 12
volume_interval_t volume; // 16
soundlevel_interval_t soundlevel; // 20
pitch_interval_t pitch; // 22
uint16 channel; // 24
uint16 delay_msec; // 26
uint16 m_nSoundEntryVersion; // 28
bool play_to_owner_only:1; // For weapon sounds... // 29
// Internal use, for warning about missing .wav files
bool had_missing_wave_files:1;
bool uses_gender_token:1;
bool m_bShouldPreload:1;
bool m_bHasCached:1;
bool m_bShouldAutoCache:1;
bool m_bHRTFFollowEntity : 1;
bool m_bHRTFBilinear : 1;
byte reserved; // 30
KeyValues * m_pGameData; // 34
KeyValues * m_pOperatorsKV; // 38
};
#pragma pack()
//-----------------------------------------------------------------------------
// Purpose: Base class for sound emitter system handling (can be used by tools)
//-----------------------------------------------------------------------------
abstract_class ISoundEmitterSystemBase : public IAppSystem
{
public:
// Unused, left in the interface so I don't have to rebuild all
virtual void Unused1() {}
virtual void Unused2() {}
virtual int GetSoundIndex( const char *pName ) const = 0;
virtual bool IsValidIndex( int index ) = 0;
virtual int GetSoundCount( void ) = 0;
virtual const char *GetSoundName( int index ) = 0;
virtual bool GetParametersForSound( const char *soundname, CSoundParameters& params, gender_t gender, bool isbeingemitted = false ) = 0;
virtual const char *GetWaveName( CUtlSymbol& sym ) = 0;
virtual CUtlSymbol AddWaveName( const char *name ) = 0;
virtual soundlevel_t LookupSoundLevel( const char *soundname ) = 0;
virtual const char *GetWavFileForSound( const char *soundname, char const *actormodel ) = 0;
virtual const char *GetWavFileForSound( const char *soundname, gender_t gender ) = 0;
virtual int CheckForMissingWavFiles( bool verbose ) = 0;
virtual const char *GetSourceFileForSound( int index ) const = 0;
// Iteration methods
virtual int First() const = 0;
virtual int Next( int i ) const = 0;
virtual int InvalidIndex() const = 0;
virtual CSoundParametersInternal *InternalGetParametersForSound( int index ) = 0;
// The host application is responsible for dealing with dirty sound scripts, etc.
virtual bool AddSound( const char *soundname, const char *scriptfile, const CSoundParametersInternal& params ) = 0;
virtual void RemoveSound( const char *soundname ) = 0;
virtual void MoveSound( const char *soundname, const char *newscript ) = 0;
virtual void RenameSound( const char *soundname, const char *newname ) = 0;
virtual void UpdateSoundParameters( const char *soundname, const CSoundParametersInternal& params ) = 0;
virtual int GetNumSoundScripts() const = 0;
virtual char const *GetSoundScriptName( int index ) const = 0;
virtual bool IsSoundScriptDirty( int index ) const = 0;
virtual int FindSoundScript( const char *name ) const = 0;
virtual void SaveChangesToSoundScript( int scriptindex ) = 0;
virtual void ExpandSoundNameMacros( CSoundParametersInternal& params, char const *wavename ) = 0;
virtual gender_t GetActorGender( char const *actormodel ) = 0;
virtual void GenderExpandString( char const *actormodel, char const *in, char *out, int maxlen ) = 0;
virtual void GenderExpandString( gender_t gender, char const *in, char *out, int maxlen ) = 0;
virtual bool IsUsingGenderToken( char const *soundname ) = 0;
// For blowing away caches based on filetimstamps of the manifest, or of any of the
// .txt files that are read into the sound emitter system
virtual unsigned int GetManifestFileTimeChecksum() = 0;
virtual bool GetParametersForSoundEx( const char *soundname, HSOUNDSCRIPTHASH& handle, CSoundParameters& params, gender_t gender, bool isbeingemitted = false ) = 0;
virtual soundlevel_t LookupSoundLevelByHandle( char const *soundname, HSOUNDSCRIPTHASH& handle ) = 0;
virtual KeyValues *GetOperatorKVByHandle( HSOUNDSCRIPTHASH& handle ) = 0;
virtual char const *GetSoundNameForHash( HSOUNDSCRIPTHASH hash ) const = 0; // Returns NULL if hash not found!!!
virtual int GetSoundIndexForHash( HSOUNDSCRIPTHASH hash ) const = 0;
virtual HSOUNDSCRIPTHASH HashSoundName( char const *pchSndName ) const = 0;
virtual bool IsValidHash( HSOUNDSCRIPTHASH hash ) const = 0;
virtual void DescribeSound( char const *soundname ) = 0;
// Flush and reload
virtual void Flush() = 0;
virtual void AddSoundsFromFile( const char *filename, bool bPreload, bool bAutoCache, bool bIsOverride = false ) = 0;
};
#endif // ISOUNDEMITTERSYSTEMBASE_H

View File

@@ -0,0 +1,624 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#if !defined(_STATIC_LINKED) || defined(SOUNDEMITTERSYSTEM_DLL)
#include "SoundEmitterSystem/isoundemittersystembase.h"
#include "tier2/interval.h"
#include "soundchars.h"
#include "keyvalues.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
struct SoundChannels
{
int channel;
const char *name;
};
// NOTE: This will need to be updated if channel names are added/removed
static SoundChannels g_pChannelNames[] =
{
{ CHAN_AUTO, "CHAN_AUTO" },
{ CHAN_WEAPON, "CHAN_WEAPON" },
{ CHAN_VOICE, "CHAN_VOICE" },
{ CHAN_ITEM, "CHAN_ITEM" },
{ CHAN_BODY, "CHAN_BODY" },
{ CHAN_STREAM, "CHAN_STREAM" },
{ CHAN_STATIC, "CHAN_STATIC" },
};
struct VolumeLevel
{
float volume;
const char *name;
};
static VolumeLevel g_pVolumeLevels[] =
{
{ VOL_NORM, "VOL_NORM" },
};
struct PitchLookup
{
float pitch;
const char *name;
};
static PitchLookup g_pPitchLookup[] =
{
{ PITCH_NORM, "PITCH_NORM" },
{ PITCH_LOW, "PITCH_LOW" },
{ PITCH_HIGH, "PITCH_HIGH" },
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
struct SoundLevelLookup
{
soundlevel_t level;
char const *name;
};
// NOTE: Needs to reflect the soundlevel_t enum defined in soundflags.h
static SoundLevelLookup g_pSoundLevels[] =
{
{ SNDLVL_NONE, "SNDLVL_NONE" },
{ SNDLVL_20dB, "SNDLVL_20dB" },
{ SNDLVL_25dB, "SNDLVL_25dB" },
{ SNDLVL_30dB, "SNDLVL_30dB" },
{ SNDLVL_35dB, "SNDLVL_35dB" },
{ SNDLVL_40dB, "SNDLVL_40dB" },
{ SNDLVL_45dB, "SNDLVL_45dB" },
{ SNDLVL_50dB, "SNDLVL_50dB" },
{ SNDLVL_55dB, "SNDLVL_55dB" },
{ SNDLVL_IDLE, "SNDLVL_IDLE" },
{ SNDLVL_TALKING, "SNDLVL_TALKING" },
{ SNDLVL_60dB, "SNDLVL_60dB" },
{ SNDLVL_65dB, "SNDLVL_65dB" },
{ SNDLVL_STATIC, "SNDLVL_STATIC" },
{ SNDLVL_70dB, "SNDLVL_70dB" },
{ SNDLVL_NORM, "SNDLVL_NORM" },
{ SNDLVL_75dB, "SNDLVL_75dB" },
{ SNDLVL_80dB, "SNDLVL_80dB" },
{ SNDLVL_85dB, "SNDLVL_85dB" },
{ SNDLVL_90dB, "SNDLVL_90dB" },
{ SNDLVL_95dB, "SNDLVL_95dB" },
{ SNDLVL_100dB, "SNDLVL_100dB" },
{ SNDLVL_105dB, "SNDLVL_105dB" },
{ SNDLVL_110dB, "SNDLVL_110dB" },
{ SNDLVL_120dB, "SNDLVL_120dB" },
{ SNDLVL_130dB, "SNDLVL_130dB" },
{ SNDLVL_GUNFIRE, "SNDLVL_GUNFIRE" },
{ SNDLVL_140dB, "SNDLVL_140dB" },
{ SNDLVL_150dB, "SNDLVL_150dB" },
{ SNDLVL_180dB, "SNDLVL_180dB" },
};
static const char *_SoundLevelToString( soundlevel_t level )
{
int c = ARRAYSIZE( g_pSoundLevels );
int i;
for ( i = 0 ; i < c; i++ )
{
SoundLevelLookup *entry = &g_pSoundLevels[ i ];
if ( entry->level == level )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%i", (int)level );
return sz;
}
static const char *_ChannelToString( int channel )
{
int c = ARRAYSIZE( g_pChannelNames );
int i;
for ( i = 0 ; i < c; i++ )
{
SoundChannels *entry = &g_pChannelNames[ i ];
if ( entry->channel == channel )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%i", (int)channel );
return sz;
}
static const char *_VolumeToString( float volume )
{
int c = ARRAYSIZE( g_pVolumeLevels );
int i;
for ( i = 0 ; i < c; i++ )
{
VolumeLevel *entry = &g_pVolumeLevels[ i ];
if ( entry->volume == volume )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%.3f", volume );
return sz;
}
static const char *_PitchToString( float pitch )
{
int c = ARRAYSIZE( g_pPitchLookup );
int i;
for ( i = 0 ; i < c; i++ )
{
PitchLookup *entry = &g_pPitchLookup[ i ];
if ( entry->pitch == pitch )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%.3f", pitch );
return sz;
}
#define SNDLVL_PREFIX "SNDLVL_"
soundlevel_t TextToSoundLevel( const char *key )
{
if ( !key )
{
Assert( 0 );
return SNDLVL_NORM;
}
int c = ARRAYSIZE( g_pSoundLevels );
int i;
for ( i = 0 ; i < c; i++ )
{
SoundLevelLookup *entry = &g_pSoundLevels[ i ];
if ( !Q_strcasecmp( key, entry->name ) )
return entry->level;
}
if ( StringHasPrefix( key, SNDLVL_PREFIX ) )
{
char const *val = key + V_strlen( SNDLVL_PREFIX );
int sndlvl = atoi( val );
if ( sndlvl > 0 && sndlvl <= 180 )
{
return ( soundlevel_t )sndlvl;
}
}
DevMsg( "CSoundEmitterSystem: Unknown sound level %s\n", key );
return SNDLVL_NORM;
}
//-----------------------------------------------------------------------------
// Purpose: Convert "chan_xxx" into integer value for channel
// Input : *name -
// Output : static int
//-----------------------------------------------------------------------------
int TextToChannel( const char *name )
{
if ( !name )
{
Assert( 0 );
// CHAN_AUTO
return CHAN_AUTO;
}
if ( Q_strncasecmp( name, "chan_", strlen( "chan_" ) ) )
{
return atoi( name );
}
int c = ARRAYSIZE( g_pChannelNames );
int i;
for ( i = 0; i < c; i++ )
{
if ( !Q_strcasecmp( name, g_pChannelNames[ i ].name ) )
{
return g_pChannelNames[ i ].channel;
}
}
// At this point, it starts with chan_ but is not recognized
// atoi would return 0, so just do chan auto
DevMsg( "CSoundEmitterSystem: Warning, unknown channel type in sounds.txt (%s)\n", name );
return CHAN_AUTO;
}
const char *SoundLevelToString( soundlevel_t level )
{
int c = ARRAYSIZE( g_pSoundLevels );
int i;
for ( i = 0 ; i < c; i++ )
{
SoundLevelLookup *entry = &g_pSoundLevels[ i ];
if ( entry->level == level )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%i", (int)level );
return sz;
}
const char *ChannelToString( int channel )
{
int c = ARRAYSIZE( g_pChannelNames );
int i;
for ( i = 0 ; i < c; i++ )
{
SoundChannels *entry = &g_pChannelNames[ i ];
if ( entry->channel == channel )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%i", (int)channel );
return sz;
}
const char *VolumeToString( float volume )
{
int c = ARRAYSIZE( g_pVolumeLevels );
int i;
for ( i = 0 ; i < c; i++ )
{
VolumeLevel *entry = &g_pVolumeLevels[ i ];
if ( entry->volume == volume )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%.3f", volume );
return sz;
}
const char *PitchToString( float pitch )
{
int c = ARRAYSIZE( g_pPitchLookup );
int i;
for ( i = 0 ; i < c; i++ )
{
PitchLookup *entry = &g_pPitchLookup[ i ];
if ( entry->pitch == pitch )
return entry->name;
}
static char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "%.3f", pitch );
return sz;
}
CSoundParametersInternal::CSoundParametersInternal()
{
m_pConvertedNames = m_pSoundNames = NULL;
m_nConvertedNames = m_nSoundNames = 0;
channel = CHAN_AUTO; // 0
volume.start = VOL_NORM; // 1.0f
volume.range = 0.0f;
pitch.start = PITCH_NORM; // 100
pitch.range = 0;
soundlevel.start = SNDLVL_NORM; // 75dB
soundlevel.range = 0;
delay_msec = 0;
play_to_owner_only = false;
had_missing_wave_files = false;
uses_gender_token = false;
m_bHasCached = false;
m_bHRTFBilinear = false;
m_bHRTFFollowEntity = false;
m_nSoundEntryVersion = 1;
m_pOperatorsKV = NULL;
// TERROR:
m_pGameData = NULL;
}
CSoundParametersInternal::CSoundParametersInternal( const CSoundParametersInternal& src )
{
m_pSoundNames = NULL;
m_pConvertedNames = NULL;
m_pOperatorsKV = NULL;
// TERROR:
m_pGameData = NULL;
CopyFrom( src );
}
CSoundParametersInternal::~CSoundParametersInternal()
{
if ( m_nSoundNames > 1 )
free(m_pSoundNames );
if ( m_nConvertedNames > 1 )
free( m_pConvertedNames);
if ( m_pOperatorsKV )
{
m_pOperatorsKV->deleteThis();
m_pOperatorsKV = NULL;
}
m_pConvertedNames = NULL;
m_pSoundNames = NULL;
m_nSoundNames = 0;
m_nConvertedNames = 0;
}
void CSoundParametersInternal::SetOperatorsKV( KeyValues *src )
{
if ( m_pOperatorsKV )
{
m_pOperatorsKV->deleteThis();
}
m_pOperatorsKV = NULL;
m_pOperatorsKV = new KeyValues( "Operators" );
src->CopySubkeys( m_pOperatorsKV );
}
void CSoundParametersInternal::CopyFrom( const CSoundParametersInternal& src )
{
if ( m_nSoundNames > 1 )
free(m_pSoundNames);
if ( m_nConvertedNames > 1 )
free(m_pConvertedNames);
channel = src.channel;
volume = src.volume;
pitch = src.pitch;
soundlevel = src.soundlevel;
delay_msec = src.delay_msec;
play_to_owner_only = src.play_to_owner_only;
m_bHRTFBilinear = src.m_bHRTFBilinear;
m_bHRTFFollowEntity = src.m_bHRTFFollowEntity;
m_nSoundNames = src.m_nSoundNames;
if ( m_nSoundNames )
{
if ( m_nSoundNames > 1 )
{
m_pSoundNames = (SoundFile*)malloc( sizeof(SoundFile)*m_nSoundNames);
memcpy( m_pSoundNames, src.m_pSoundNames, m_nSoundNames * sizeof(SoundFile) );
}
else
{
m_pSoundNames = src.m_pSoundNames;
}
}
else
{
m_pSoundNames = NULL;
}
m_nConvertedNames = src.m_nConvertedNames;
if ( m_nConvertedNames )
{
if ( m_nConvertedNames > 1 )
{
m_pConvertedNames = (SoundFile*)malloc( sizeof(SoundFile)*m_nConvertedNames);
memcpy( m_pConvertedNames, src.m_pConvertedNames, m_nConvertedNames * sizeof(SoundFile) );
}
else
{
m_pConvertedNames = src.m_pConvertedNames;
}
}
else
{
m_pConvertedNames = NULL;
}
if ( src.m_pOperatorsKV )
{
SetOperatorsKV( src.m_pOperatorsKV );
}
had_missing_wave_files = src.had_missing_wave_files;
uses_gender_token = src.uses_gender_token;
}
#define CompareInterval( i1, i2 ) ( memcmp( &(i1), &(i2), sizeof(i1) ) == 0 )
bool CSoundParametersInternal::operator == ( const CSoundParametersInternal& other ) const
{
if ( this == &other )
return true;
if ( channel != other.channel )
return false;
if ( !CompareInterval( volume, other.volume ) )
return false;
if ( !CompareInterval( pitch, other.pitch ) )
return false;
if ( !CompareInterval( soundlevel, other.soundlevel ) )
return false;
if ( delay_msec != other.delay_msec )
return false;
if ( play_to_owner_only != other.play_to_owner_only )
return false;
if (m_bHRTFBilinear != other.m_bHRTFBilinear)
return false;
if ( m_bHRTFFollowEntity != other.m_bHRTFFollowEntity )
return false;
if ( m_nSoundNames != other.m_nSoundNames )
return false;
// Compare items
int c = m_nSoundNames;
for ( int i = 0; i < c; i++ )
{
if ( GetSoundNames()[ i ].symbol != other.GetSoundNames()[ i ].symbol )
return false;
}
return true;
}
float16 ZERO_FLOAT16;
const char *CSoundParametersInternal::VolumeToString( void ) const
{
if ( volume.range == ZERO_FLOAT16 )
{
return _VolumeToString( volume.start );
}
static char sz[ 64 ];
Q_snprintf( sz, sizeof( sz ), "%.3f, %.3f", (float)volume.start, (float)volume.start + (float)volume.range );
return sz;
}
const char *CSoundParametersInternal::ChannelToString( void ) const
{
return _ChannelToString( channel );
}
const char *CSoundParametersInternal::SoundLevelToString( void ) const
{
if ( soundlevel.range == 0 )
{
return _SoundLevelToString( (soundlevel_t)(int)soundlevel.start );
}
static char sz[ 64 ];
Q_snprintf( sz, sizeof( sz ), "%i, %i", (soundlevel_t)(int)soundlevel.start, (soundlevel_t)(int)(soundlevel.start + soundlevel.range ) );
return sz;
}
const char *CSoundParametersInternal::PitchToString( void ) const
{
if ( pitch.range == 0 )
{
return _PitchToString( (int)pitch.start );
}
static char sz[ 64 ];
Q_snprintf( sz, sizeof( sz ), "%i, %i", (int)pitch.start, (int)(pitch.start + pitch.range ) );
return sz;
}
void CSoundParametersInternal::VolumeFromString( const char *sz )
{
if ( !Q_strcasecmp( sz, "VOL_NORM" ) )
{
volume.start = VOL_NORM;
volume.range = 0.0f;
}
else
{
volume.FromInterval( ReadInterval( sz ) );
}
}
void CSoundParametersInternal::ChannelFromString( const char *sz )
{
channel = TextToChannel( sz );
}
void CSoundParametersInternal::PitchFromString( const char *sz )
{
if ( !Q_strcasecmp( sz, "PITCH_NORM" ) )
{
pitch.start = PITCH_NORM;
pitch.range = 0;
}
else if ( !Q_strcasecmp( sz, "PITCH_LOW" ) )
{
pitch.start = PITCH_LOW;
pitch.range = 0;
}
else if ( !Q_strcasecmp( sz, "PITCH_HIGH" ) )
{
pitch.start = PITCH_HIGH;
pitch.range = 0;
}
else
{
pitch.FromInterval( ReadInterval( sz ) );
}
}
void CSoundParametersInternal::SoundLevelFromString( const char *sz )
{
if ( !Q_strncasecmp( sz, "SNDLVL_", strlen( "SNDLVL_" ) ) )
{
soundlevel.start = TextToSoundLevel( sz );
soundlevel.range = 0;
}
else
{
soundlevel.FromInterval( ReadInterval( sz ) );
}
}
void CSoundParametersInternal::AddToTail( SoundFile **pDest, uint16 *pDestCount, const SoundFile &source )
{
(*pDestCount)++;
if ( *pDestCount == 1 )
{
// NOTE: when there's only one soundfile in the list, we store it
// packed into the pointer itself, the four bytes for the pointer is just used to store the sound file!
COMPILE_TIME_ASSERT( sizeof(SoundFile) <= sizeof(SoundFile *) );
*((SoundFile *)(pDest)) = source;
}
else
{
SoundFile temp;
if ( *pDestCount == 2 )
{
// Copying from a list of one soundfile. Save off the struct
// packed into the pointer field.
temp = *((SoundFile *)(pDest));
*pDest = NULL;
}
*pDest = (SoundFile *)realloc( *pDest, (*pDestCount) * sizeof(SoundFile) );
(*pDest)[ *pDestCount - 1 ] = source;
if ( *pDestCount == 2 )
{
(*pDest)[0] = temp;
}
}
}
#endif // !_STATIC_LINKED || SOUNDEMITTERSYSTEM_DLL

View File

@@ -0,0 +1,243 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <stdlib.h>
#include <ctype.h>
#include "utlbuffer.h"
#ifdef _PS3
#include <wctype.h>
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Advances until non-whitespace hit
//-----------------------------------------------------------------------------
ucs2 *AdvanceOverWhitespace(ucs2 *Start)
{
while (*Start != 0 && iswspace(*Start))
{
Start++;
}
return Start;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
ucs2 *ReadUnicodeToken(ucs2 *start, ucs2 *token, int tokenBufferSize, bool &quoted)
{
// skip over any whitespace
start = AdvanceOverWhitespace(start);
quoted = false;
*token = 0;
if (!*start)
{
return start;
}
// check to see if it's a quoted string
if (*start == '\"')
{
quoted = true;
// copy out the string until we hit an end quote
start++;
int count = 0;
while (*start && *start != '\"' && count < tokenBufferSize-1)
{
// check for special characters
if (*start == '\\' && *(start+1) == 'n')
{
start++;
*token = '\n';
}
else if (*start == '\\' && *(start+1) == '\"')
{
start++;
*token = '\"';
}
else
{
*token = *start;
}
start++;
token++;
count++;
}
if (*start == '\"')
{
start++;
}
}
else
{
// copy out the string until we hit a whitespace
int count = 0;
while (*start && !iswspace(*start) && count < tokenBufferSize-1)
{
// no checking for special characters if it's not a quoted string
*token = *start;
start++;
token++;
count++;
}
}
*token = 0;
return start;
}
//-----------------------------------------------------------------------------
// Purpose: Same as above but no translation of \n
//-----------------------------------------------------------------------------
ucs2 *ReadUnicodeTokenNoSpecial(ucs2 *start, ucs2 *token, int tokenBufferSize, bool &quoted)
{
// skip over any whitespace
start = AdvanceOverWhitespace(start);
quoted = false;
*token = 0;
if (!*start)
{
return start;
}
// check to see if it's a quoted string
if (*start == '\"')
{
quoted = true;
// copy out the string until we hit an end quote
start++;
int count = 0;
while (*start && *start != '\"' && count < tokenBufferSize-1)
{
// check for special characters
/*
if (*start == '\\' && *(start+1) == 'n')
{
start++;
*token = '\n';
}
else
*/
if (*start == '\\' && *(start+1) == '\"')
{
start++;
*token = '\"';
}
else
{
*token = *start;
}
start++;
token++;
count++;
}
if (*start == '\"')
{
start++;
}
}
else
{
// copy out the string until we hit a whitespace
int count = 0;
while (*start && !iswspace(*start) && count < tokenBufferSize-1)
{
// no checking for special characters if it's not a quoted string
*token = *start;
start++;
token++;
count++;
}
}
*token = 0;
return start;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the first character after the next EOL characters
//-----------------------------------------------------------------------------
ucs2 *ReadToEndOfLine(ucs2 *start)
{
if (!*start)
return start;
while (*start)
{
if (*start == 0x0D || *start== 0x0A)
break;
start++;
}
while (*start == 0x0D || *start== 0x0A)
start++;
return start;
}
//-----------------------------------------------------------------------------
// Purpose: file writing
//-----------------------------------------------------------------------------
void WriteUnicodeString(CUtlBuffer &buf, const wchar_t *string, bool addQuotes)
{
if (addQuotes)
{
buf.PutUnsignedShort('\"');
}
for (const wchar_t *ws = string; *ws != 0; ws++)
{
// handle special characters
if (addQuotes && *ws == '\"')
{
buf.PutUnsignedShort('\\');
}
// write the character
buf.PutUnsignedShort(*ws);
}
if (addQuotes)
{
buf.PutUnsignedShort('\"');
}
}
//-----------------------------------------------------------------------------
// Purpose: file writing
//-----------------------------------------------------------------------------
void WriteAsciiStringAsUnicode(CUtlBuffer &buf, const char *string, bool addQuotes)
{
if (addQuotes)
{
buf.PutUnsignedShort('\"');
}
for (const char *sz = string; *sz != 0; sz++)
{
// handle special characters
if (addQuotes && *sz == '\"')
{
buf.PutUnsignedShort('\\');
}
buf.PutUnsignedShort(*sz);
}
if (addQuotes)
{
buf.PutUnsignedShort('\"');
}
}

View File

@@ -0,0 +1,28 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef UNICODEFILEHELPERS_H
#define UNICODEFILEHELPERS_H
#ifdef _WIN32
#pragma once
#endif
#include <stdlib.h>
// helper functions for parsing unicode file buffers
ucs2 *AdvanceOverWhitespace(ucs2 *start);
ucs2 *ReadUnicodeToken(ucs2 *start, ucs2 *token, int tokenBufferSize, bool &quoted);
ucs2 *ReadUnicodeTokenNoSpecial(ucs2 *start, ucs2 *token, int tokenBufferSize, bool &quoted);
ucs2 *ReadToEndOfLine(ucs2 *start);
// writing to unicode files via CUtlBuffer
class CUtlBuffer;
void WriteUnicodeString(CUtlBuffer &buffer, const wchar_t *string, bool addQuotes = false);
void WriteAsciiStringAsUnicode(CUtlBuffer &buffer, const char *string, bool addQuotes = false);
#endif // UNICODEFILEHELPERS_H

1091
public/UtlCachedFileData.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,126 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: An extra interface implemented by the material system
// implementation of vgui::ISurface
//
// $Revision: $
// $NoKeywords: $
//===========================================================================//
#ifndef IMATSYSTEMSURFACE_H
#define IMATSYSTEMSURFACE_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui/vgui.h>
#include "vgui/ISurface.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class VMatrix;
class IMaterial;
struct InputEvent_t;
FORWARD_DECLARE_HANDLE( InputContextHandle_t );
//-----------------------------------------------------------------------------
// Callbacks for mouse getting + setting
//-----------------------------------------------------------------------------
typedef void (*GetMouseCallback_t)(int &x, int &y);
typedef void (*SetMouseCallback_t)(int x, int y);
//-----------------------------------------------------------------------------
// Callbacks for sound playing
//-----------------------------------------------------------------------------
typedef void (*PlaySoundFunc_t)(const char *pFileName);
//-----------------------------------------------------------------------------
//
// An extra interface implemented by the material system implementation of vgui::ISurface
//
//-----------------------------------------------------------------------------
class IMatSystemSurface : public vgui::ISurface
{
public:
// If the app drives the input (like the engine needs to do for VCR mode),
// it can call this, setting bLetAppDriveInput to true and call
// HandleInputEvent for the input events.
virtual void SetAppDrivesInput( bool bLetAppDriveInput ) = 0;
// Tells the surface to ignore windows messages
virtual void EnableWindowsMessages( bool bEnable ) = 0;
// Starts, ends 3D painting
// NOTE: These methods should only be called from within the paint()
// method of a panel.
// When manual supersampling of rendertarget is enabled then the render
// target will double the width and height of the rendering region if possible, or will otherwise
// increase the rendering region to fill up the width/height of the render target maintaining
// the aspect ratio.
virtual void Begin3DPaint( int iLeft, int iTop, int iRight, int iBottom, bool bSupersampleRT = false ) = 0;
virtual void End3DPaint( bool bIgnoreAlphaWhenCompositing = false ) = 0;
// NOTE: This also should only be called from within the paint()
// method of a panel. Use it to disable clipping for the rendering
// of this panel.
virtual void DisableClipping( bool bDisable ) = 0;
// Prevents vgui from changing the cursor
virtual bool IsCursorLocked() const = 0;
// Sets the mouse get + set callbacks
virtual void SetMouseCallbacks( GetMouseCallback_t getFunc, SetMouseCallback_t setFunc ) = 0;
// Installs a function to play sounds
virtual void InstallPlaySoundFunc( PlaySoundFunc_t soundFunc ) = 0;
// Some drawing methods that cannot be accomplished under Win32
virtual void DrawColoredCircle( int centerx, int centery, float radius, int r, int g, int b, int a ) = 0;
virtual void DrawColoredText( vgui::HFont font, int x, int y, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *fmt, ... ) = 0;
// Draws text with current font at position and wordwrapped to the rect using color values specified
virtual void DrawColoredTextRect( vgui::HFont font, int x, int y, int w, int h, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *fmt, ... ) = 0;
virtual void DrawTextHeight( vgui::HFont font, int w, int& h, PRINTF_FORMAT_STRING char *fmt, ... ) = 0;
// Returns the length of the text string in pixels
virtual int DrawTextLen( vgui::HFont font, PRINTF_FORMAT_STRING const char *fmt, ... ) = 0;
// Draws a panel in 3D space. Assumes view + projection are already set up
// Also assumes the (x,y) coordinates of the panels are defined in 640xN coords
// (N isn't necessary 480 because the panel may not be 4x3)
// The width + height specified are the size of the panel in world coordinates
virtual void DrawPanelIn3DSpace( vgui::VPANEL pRootPanel, const VMatrix &panelCenterToWorld, int nPixelWidth, int nPixelHeight, float flWorldWidth, float flWorldHeight ) = 0;
// Binds a material to a surface texture ID
virtual void DrawSetTextureMaterial( int id, IMaterial *pMaterial ) = 0;
// Handles an input event, returns true if the event should be filtered from the rest of the game
virtual bool HandleInputEvent( const InputEvent_t &event ) = 0;
virtual void Set3DPaintTempRenderTarget( const char *pRenderTargetName ) = 0;
virtual void Reset3DPaintTempRenderTarget( void ) = 0;
// Gets a material bound to a surface texture ID
virtual IMaterial *DrawGetTextureMaterial( int id ) = 0;
// Sets the VGui input context
virtual void SetInputContext( InputContextHandle_t hContext ) = 0;
// uploads a part of a texture, used for font rendering
virtual void DrawSetSubTextureRGBA( int textureID, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall ) = 0;
// Draws a gradient filled rect where the colors may be different
virtual void DrawTexturedSubRectGradient( int x0, int y0, int x1, int y1, float texs0, float text0, float texs1, float text1, Color colStart, Color colEnd, bool bHorizontal ) = 0;
// Sets texture RGBA with linear scaling (normally it's pointsampling on the DrawSetTextureRGBA call)
virtual void DrawSetTextureRGBALinear( int id, const unsigned char *rgba, int wide, int tall ) = 0;
};
#endif // IMATSYSTEMSURFACE_H

View File

@@ -0,0 +1,88 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef IMATSYSTEMSURFACEV5_H
#define IMATSYSTEMSURFACEV5_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui/VGUI.h>
#include "vgui/isurfacev30.h"
namespace MatSystemSurfaceV5
{
#define MAT_SYSTEM_SURFACE_INTERFACE_VERSION_5 "MatSystemSurface005"
class IMatSystemSurface : public SurfaceV30::ISurface
{
public:
// Hook needed to get input to work.
// If the app drives the input (like the engine needs to do for VCR mode),
// it can set bLetAppDriveInput to true and call HandleWindowMessage for the Windows messages.
virtual void AttachToWindow( void *hwnd, bool bLetAppDriveInput=false ) = 0;
// If you specified true for bLetAppDriveInput, then call this for each window message that comes in.
virtual void HandleWindowMessage( void *hwnd, unsigned int uMsg, unsigned int wParam, long lParam ) = 0;
// Tells the surface to ignore windows messages
virtual void EnableWindowsMessages( bool bEnable ) = 0;
// Starts, ends 3D painting
// NOTE: These methods should only be called from within the paint()
// method of a panel.
virtual void Begin3DPaint( int iLeft, int iTop, int iRight, int iBottom ) = 0;
virtual void End3DPaint() = 0;
// NOTE: This also should only be called from within the paint()
// method of a panel. Use it to disable clipping for the rendering
// of this panel.
virtual void DisableClipping( bool bDisable ) = 0;
// Prevents vgui from changing the cursor
virtual bool IsCursorLocked() const = 0;
// Sets the mouse get + set callbacks
virtual void SetMouseCallbacks( GetMouseCallback_t getFunc, SetMouseCallback_t setFunc ) = 0;
// Installs a function to play sounds
virtual void InstallPlaySoundFunc( PlaySoundFunc_t soundFunc ) = 0;
// Some drawing methods that cannot be accomplished under Win32
virtual void DrawColoredCircle( int centerx, int centery, float radius, int r, int g, int b, int a ) = 0;
virtual int DrawColoredText( vgui::HFont font, int x, int y, int r, int g, int b, int a, const char *fmt, ... ) = 0;
// Draws text with current font at position and wordwrapped to the rect using color values specified
virtual void DrawColoredTextRect( vgui::HFont font, int x, int y, int w, int h, int r, int g, int b, int a, const char *fmt, ... ) = 0;
virtual void DrawTextHeight( vgui::HFont font, int w, int& h, char *fmt, ... ) = 0;
// Returns the length of the text string in pixels
virtual int DrawTextLen( vgui::HFont font, const char *fmt, ... ) = 0;
// Draws a panel in 3D space. Assumes view + projection are already set up
// Also assumes the (x,y) coordinates of the panels are defined in 640xN coords
// (N isn't necessary 480 because the panel may not be 4x3)
// The width + height specified are the size of the panel in world coordinates
virtual void DrawPanelIn3DSpace( vgui::VPANEL pRootPanel, const VMatrix &panelCenterToWorld, int nPixelWidth, int nPixelHeight, float flWorldWidth, float flWorldHeight ) = 0;
// Binds a material to a surface texture ID
virtual void DrawSetTextureMaterial( int id, IMaterial *pMaterial ) = 0;
};
}
//-----------------------------------------------------------------------------
// FIXME: This works around using scoped interfaces w/ EXPOSE_SINGLE_INTERFACE
//-----------------------------------------------------------------------------
class IMatSystemSurfaceV5 : public MatSystemSurfaceV5::IMatSystemSurface
{
public:
};
#endif // IMATSYSTEMSURFACEV5_H

4525
public/XUnzip.cpp Normal file

File diff suppressed because it is too large Load Diff

3078
public/XZip.cpp Normal file

File diff suppressed because it is too large Load Diff

23
public/alignedarray.h Normal file
View File

@@ -0,0 +1,23 @@
//========= Copyright c 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef ALIGNED_ARRAY_H
#define ALIGNED_ARRAY_H
#include "mathlib/vector4d.h"
#include "tier1/utlvector.h"
// can't make it with Vector4DAligned for now, because of private copy constructor..
typedef CUtlVector<Vector4D, CUtlMemoryAligned<Vector4D, 16> > CUtlVector_Vector4DAligned;
#endif

View File

@@ -0,0 +1,228 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: An application framework
//
// $Revision: $
// $NoKeywords: $
//===========================================================================//
#ifndef APPFRAMEWORK_H
#define APPFRAMEWORK_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/IAppSystemGroup.h"
#include "ilaunchabledll.h"
//-----------------------------------------------------------------------------
// Gets the application instance..
//-----------------------------------------------------------------------------
void *GetAppInstance();
//-----------------------------------------------------------------------------
// Sets the application instance, should only be used if you're not calling AppMain.
//-----------------------------------------------------------------------------
void SetAppInstance( void* hInstance );
//-----------------------------------------------------------------------------
// Main entry point for the application
//-----------------------------------------------------------------------------
int AppMain( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup );
int AppMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup );
//-----------------------------------------------------------------------------
// Used to startup/shutdown the application
//-----------------------------------------------------------------------------
int AppStartup( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup );
int AppStartup( int argc, char **argv, CAppSystemGroup *pAppSystemGroup );
void AppShutdown( CAppSystemGroup *pAppSystemGroup );
//-----------------------------------------------------------------------------
// Macros to create singleton application objects for windowed + console apps
//-----------------------------------------------------------------------------
// This assumes you've used one of the
#define DEFINE_LAUNCHABLE_DLL_STEAM_APP() \
class CAppLaunchableDLL : public ILaunchableDLL \
{ \
public: \
virtual int main( int argc, char **argv ) \
{ \
return AppMain( argc, argv, &__s_SteamApplicationObject ); \
} \
}; \
static CAppLaunchableDLL __g_AppLaunchableDLL; \
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CAppLaunchableDLL, ILaunchableDLL, LAUNCHABLE_DLL_INTERFACE_VERSION, __g_AppLaunchableDLL );
#if !defined( _X360 )
#if defined( _OSX )
#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \
int main( int argc, char **argv ) \
{ \
extern int ValveCocoaMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup ); \
return ValveCocoaMain( argc, argv, &_globalVarName ); \
}
#elif defined( PLATFORM_LINUX )
#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \
int main( int argc, char **argv ) \
{ \
extern int ValveLinuxWindowedMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup ); \
return ValveLinuxWindowedMain( argc, argv, &_globalVarName ); \
}
#else
#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \
int __stdcall WinMain( struct HINSTANCE__* hInstance, struct HINSTANCE__* hPrevInstance, NULLTERMINATED char *lpCmdLine, int nCmdShow ) \
{ \
return AppMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow, &_globalVarName ); \
}
#endif
#else
#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \
DLL_EXPORT int AppMain360( struct HINSTANCE__* hInstance, struct HINSTANCE__* hPrevInstance, NULLTERMINATED char *lpCmdLine, int nCmdShow ) \
{ \
return AppMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow, &_globalVarName ); \
}
#endif
#if !defined( _X360 )
#define DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \
int main( int argc, char **argv ) \
{ \
return AppMain( argc, argv, &_globalVarName ); \
}
#else
#define DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \
DLL_EXPORT int AppMain360( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) \
{ \
return AppMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow, &_globalVarName ); \
}
#endif
#define DEFINE_BINLAUNCHABLE_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \
class CApplicationDLL : public ILaunchableDLL \
{ \
public: \
virtual int main( int argc, char **argv ) \
{ \
return AppMain( argc, argv, &_globalVarName ); \
} \
}; \
EXPOSE_SINGLE_INTERFACE( CApplicationDLL, ILaunchableDLL, LAUNCHABLE_DLL_INTERFACE_VERSION )
#define DEFINE_WINDOWED_APPLICATION_OBJECT( _className ) \
static _className __s_ApplicationObject; \
DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( __s_ApplicationObject )
#define DEFINE_CONSOLE_APPLICATION_OBJECT( _className ) \
static _className __s_ApplicationObject; \
DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( __s_ApplicationObject )
#define DEFINE_BINLAUNCHABLE_APPLICATION_OBJECT( _className ) \
static _className __s_ApplicationObject; \
DEFINE_BINLAUNCHABLE_APPLICATION_OBJECT_GLOBALVAR( __s_ApplicationObject )
//-----------------------------------------------------------------------------
// This class is a helper class used for steam-based applications.
// It loads up the file system in preparation for using it to load other
// required modules from steam.
//-----------------------------------------------------------------------------
class CSteamApplication : public CAppSystemGroup
{
typedef CAppSystemGroup BaseClass;
public:
CSteamApplication( CSteamAppSystemGroup *pAppSystemGroup );
// Implementation of IAppSystemGroup
virtual bool Create( );
virtual bool PreInit( );
virtual int Main( );
virtual void PostShutdown();
virtual void Destroy();
// Use this version in cases where you can't control the main loop and
// expect to be ticked
virtual int Startup();
virtual void Shutdown();
public:
// Here's a hook to override the filesystem DLL that it tries to load.
// By default, it uses FileSystem_GetFileSystemDLLName to figure this out.
virtual bool GetFileSystemDLLName( char *pOut, int nMaxBytes, bool &bIsSteam );
protected:
IFileSystem *m_pFileSystem;
CSteamAppSystemGroup *m_pChildAppSystemGroup;
bool m_bSteam;
};
class CBinLaunchableSteamApp : public CSteamApplication
{
public:
CBinLaunchableSteamApp( CSteamAppSystemGroup *pAppSystemGroup ) : CSteamApplication( pAppSystemGroup )
{
}
virtual bool GetFileSystemDLLName( char *pOut, int nMaxChars, bool &bIsSteam )
{
// Our path should already include game\bin, so just use the filename directly
// and don't try to figure out an absolute path to it as CSteamApplication does.
V_strncpy( pOut, "filesystem_stdio", nMaxChars );
bIsSteam = false;
return true;
}
};
//-----------------------------------------------------------------------------
// Macros to help create singleton application objects for windowed + console steam apps
//-----------------------------------------------------------------------------
#define DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT_GLOBALVAR( _className, _varName ) \
static CSteamApplication __s_SteamApplicationObject( &_varName ); \
DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject )
#define DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT( _className ) \
static _className __s_ApplicationObject; \
static CSteamApplication __s_SteamApplicationObject( &__s_ApplicationObject ); \
DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject )
#define DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT_GLOBALVAR( _className, _varName ) \
static CSteamApplication __s_SteamApplicationObject( &_varName ); \
DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject )
#define DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT( _className ) \
static _className __s_ApplicationObject; \
static CSteamApplication __s_SteamApplicationObject( &__s_ApplicationObject ); \
DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject )
#define DEFINE_BINLAUNCHABLE_STEAM_APPLICATION_OBJECT_GLOBALVAR( _className, _varName ) \
static CBinLaunchableSteamApp __s_SteamApplicationObject( &_varName ); \
DEFINE_BINLAUNCHABLE_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject )
#define DEFINE_BINLAUNCHABLE_STEAM_APPLICATION_OBJECT( _className ) \
static _className __s_ApplicationObject; \
static CBinLaunchableSteamApp __s_SteamApplicationObject( &__s_ApplicationObject ); \
DEFINE_BINLAUNCHABLE_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject )
// This defines your steam application object and ties it to your appsystemgroup.
// This does NOT hookup its AppMain to get called. You'll have to call that from startup code
// or use something like DEFINE_LAUNCHABLE_DLL_STEAM_APP() to call it.
//
// _steamApplicationClass derives from CSteamApplication.
// _appClass derives from CAppSystemGroup (.. can derive from - or be - CTier2SteamApp for example).
//
#define DEFINE_CUSTOM_STEAM_APPLICATION_OBJECT( _steamApplicationClassName, _appClassName ) \
static _appClassName __s_ApplicationObject; \
static _steamApplicationClassName __s_SteamApplicationObject( &__s_ApplicationObject );
#endif // APPFRAMEWORK_H

View File

@@ -0,0 +1,302 @@
//======== (C) Copyright 1999, 2000 Valve, L.L.C. All rights reserved. ========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: Defines a group of app systems that all have the same lifetime
// that need to be connected/initialized, etc. in a well-defined order
//
// $Revision: $
// $NoKeywords: $
//=============================================================================
#ifndef IAPPSYSTEMGROUP_H
#define IAPPSYSTEMGROUP_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/interface.h"
#include "tier1/utlvector.h"
#include "tier1/utldict.h"
#include "tier1/UtlStringMap.h"
#include "iappsystem.h"
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
class IAppSystem;
class CSysModule;
class IBaseInterface;
class IFileSystem;
//-----------------------------------------------------------------------------
// Handle to a DLL
//-----------------------------------------------------------------------------
typedef int AppModule_t;
enum
{
APP_MODULE_INVALID = (AppModule_t)~0
};
//-----------------------------------------------------------------------------
// NOTE: The following methods must be implemented in your application
// although they can be empty implementations if you like...
//-----------------------------------------------------------------------------
abstract_class IAppSystemGroup
{
public:
// An installed application creation function, you should tell the group
// the DLLs and the singleton interfaces you want to instantiate.
// Return false if there's any problems and the app will abort
virtual bool Create( ) = 0;
// Allow the application to do some work after AppSystems are connected but
// they are all Initialized.
// Return false if there's any problems and the app will abort
virtual bool PreInit() = 0;
// Allow the application to do some work after AppSystems are initialized but
// before main is run
// Return false if there's any problems and the app will abort
virtual bool PostInit() = 0;
// Main loop implemented by the application
virtual int Main( ) = 0;
// Allow the application to do some work after all AppSystems are shut down
virtual void PreShutdown() = 0;
// Allow the application to do some work after all AppSystems are shut down
virtual void PostShutdown() = 0;
// Call an installed application destroy function, occurring after all modules
// are unloaded
virtual void Destroy() = 0;
};
//-----------------------------------------------------------------------------
// This class represents a group of app systems that all have the same lifetime
// that need to be connected/initialized, etc. in a well-defined order
//-----------------------------------------------------------------------------
class CAppSystemGroup : public IAppSystemGroup
{
public:
// Used to determine where we exited out from the system
enum AppSystemGroupStage_t
{
CREATION = 0,
DEPENDENCIES,
CONNECTION,
PREINITIALIZATION,
INITIALIZATION,
POSTINITIALIZATION,
RUNNING,
PRESHUTDOWN,
SHUTDOWN,
POSTSHUTDOWN,
DISCONNECTION,
DESTRUCTION,
APPSYSTEM_GROUP_STAGE_COUNT,
NONE, // This means no error
};
public:
// constructor
CAppSystemGroup( CAppSystemGroup *pParentAppSystem = NULL );
// Runs the app system group.
// First, modules are loaded, next they are connected, followed by initialization
// Then Main() is run
// Then modules are shut down, disconnected, and unloaded
int Run( );
// Use this version in cases where you can't control the main loop and
// expect to be ticked
virtual int Startup();
virtual void Shutdown();
// Default implementations...
virtual bool PostInit() { return true; }
virtual void PreShutdown() { }
// Returns the stage at which the app system group ran into an error
AppSystemGroupStage_t GetCurrentStage() const;
int ReloadModule( const char * pDLLName );
protected:
// These methods are meant to be called by derived classes of CAppSystemGroup
// Methods to load + unload DLLs
AppModule_t LoadModule( const char *pDLLName );
AppModule_t LoadModule( CreateInterfaceFn factory );
// Method to add various global singleton systems
IAppSystem *AddSystem( AppModule_t module, const char *pInterfaceName );
void AddSystem( IAppSystem *pAppSystem, const char *pInterfaceName );
// Simpler method of doing the LoadModule/AddSystem thing.
// Make sure the last AppSystemInfo has a NULL module name
bool AddSystems( AppSystemInfo_t *pSystems );
// Adds a factory to the system so other stuff can query it. Triggers a connect systems
void AddNonAppSystemFactory( CreateInterfaceFn fn );
// Removes a factory, triggers a disconnect call if it succeeds
void RemoveNonAppSystemFactory( CreateInterfaceFn fn );
// Causes the systems to reconnect to an interface
void ReconnectSystems( const char *pInterfaceName );
// Method to look up a particular named system...
void *FindSystem( const char *pInterfaceName );
// Creates the app window (windowed app only)
virtual void *CreateAppWindow( void *hInstance, const char *pTitle, bool bWindowed, int w, int h, bool bResizing );
void SetAppWindowTitle( void* hWnd, const char *pTitle );
// Gets at a class factory for the topmost appsystem group in an appsystem stack
static CreateInterfaceFn GetFactory();
private:
struct Module_t
{
CSysModule *m_pModule;
CreateInterfaceFn m_Factory;
char *m_pModuleName;
};
typedef CUtlStringMap< CUtlSymbolTable > LibraryDependencies_t;
int OnStartup();
void OnShutdown();
void UnloadAllModules( );
void RemoveAllSystems();
// Method to load all dependent systems
bool LoadDependentSystems();
// Method to connect/disconnect all systems
bool ConnectSystems( );
void DisconnectSystems();
// Method to initialize/shutdown all systems
InitReturnVal_t InitSystems();
void ShutdownSystems();
// Gets at the parent appsystem group
CAppSystemGroup *GetParent();
// Loads a module the standard way
virtual CSysModule *LoadModuleDLL( const char *pDLLName );
void ComputeDependencies( LibraryDependencies_t &depend );
void SortDependentLibraries( LibraryDependencies_t &depend );
const char *FindSystemName( int nIndex );
static bool SortLessFunc( const int &left, const int &right );
void ReportStartupFailure( int nErrorStage, int nSysIndex );
CUtlVector<Module_t> m_Modules;
CUtlVector<IAppSystem*> m_Systems;
CUtlVector<CreateInterfaceFn> m_NonAppSystemFactories;
CUtlDict<int, unsigned short> m_SystemDict;
CAppSystemGroup *m_pParentAppSystem;
AppSystemGroupStage_t m_nCurrentStage;
static LibraryDependencies_t *sm_pSortDependencies;
friend void *AppSystemCreateInterfaceFn(const char *pName, int *pReturnCode);
friend class CSteamAppSystemGroup;
};
//-----------------------------------------------------------------------------
// This class represents a group of app systems that are loaded through steam
//-----------------------------------------------------------------------------
class CSteamAppSystemGroup : public CAppSystemGroup
{
public:
CSteamAppSystemGroup( IFileSystem *pFileSystem = NULL, CAppSystemGroup *pParentAppSystem = NULL );
// Used by CSteamApplication to set up necessary pointers if we can't do it in the constructor
void Setup( IFileSystem *pFileSystem, CAppSystemGroup *pParentAppSystem );
protected:
// Sets up the search paths
bool SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool );
// Returns the game info path. Only works if you've called SetupSearchPaths first
const char *GetGameInfoPath() const;
private:
virtual CSysModule *LoadModuleDLL( const char *pDLLName );
IFileSystem *m_pFileSystem;
char m_pGameInfoPath[ MAX_PATH ];
};
//-----------------------------------------------------------------------------
// Helper empty decorator implementation of an IAppSystemGroup
//-----------------------------------------------------------------------------
template< class CBaseClass >
class CDefaultAppSystemGroup : public CBaseClass
{
public:
virtual bool Create( ) { return true; }
virtual bool PreInit() { return true; }
virtual bool PostInit() { return true; }
virtual void PreShutdown() { }
virtual void PostShutdown() {}
virtual void Destroy() {}
};
//-----------------------------------------------------------------------------
// Special helper for game info directory suggestion
//-----------------------------------------------------------------------------
class CFSSteamSetupInfo; // Forward declaration
//
// SuggestGameInfoDirFn_t
// Game info suggestion function.
// Provided by the application to possibly detect the suggested game info
// directory and initialize all the game-info-related systems appropriately.
// Parameters:
// pFsSteamSetupInfo steam file system setup information if available.
// pchPathBuffer buffer to hold game info directory path on return.
// nBufferLength length of the provided buffer to hold game info directory path.
// pbBubbleDirectories should contain "true" on return to bubble the directories up searching for game info file.
// Return values:
// Returns "true" if the game info directory path suggestion is available and
// was successfully copied into the provided buffer.
// Returns "false" otherwise, interpreted that no suggestion will be used.
//
typedef bool ( * SuggestGameInfoDirFn_t ) ( CFSSteamSetupInfo const *pFsSteamSetupInfo, char *pchPathBuffer, int nBufferLength, bool *pbBubbleDirectories );
//
// SetSuggestGameInfoDirFn
// Installs the supplied game info directory suggestion function.
// Parameters:
// pfnNewFn the new game info directory suggestion function.
// Returns:
// The previously installed suggestion function or NULL if none was installed before.
// This function never fails.
//
SuggestGameInfoDirFn_t SetSuggestGameInfoDirFn( SuggestGameInfoDirFn_t pfnNewFn );
#endif // APPSYSTEMGROUP_H

View File

@@ -0,0 +1,51 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Material editor
//=============================================================================
#ifndef VGUIMATSYSAPP_H
#define VGUIMATSYSAPP_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/matsysapp.h"
FORWARD_DECLARE_HANDLE( InputContextHandle_t );
//-----------------------------------------------------------------------------
// The application object
//-----------------------------------------------------------------------------
class CVguiMatSysApp : public CMatSysApp
{
typedef CMatSysApp BaseClass;
public:
CVguiMatSysApp();
// Methods of IApplication
virtual bool Create();
virtual bool PreInit();
virtual bool PostInit();
virtual void PreShutdown();
virtual void PostShutdown();
virtual void Destroy();
InputContextHandle_t GetAppInputContext();
private:
InputContextHandle_t m_hAppInputContext;
};
#endif // VGUIMATSYSAPP_H

View File

@@ -0,0 +1,123 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: An application framework
//
// $Revision: $
// $NoKeywords: $
//===========================================================================//
#ifndef IAPPSYSTEM_H
#define IAPPSYSTEM_H
#ifdef COMPILER_MSVC
#pragma once
#endif
#include "tier1/interface.h"
#include "interfaces/interfaces.h"
//-----------------------------------------------------------------------------
// Specifies a module + interface name for initialization
//-----------------------------------------------------------------------------
struct AppSystemInfo_t
{
const char *m_pModuleName;
const char *m_pInterfaceName;
};
//-----------------------------------------------------------------------------
// Client systems are singleton objects in the client codebase responsible for
// various tasks
// The order in which the client systems appear in this list are the
// order in which they are initialized and updated. They are shut down in
// reverse order from which they are initialized.
//-----------------------------------------------------------------------------
enum InitReturnVal_t
{
INIT_FAILED = 0,
INIT_OK,
INIT_LAST_VAL,
};
enum AppSystemTier_t
{
APP_SYSTEM_TIER0 = 0,
APP_SYSTEM_TIER1,
APP_SYSTEM_TIER2,
APP_SYSTEM_TIER3,
APP_SYSTEM_TIER_OTHER,
};
abstract_class IAppSystem
{
public:
// Here's where the app systems get to learn about each other
virtual bool Connect( CreateInterfaceFn factory ) = 0;
virtual void Disconnect() = 0;
// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void *QueryInterface( const char *pInterfaceName ) = 0;
// Init, shutdown
virtual InitReturnVal_t Init() = 0;
virtual void Shutdown() = 0;
// Returns all dependent libraries
virtual const AppSystemInfo_t* GetDependencies() {return NULL;}
// Returns the tier
virtual AppSystemTier_t GetTier() {return APP_SYSTEM_TIER_OTHER;}
// Reconnect to a particular interface
virtual void Reconnect( CreateInterfaceFn factory, const char *pInterfaceName ) {}
// Is this appsystem a singleton? (returns false if there can be multiple instances of this interface)
virtual bool IsSingleton() { return true; }
};
//-----------------------------------------------------------------------------
// Helper empty implementation of an IAppSystem
//-----------------------------------------------------------------------------
template< class IInterface >
class CBaseAppSystem : public IInterface
{
public:
// Here's where the app systems get to learn about each other
virtual bool Connect( CreateInterfaceFn factory ) { return true; }
virtual void Disconnect() {}
// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void *QueryInterface( const char *pInterfaceName ) { return NULL; }
// Init, shutdown
virtual InitReturnVal_t Init() { return INIT_OK; }
virtual void Shutdown() {}
virtual const AppSystemInfo_t* GetDependencies() { return NULL; }
virtual AppSystemTier_t GetTier() { return APP_SYSTEM_TIER_OTHER; }
virtual void Reconnect( CreateInterfaceFn factory, const char *pInterfaceName )
{
ReconnectInterface( factory, pInterfaceName );
}
};
//-----------------------------------------------------------------------------
// Helper implementation of an IAppSystem for tier0
//-----------------------------------------------------------------------------
template< class IInterface >
class CTier0AppSystem : public CBaseAppSystem< IInterface >
{
};
#endif // IAPPSYSTEM_H

View File

@@ -0,0 +1,260 @@
//================ Copyright (c) 1996-2009 Valve Corporation. All Rights Reserved. =================
//
//
//
//==================================================================================================
#ifndef ICOCOAMGR_H
#define ICOCOAMGR_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/threadtools.h"
#include "appframework/IAppSystem.h"
#include "glmgr/glmgr.h"
// if you rev this version also update materialsystem/cmaterialsystem.cpp CMaterialSystem::Connect as it defines the string directly
#define COCOAMGR_INTERFACE_VERSION "CocoaMgrInterface006"
enum CocoaEventType_t
{
CocoaEvent_KeyDown,
CocoaEvent_KeyUp,
CocoaEvent_MouseButtonDown,
CocoaEvent_MouseMove,
CocoaEvent_MouseButtonUp,
CocoaEvent_AppActivate,
CocoaEvent_MouseScroll,
CocoaEvent_AppQuit
};
// enum values need to match bit-shifting logic in CInputSystem::UpdateMouseButtonState and
// the codes from NSEvent pressedMouseButtons, turns out the two are in agreement right now
enum CocoaMouseButton_t
{
COCOABUTTON_LEFT = 1 << 0,
COCOABUTTON_RIGHT = 1 << 1,
COCOABUTTON_MIDDLE = 1 << 2,
COCOABUTTON_4 = 1 << 3,
COCOABUTTON_5 = 1 << 4,
};
enum ECocoaKeyModifier
{
eCapsLockKey,
eShiftKey,
eControlKey,
eAltKey, // aka option
eCommandKey
};
class CCocoaEvent
{
public:
CocoaEventType_t m_EventType;
int m_VirtualKeyCode;
wchar_t m_UnicodeKey;
wchar_t m_UnicodeKeyUnmodified;
uint m_ModifierKeyMask; //
int m_MousePos[2];
int m_MouseButtonFlags; // Current state of the mouse buttons. See COCOABUTTON_xxxx.
uint m_nMouseClickCount;
int m_MouseButton; // which of the CocoaMouseButton_t buttons this is for from above
};
class CShowPixelsParams
{
public:
GLuint m_srcTexName;
int m_width,m_height;
bool m_vsyncEnable;
bool m_fsEnable; // want receiving view to be full screen. for now, just target the main screen. extend later.
bool m_useBlit; // use FBO blit - sending context says it is available.
bool m_noBlit; // the back buffer has already been populated by the caller (perhaps via direct MSAA resolve from multisampled RT tex)
bool m_onlySyncView; // react to full/windowed state change only, do not present bits
};
#define kMaxCrawlFrames 100
#define kMaxCrawlText (kMaxCrawlFrames * 256)
class CStackCrawlParams
{
public:
uint m_frameLimit; // input: max frames to retrieve
uint m_frameCount; // output: frames found
void *m_crawl[kMaxCrawlFrames]; // call site addresses
char *m_crawlNames[kMaxCrawlFrames]; // pointers into text following, one per decoded name
char m_crawlText[kMaxCrawlText];
};
struct GLMRendererInfoFields;
class GLMDisplayDB;
class ICocoaMgr : public IAppSystem
{
public:
virtual bool Connect( CreateInterfaceFn factory ) = 0;
virtual void Disconnect() = 0;
virtual void *QueryInterface( const char *pInterfaceName ) = 0;
// Init, shutdown
virtual InitReturnVal_t Init() = 0;
virtual void Shutdown() = 0;
// Create the window.
virtual bool CreateGameWindow( const char *pTitle, bool bWindowed, int width, int height ) = 0;
// Get the NSWindow*.
// virtual void* GetNSWindow() = 0;
// Get the NSGLContext for a window's main view - note this is the carbon windowref as an argument
virtual PseudoNSGLContextPtr GetNSGLContextForWindow( void* windowref ) = 0;
// Get the next N events. The function returns the number of events that were filled into your array.
virtual int GetEvents( CCocoaEvent *pEvents, int nMaxEventsToReturn, bool debugEvents = false ) = 0;
// Set the mouse cursor position.
virtual void SetCursorPosition( int x, int y ) = 0;
virtual void *GetWindowRef() = 0;
virtual void ShowPixels( CShowPixelsParams *params ) = 0;
virtual void MoveWindow( int x, int y ) = 0;
virtual void SizeWindow( int width, int tall ) = 0;
virtual void PumpWindowsMessageLoop() = 0;
virtual void GetStackCrawl( CStackCrawlParams *params ) = 0;
virtual void DestroyGameWindow() = 0;
virtual void SetApplicationIcon( const char *pchAppIconFile ) = 0;
virtual void GetMouseDelta( int &x, int &y, bool bIgnoreNextMouseDelta = false ) = 0;
virtual void RenderedSize( uint &width, uint &height, bool set ) = 0; // either set or retrieve rendered size value (from dxabstract)
virtual void DisplayedSize( uint &width, uint &height ) = 0; // query backbuffer size (window size whether FS or windowed)
virtual void GetDesiredPixelFormatAttribsAndRendererInfo( uint **ptrOut, uint *countOut, GLMRendererInfoFields *rendInfoOut ) = 0;
virtual GLMDisplayDB *GetDisplayDB( void ) = 0;
virtual void WaitUntilUserInput( int msSleepTime ) = 0;
};
//===============================================================================
// modes, displays, and renderers
// think of renderers as being at the top of a tree.
// each renderer has displays hanging off of it.
// each display has modes hanging off of it.
// the tree is populated on demand and then queried as needed.
//===============================================================================
// GLMDisplayModeInfoFields is in glmdisplay.h
class GLMDisplayMode
{
public:
GLMDisplayModeInfoFields m_info;
GLMDisplayMode( uint width, uint height, uint refreshHz );
~GLMDisplayMode( void );
void Dump( int which );
};
//===============================================================================
// GLMDisplayInfoFields is in glmdisplay.h
class GLMDisplayInfo
{
public:
GLMDisplayInfoFields m_info;
CUtlVector< GLMDisplayMode* > *m_modes; // starts out NULL, set by PopulateModes
GLMDisplayInfo( CGDirectDisplayID displayID, CGOpenGLDisplayMask displayMask );
~GLMDisplayInfo( void );
void PopulateModes( void );
void Dump( int which );
};
//===============================================================================
// GLMRendererInfoFields is in glmdisplay.h
class GLMRendererInfo
{
public:
GLMRendererInfoFields m_info;
CUtlVector< GLMDisplayInfo* > *m_displays; // starts out NULL, set by PopulateDisplays
GLMRendererInfo ( GLMRendererInfoFields *info );
~GLMRendererInfo ( void );
void PopulateDisplays( void );
void Dump( int which );
};
//===============================================================================
// this is just a tuple describing fake adapters which are really renderer/display pairings.
// dxabstract bridges the gap between the d3d adapter-centric world and the GL renderer+display world.
// this makes it straightforward to handle cases like two video cards with two displays on one, and one on the other -
// you get three fake adapters which represent each useful screen.
// the constraint that dxa will have to follow though, is that if the user wants to change their
// display selection for full screen, they would only be able to pick on that has the same underlying renderer.
// can't change fakeAdapter from one to another with different GL renderer under it. Screen hop but no card hop.
struct GLMFakeAdapter
{
int m_rendererIndex;
int m_displayIndex;
};
class GLMDisplayDB
{
public:
CUtlVector< GLMRendererInfo* > *m_renderers; // starts out NULL, set by PopulateRenderers
CUtlVector< GLMFakeAdapter > m_fakeAdapters;
GLMDisplayDB ( void );
~GLMDisplayDB ( void );
virtual void PopulateRenderers( void );
virtual void PopulateFakeAdapters( uint realRendererIndex ); // fake adapters = one real adapter times however many displays are on it
virtual void Populate( void );
// The info-get functions return false on success.
virtual int GetFakeAdapterCount( void );
virtual bool GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut );
virtual int GetRendererCount( void );
virtual bool GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut );
virtual int GetDisplayCount( int rendererIndex );
virtual bool GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut );
virtual int GetModeCount( int rendererIndex, int displayIndex );
virtual bool GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut );
virtual void Dump( void );
};
#endif // ICOCOAMGR_H

View File

@@ -0,0 +1,37 @@
//================ Copyright (c) 1996-2009 Valve Corporation. All Rights Reserved. =================
//
//
//
//==================================================================================================
#ifndef IGLXMGR_H
#define IGLXMGR_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/basetypes.h"
#define GLXMGR_INTERFACE_VERSION "GLXMgrInterface001"
DECLARE_POINTER_HANDLE( GLXMgrContext_t );
class IGLXMgr
{
public:
// Window creation.
// pAttributes are GLX_ attributes that go to glXChooseVisual.
virtual void* CreateWindow( const char *pTitle, bool bWindowed, int width, int height ) = 0;
// GL context management.
virtual GLXMgrContext_t GetMainContext() = 0;
virtual GLXMgrContext_t CreateExtraContext() = 0;
virtual void DeleteContext( GLXMgrContext_t hContext ) = 0;
virtual void MakeContextCurrent( GLXMgrContext_t hContext ) = 0;
};
#endif // IGLXMGR_H

View File

@@ -0,0 +1,183 @@
//================ Copyright (c) 1996-2009 Valve Corporation. All Rights Reserved. =================
//
// ilaunchermgr.h
//
//==================================================================================================
#ifndef ILAUNCHERMGR_H
#define ILAUNCHERMGR_H
#ifdef _WIN32
#pragma once
#endif
#if defined( USE_SDL ) || defined( OSX ) || defined( LINUX )
// Purpose: The overlay doesn't properly work on OS X 64-bit because a bunch of
// Cocoa functions that we hook were never ported to 64-bit. Until that is fixed,
// we basically have to work around this by making sure the cursor is visible
// and set to something that is reasonable for usage in the overlay.
#if ( defined( OSX ) && defined( PLATFORM_64BITS ) && !defined( NO_STEAM ) )
#define WITH_OVERLAY_CURSOR_VISIBILITY_WORKAROUND 1
#endif
#include "tier0/threadtools.h"
#include "appframework/iappsystem.h"
#include "inputsystem/iinputsystem.h"
#include "togl/glmgrbasics.h"
#include "togl/glmdisplay.h"
// if you rev this version also update materialsystem/cmaterialsystem.cpp CMaterialSystem::Connect as it defines the string directly
#if defined( USE_SDL )
#define SDLMGR_INTERFACE_VERSION "SDLMgrInterface001"
#elif defined( OSX )
#define COCOAMGR_INTERFACE_VERSION "CocoaMgrInterface006"
#endif
class GLMDisplayDB;
class CCocoaEvent;
class CShowPixelsParams;
class CStackCrawlParams;
#if defined( USE_SDL )
typedef struct SDL_Cursor SDL_Cursor;
#endif
class ILauncherMgr : public IAppSystem
{
public:
virtual bool Connect( CreateInterfaceFn factory ) = 0;
virtual void Disconnect() = 0;
virtual void *QueryInterface( const char *pInterfaceName ) = 0;
// Init, shutdown
virtual InitReturnVal_t Init() = 0;
virtual void Shutdown() = 0;
// Create the window.
#ifdef USE_SDL
virtual bool CreateGameWindow( const char *pTitle, bool bWindowed, int width, int height, bool bDesktopFriendlyFullscreen ) = 0;
#else
virtual bool CreateGameWindow( const char *pTitle, bool bWindowed, int width, int height ) = 0;
#endif
virtual void GetDesiredPixelFormatAttribsAndRendererInfo( uint **ptrOut, uint *countOut, GLMRendererInfoFields *rendInfoOut ) = 0;
// Get the NSGLContext for a window's main view - note this is the carbon windowref as an argument
virtual PseudoGLContextPtr GetGLContextForWindow( void* windowref ) = 0;
// Get the next N events. The function returns the number of events that were filled into your array.
virtual int GetEvents( CCocoaEvent *pEvents, int nMaxEventsToReturn, bool debugEvents = false ) = 0;
// Set the mouse cursor position.
virtual void SetCursorPosition( int x, int y ) = 0;
virtual void ShowPixels( CShowPixelsParams *params ) = 0;
#ifdef USE_SDL
virtual void SetWindowFullScreen( bool bFullScreen, int nWidth, int nHeight, bool bDesktopFriendlyFullscreen ) = 0;
#else
virtual void SetWindowFullScreen( bool bFullScreen, int nWidth, int nHeight ) = 0;
#endif
virtual bool IsWindowFullScreen() = 0;
virtual void MoveWindow( int x, int y ) = 0;
virtual void SizeWindow( int width, int tall ) = 0;
virtual void PumpWindowsMessageLoop() = 0;
virtual void DestroyGameWindow() = 0;
virtual void SetApplicationIcon( const char *pchAppIconFile ) = 0;
virtual void GetMouseDelta( int &x, int &y, bool bIgnoreNextMouseDelta = false ) = 0;
virtual void GetNativeDisplayInfo( int nDisplay, uint &nWidth, uint &nHeight, uint &nRefreshHz ) = 0; // Retrieve the size of the monitor (desktop)
virtual void RenderedSize( uint &width, uint &height, bool set ) = 0; // either set or retrieve rendered size value (from dxabstract)
virtual void DisplayedSize( uint &width, uint &height ) = 0; // query backbuffer size (window size whether FS or windowed)
virtual GLMDisplayDB *GetDisplayDB( void ) = 0;
virtual void WaitUntilUserInput( int msSleepTime ) = 0;
virtual PseudoGLContextPtr GetMainContext() = 0;
virtual PseudoGLContextPtr CreateExtraContext() = 0;
virtual void DeleteContext( PseudoGLContextPtr hContext ) = 0;
virtual bool MakeContextCurrent( PseudoGLContextPtr hContext ) = 0;
virtual void GetStackCrawl( CStackCrawlParams *params ) = 0;
virtual void *GetWindowRef() = 0;
virtual void SetMouseVisible( bool bState ) = 0;
#ifdef USE_SDL
virtual int GetActiveDisplayIndex() = 0;
virtual void SetMouseCursor( SDL_Cursor *hCursor ) = 0;
virtual void SetForbidMouseGrab( bool bForbidMouseGrab ) = 0;
virtual void OnFrameRendered() = 0;
#endif
#ifndef OSX
virtual void SetGammaRamp( const uint16 *pRed, const uint16 *pGreen, const uint16 *pBlue ) = 0;
#endif
#if WITH_OVERLAY_CURSOR_VISIBILITY_WORKAROUND
virtual void ForceSystemCursorVisible() = 0;
virtual void UnforceSystemCursorVisible() = 0;
#endif
virtual double GetPrevGLSwapWindowTime() = 0;
};
extern ILauncherMgr *g_pLauncherMgr;
enum CocoaEventType_t
{
CocoaEvent_KeyDown,
CocoaEvent_KeyUp,
CocoaEvent_MouseButtonDown,
CocoaEvent_MouseMove,
CocoaEvent_MouseButtonUp,
CocoaEvent_AppActivate,
CocoaEvent_MouseScroll,
CocoaEvent_AppQuit,
CocoaEvent_Deleted, // Event was one of the above, but has been handled and should be ignored now.
};
// enum values need to match bit-shifting logic in CInputSystem::UpdateMouseButtonState and
// the codes from NSEvent pressedMouseButtons, turns out the two are in agreement right now
enum CocoaMouseButton_t
{
COCOABUTTON_LEFT = 1 << 0,
COCOABUTTON_RIGHT = 1 << 1,
COCOABUTTON_MIDDLE = 1 << 2,
COCOABUTTON_4 = 1 << 3,
COCOABUTTON_5 = 1 << 4,
};
enum ECocoaKeyModifier
{
eCapsLockKey,
eShiftKey,
eControlKey,
eAltKey, // aka option
eCommandKey
};
class CCocoaEvent
{
public:
CocoaEventType_t m_EventType;
int m_VirtualKeyCode;
wchar_t m_UnicodeKey;
wchar_t m_UnicodeKeyUnmodified;
uint m_ModifierKeyMask; //
int m_MousePos[2];
int m_MouseButtonFlags; // Current state of the mouse buttons. See COCOABUTTON_xxxx.
uint m_nMouseClickCount;
int m_MouseButton; // which of the CocoaMouseButton_t buttons this is for from above
};
#endif // defined( USE_SDL ) || defined( OSX ) || defined( LINUX)
#endif // ILAUNCHERMGR_H

View File

@@ -0,0 +1,121 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Used for material system apps
//=============================================================================
#ifndef MATERIALSYSTEM2APP_H
#define MATERIALSYSTEM2APP_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/tier2app.h"
#include "tier0/platwindow.h"
#include "rendersystem/irenderdevice.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
FORWARD_DECLARE_HANDLE( SwapChainHandle_t );
//-----------------------------------------------------------------------------
// The application object
//-----------------------------------------------------------------------------
class CMaterialSystem2App : public CTier2SteamApp, public IRenderDeviceSetup
{
typedef CTier2SteamApp BaseClass;
public:
enum RenderSystemDLL_t
{
RENDER_SYSTEM_DX9 = 0,
RENDER_SYSTEM_DX11,
RENDER_SYSTEM_GL,
RENDER_SYSTEM_X360,
};
public:
CMaterialSystem2App();
// Methods of IApplication
virtual bool Create();
virtual bool PreInit();
virtual bool PostInit();
virtual void PreShutdown();
virtual void Destroy();
// Returns the window handle
PlatWindow_t GetAppWindow();
// Gets the render system we're running on
RenderSystemDLL_t GetRenderSystem() const;
// Returns the number of threads our thread pool is using
int GetThreadCount() const;
// Creates a 3D-capable window
SwapChainHandle_t Create3DWindow( const char *pTitle, int nWidth, int nHeight, bool bResizing, bool bFullscreen, bool bAcceptsInput );
protected:
void AppPumpMessages();
// Sets up the game path
bool SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool );
private:
// Inherited from IRenderDeviceSetup
virtual bool CreateRenderDevice();
private:
// Returns the app name
virtual const char *GetAppName() = 0;
virtual bool IsConsoleApp() { return false; }
bool AddRenderSystem();
void ApplyModSettings( );
bool CreateMainWindow( bool bResizing );
bool CreateMainConsoleWindow();
SwapChainHandle_t m_hSwapChain;
int m_nThreadCount;
RenderSystemDLL_t m_nRenderSystem;
CreateInterfaceFn m_RenderFactory;
};
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Gets the render system we're running on
//-----------------------------------------------------------------------------
inline CMaterialSystem2App::RenderSystemDLL_t CMaterialSystem2App::GetRenderSystem() const
{
return m_nRenderSystem;
}
//-----------------------------------------------------------------------------
// Returns the number of threads our thread pool is using
//-----------------------------------------------------------------------------
inline int CMaterialSystem2App::GetThreadCount() const
{
return m_nThreadCount;
}
#endif // MATERIALSYSTEM2APP_H

View File

@@ -0,0 +1,68 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Used for material system apps
//=============================================================================
#ifndef MATSYSAPP_H
#define MATSYSAPP_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/tier2app.h"
//-----------------------------------------------------------------------------
// The application object
//-----------------------------------------------------------------------------
class CMatSysApp : public CTier2SteamApp
{
typedef CTier2SteamApp BaseClass;
public:
CMatSysApp();
// Methods of IApplication
virtual bool Create();
virtual bool PreInit();
virtual void PostShutdown();
virtual void Destroy();
// Returns the window handle (HWND in Win32)
void* GetAppWindow();
// Gets the window size
int GetWindowWidth() const;
int GetWindowHeight() const;
protected:
void AppPumpMessages();
// Sets the video mode
bool SetVideoMode( );
// Sets up the game path
bool SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool );
private:
// Returns the app name
virtual const char *GetAppName() = 0;
virtual bool AppUsesReadPixels() { return false; }
void *m_HWnd;
int m_nWidth;
int m_nHeight;
};
#endif // MATSYSAPP_H

View File

@@ -0,0 +1,89 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The application object for apps that use tier2
//=============================================================================
#ifndef TIER2APP_H
#define TIER2APP_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/AppFramework.h"
#include "tier2/tier2dm.h"
#include "tier1/convar.h"
//-----------------------------------------------------------------------------
// The application object for apps that use tier2
//-----------------------------------------------------------------------------
class CTier2SteamApp : public CSteamAppSystemGroup
{
typedef CSteamAppSystemGroup BaseClass;
public:
// Methods of IApplication
virtual bool PreInit()
{
CreateInterfaceFn factory = GetFactory();
ConnectTier1Libraries( &factory, 1 );
ConVar_Register( 0 );
ConnectTier2Libraries( &factory, 1 );
return true;
}
virtual void PostShutdown()
{
DisconnectTier2Libraries();
ConVar_Unregister();
DisconnectTier1Libraries();
}
virtual void Destroy()
{
}
};
//-----------------------------------------------------------------------------
// The application object for apps that use tier2 and datamodel
//-----------------------------------------------------------------------------
class CTier2DmSteamApp : public CTier2SteamApp
{
typedef CTier2SteamApp BaseClass;
public:
// Methods of IApplication
virtual bool PreInit()
{
if ( !BaseClass::PreInit() )
return false;
CreateInterfaceFn factory = GetFactory();
if ( !ConnectDataModel( factory ) )
return false;
InitReturnVal_t nRetVal = InitDataModel();
return ( nRetVal == INIT_OK );
}
virtual void PostShutdown()
{
ShutdownDataModel();
DisconnectDataModel();
BaseClass::PostShutdown();
}
};
#endif // TIER2APP_H

View File

@@ -0,0 +1,121 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The application objects for apps that use tier3
//=============================================================================
#ifndef TIER3APP_H
#define TIER3APP_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/tier2app.h"
#include "tier3/tier3.h"
#include "vgui_controls/Controls.h"
//-----------------------------------------------------------------------------
// The application object for apps that use tier3
//-----------------------------------------------------------------------------
class CTier3SteamApp : public CTier2SteamApp
{
typedef CTier2SteamApp BaseClass;
public:
// Methods of IApplication
virtual bool PreInit()
{
if ( !BaseClass::PreInit() )
return false;
CreateInterfaceFn factory = GetFactory();
ConnectTier3Libraries( &factory, 1 );
return true;
}
virtual void PostShutdown()
{
DisconnectTier3Libraries();
BaseClass::PostShutdown();
}
};
//-----------------------------------------------------------------------------
// The application object for apps that use tier3
//-----------------------------------------------------------------------------
class CTier3DmSteamApp : public CTier2DmSteamApp
{
typedef CTier2DmSteamApp BaseClass;
public:
// Methods of IApplication
virtual bool PreInit()
{
if ( !BaseClass::PreInit() )
return false;
CreateInterfaceFn factory = GetFactory();
ConnectTier3Libraries( &factory, 1 );
return true;
}
virtual void PostShutdown()
{
DisconnectTier3Libraries();
BaseClass::PostShutdown();
}
};
//-----------------------------------------------------------------------------
// The application object for apps that use vgui
//-----------------------------------------------------------------------------
class CVguiSteamApp : public CTier3SteamApp
{
typedef CTier3SteamApp BaseClass;
public:
// Methods of IApplication
virtual bool PreInit()
{
if ( !BaseClass::PreInit() )
return false;
CreateInterfaceFn factory = GetFactory();
return vgui::VGui_InitInterfacesList( "CVguiSteamApp", &factory, 1 );
}
};
//-----------------------------------------------------------------------------
// The application object for apps that use vgui
//-----------------------------------------------------------------------------
class CVguiDmSteamApp : public CTier3DmSteamApp
{
typedef CTier3DmSteamApp BaseClass;
public:
// Methods of IApplication
virtual bool PreInit()
{
if ( !BaseClass::PreInit() )
return false;
CreateInterfaceFn factory = GetFactory();
return vgui::VGui_InitInterfacesList( "CVguiSteamApp", &factory, 1 );
}
};
#endif // TIER3APP_H

View File

@@ -0,0 +1,51 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Material editor
//=============================================================================
#ifndef VGUIMATERIALSYSTEM2APP_H
#define VGUIMATERIALSYSTEM2APP_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/materialsystem2app.h"
FORWARD_DECLARE_HANDLE( InputContextHandle_t );
//-----------------------------------------------------------------------------
// The application object
//-----------------------------------------------------------------------------
class CVGuiMaterialSystem2App : public CMaterialSystem2App
{
typedef CMaterialSystem2App BaseClass;
public:
CVGuiMaterialSystem2App();
// Methods of IApplication
virtual bool Create();
virtual bool PreInit();
virtual bool PostInit();
virtual void PreShutdown();
virtual void PostShutdown();
virtual void Destroy();
InputContextHandle_t GetAppInputContext();
private:
InputContextHandle_t m_hAppInputContext;
};
#endif // VGUIMATERIALSYSTEM2APP_H

69
public/arraystack.h Normal file
View File

@@ -0,0 +1,69 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef ARRAYSTACK_H
#define ARRAYSTACK_H
#pragma once
#include <assert.h>
#include "List.h"
template <class T> class ArrayStack
{
protected:
T *data;
int m_stackDepth;
int m_maxNumElements;
public:
ArrayStack( int maxNumElements )
{
data = new T[maxNumElements];
m_maxNumElements = maxNumElements;
m_stackDepth = 0;
assert( data );
}
void Push( T elem )
{
data[m_stackDepth++] = elem;
if( m_stackDepth > m_maxNumElements )
{
printf( "ArrayStack overflow\n" );
assert( 0 );
}
}
T Pop( void )
{
if( m_stackDepth == 0 )
{
printf( "ArrayStack underflow\n" );
assert( 0 );
}
return data[--m_stackDepth];
}
bool IsEmpty()
{
return ( m_stackDepth == 0 );
}
int GetDepth()
{
return m_stackDepth;
}
};
#endif // ARRAYSTACK_H

23
public/assetpickerdefs.h Normal file
View File

@@ -0,0 +1,23 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
// Structures used when invoking the asset picker.
//
//==================================================================================================
#ifndef ASSETPICKERDEFS_H
#define ASSETPICKERDEFS_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Used when providing the asset picker with a list of used assets.
//-----------------------------------------------------------------------------
struct AssetUsageInfo_t
{
CUtlString m_assetName;
int m_nTimesUsed;
};
#endif // ASSETPICKERDEFS_H

144
public/ati_compress.h Normal file
View File

@@ -0,0 +1,144 @@
//////////////////////////////////////////////////////////////////////////////
//
// ATI Technologies Inc.
// 1 Commerce Valley Drive East
// Markham, Ontario
// CANADA L3T 7X6
//
// File Name: ATI_Compress.h
// Description: A library to compress/decompress textures
//
// Copyright (c) 2004-2006 ATI Technologies Inc.
//
// Version: 1.4
//
// Developer: Seth Sowerby
// Email: gputools.support@amd.com
//
//////////////////////////////////////////////////////////////////////////////
#ifndef ATI_COMPRESS
#define ATI_COMPRESS
#define ATI_COMPRESS_VERSION_MAJOR 1
#define ATI_COMPRESS_VERSION_MINOR 4
typedef unsigned long ATI_TC_DWORD;
typedef unsigned short ATI_TC_WORD;
typedef unsigned char ATI_TC_BYTE;
#if defined(WIN32) || defined(_WIN64)
# define ATI_TC_API __cdecl
#else
# define ATI_TC_API
#endif
#ifdef ATI_COMPRESS_INTERNAL_BUILD
#include "ATI_Compress_Internal.h"
#else // ATI_COMPRESS_INTERNAL_BUILD
typedef enum
{
ATI_TC_FORMAT_ARGB_8888,
ATI_TC_FORMAT_ARGB_2101010,
ATI_TC_FORMAT_ARGB_16,
ATI_TC_FORMAT_ARGB_16F,
ATI_TC_FORMAT_ARGB_32F,
ATI_TC_FORMAT_DXT1,
ATI_TC_FORMAT_DXT3,
ATI_TC_FORMAT_DXT5,
ATI_TC_FORMAT_DXT5_xGBR,
ATI_TC_FORMAT_DXT5_RxBG,
ATI_TC_FORMAT_DXT5_RBxG,
ATI_TC_FORMAT_DXT5_xRBG,
ATI_TC_FORMAT_DXT5_RGxB,
ATI_TC_FORMAT_DXT5_xGxR,
ATI_TC_FORMAT_ATI1N,
ATI_TC_FORMAT_ATI2N,
ATI_TC_FORMAT_ATI2N_XY,
ATI_TC_FORMAT_ATI2N_DXT5,
ATI_TC_FORMAT_MAX = ATI_TC_FORMAT_ATI2N_DXT5
} ATI_TC_FORMAT;
typedef struct _ATI_TC_CompressOptions
{
ATI_TC_DWORD dwSize; /* Size of this structure */
/* Channel Weightings */
/* With swizzled formats the weighting applies to the data within the specified channel */
/* not the channel itself. */
BOOL bUseChannelWeighting;
double fWeightingRed; /* Weighting of the Red or X Channel */
double fWeightingGreen; /* Weighting of the Green or Y Channel */
double fWeightingBlue; /* Weighting of the Blue or Z Channel */
BOOL bUseAdaptiveWeighting; /* Adapt weighting on a per-block basis */
BOOL bDXT1UseAlpha;
ATI_TC_BYTE nAlphaThreshold;
} ATI_TC_CompressOptions;
#endif // !ATI_COMPRESS_INTERNAL_BUILD
typedef struct _ATI_TC_Texture
{
ATI_TC_DWORD dwSize; /* Size of this structure */
ATI_TC_DWORD dwWidth; /* Width of the texture */
ATI_TC_DWORD dwHeight; /* Height of the texture */
ATI_TC_DWORD dwPitch; /* Distance to start of next line - necessary only for uncompressed textures */
ATI_TC_FORMAT format; /* Format of the texture */
ATI_TC_DWORD dwDataSize; /* Size of the allocated texture data */
ATI_TC_BYTE* pData; /* Pointer to the texture data */
} ATI_TC_Texture;
typedef enum
{
ATI_TC_OK = 0,
ATI_TC_ABORTED,
ATI_TC_ERR_INVALID_SOURCE_TEXTURE,
ATI_TC_ERR_INVALID_DEST_TEXTURE,
ATI_TC_ERR_UNSUPPORTED_SOURCE_FORMAT,
ATI_TC_ERR_UNSUPPORTED_DEST_FORMAT,
ATI_TC_ERR_SIZE_MISMATCH,
ATI_TC_ERR_UNABLE_TO_INIT_CODEC,
ATI_TC_ERR_GENERIC
} ATI_TC_ERROR;
#define MINIMUM_WEIGHT_VALUE 0.01f
#ifdef __cplusplus
extern "C" {
#endif
/*
** ATI_TC_Feedback_Proc
** Feedback proc for conversion
** Return non-NULL(true) value to abort conversion
*/
typedef bool (ATI_TC_API * ATI_TC_Feedback_Proc)(float fProgress, uint32* pUser1, uint32* pUser2);
/*
** ATI_TC_CalculateBufferSize
** Calculates the required buffer size for the specified texture
*/
ATI_TC_DWORD ATI_TC_API ATI_TC_CalculateBufferSize(const ATI_TC_Texture* pTexture);
/*
** ATI_TC_ConvertTexture
** Converts the source texture to the destination texture
*/
ATI_TC_ERROR ATI_TC_API ATI_TC_ConvertTexture(const ATI_TC_Texture* pSourceTexture, /* [in] - Pointer to the source texture */
ATI_TC_Texture* pDestTexture, /* [out] - Pointer to the destination texture */
const ATI_TC_CompressOptions* pOptions, /* [in] - Pointer to the compression options - can be NULL */
ATI_TC_Feedback_Proc pFeedbackProc, /* [in] - Pointer to the feedback proc - can be NULL */
uint32* pUser1, /* [in] - User data to pass to the feedback proc */
uint32* pUser2); /* [in] - User data to pass to the feedback proc */
#ifdef __cplusplus
};
#endif
#endif // !ATI_COMPRESS

128
public/avi/iavi.h Normal file
View File

@@ -0,0 +1,128 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
//=============================================================================
#ifndef IAVI_H
#define IAVI_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/iappsystem.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct BGR888_t;
class IMaterial;
//-----------------------------------------------------------------------------
// Parameters for creating a new AVI
//-----------------------------------------------------------------------------
struct AVIParams_t
{
AVIParams_t() :
m_nFrameRate( 0 ), m_nFrameScale( 1 ), m_nWidth( 0 ), m_nHeight( 0 ),
m_nSampleRate( 0 ), m_nSampleBits( 0 ), m_nNumChannels( 0 ), m_bGetCodecFromUser( true )
{
m_pFileName[ 0 ] = 0;
}
char m_pFileName[ 256 ];
char m_pPathID[ 256 ];
// fps = m_nFrameRate / m_nFrameScale
// for integer framerates, set framerate to the fps, and framescale to 1
// for ntsc-style framerates like 29.97 (or 23.976 or 59.94),
// set framerate to 30,000 (or 24,000 or 60,000) and framescale to 1001
// yes, framescale is an odd naming choice, but it matching MS's AVI api
int m_nFrameRate;
int m_nFrameScale;
int m_nWidth;
int m_nHeight;
// Sound/.wav info
int m_nSampleRate;
int m_nSampleBits;
int m_nNumChannels;
// The user will be asked to select a compressor if true, otherwise the
// previous or default will be used.
bool m_bGetCodecFromUser;
};
//-----------------------------------------------------------------------------
// Handle to an AVI
//-----------------------------------------------------------------------------
typedef unsigned short AVIHandle_t;
enum
{
AVIHANDLE_INVALID = (AVIHandle_t)~0
};
//-----------------------------------------------------------------------------
// Handle to an AVI material
//-----------------------------------------------------------------------------
typedef unsigned short AVIMaterial_t;
enum
{
AVIMATERIAL_INVALID = (AVIMaterial_t)~0
};
//-----------------------------------------------------------------------------
// Main AVI interface
//-----------------------------------------------------------------------------
class IAvi : public IAppSystem
{
public:
// Necessary to call this before any other AVI interface methods
virtual void SetMainWindow( void* hWnd ) = 0;
// Start/stop recording an AVI
virtual AVIHandle_t StartAVI( const AVIParams_t& params ) = 0;
virtual void FinishAVI( AVIHandle_t handle ) = 0;
// Add frames to an AVI
virtual void AppendMovieSound( AVIHandle_t h, short *buf, size_t bufsize ) = 0;
virtual void AppendMovieFrame( AVIHandle_t h, const BGR888_t *pRGBData ) = 0;
// Create/destroy an AVI material (a materialsystem IMaterial)
virtual AVIMaterial_t CreateAVIMaterial( const char *pMaterialName, const char *pFileName, const char *pPathID ) = 0;
virtual void DestroyAVIMaterial( AVIMaterial_t hMaterial ) = 0;
// Sets the time for an AVI material
virtual void SetTime( AVIMaterial_t hMaterial, float flTime ) = 0;
// Gets the IMaterial associated with an AVI material
virtual IMaterial* GetMaterial( AVIMaterial_t hMaterial ) = 0;
// Returns the max texture coordinate of the AVI
virtual void GetTexCoordRange( AVIMaterial_t hMaterial, float *pMaxU, float *pMaxV ) = 0;
// Returns the frame size of the AVI (stored in a subrect of the material itself)
virtual void GetFrameSize( AVIMaterial_t hMaterial, int *pWidth, int *pHeight ) = 0;
// Returns the frame rate of the AVI
virtual int GetFrameRate( AVIMaterial_t hMaterial ) = 0;
// Returns the total frame count of the AVI
virtual int GetFrameCount( AVIMaterial_t hMaterial ) = 0;
// Sets the frame for an AVI material (use instead of SetTime)
virtual void SetFrame( AVIMaterial_t hMaterial, float flFrame ) = 0;
};
extern IAvi *g_pAVI;
#endif // IAVI_H

153
public/avi/ibik.h Normal file
View File

@@ -0,0 +1,153 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
//=============================================================================
#ifndef IBIK_H
#define IBIK_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/iappsystem.h"
#define BIK_LOOP 0x00000001 // play endlessly
#define BIK_PRELOAD 0x00000002 // causes the entire move to load into memory
#define BIK_NO_AUDIO 0x00000004 // video doesn't have audio
#define ENABLE_BIK_PERF_SPEW 0
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct BGR888_t;
class IMaterial;
//-----------------------------------------------------------------------------
// Parameters for creating a new BINK
//-----------------------------------------------------------------------------
struct BIKParams_t
{
BIKParams_t() :
m_nFrameRate( 0 ), m_nFrameScale( 1 ), m_nWidth( 0 ), m_nHeight( 0 ),
m_nSampleRate( 0 ), m_nSampleBits( 0 ), m_nNumChannels( 0 )
{
m_pFileName[ 0 ] = 0;
}
char m_pFileName[ 256 ];
char m_pPathID[ 256 ];
// fps = m_nFrameRate / m_nFrameScale
// for integer framerates, set framerate to the fps, and framescale to 1
// for ntsc-style framerates like 29.97 (or 23.976 or 59.94),
// set framerate to 30,000 (or 24,000 or 60,000) and framescale to 1001
// yes, framescale is an odd naming choice, but it matching MS's AVI api
int m_nFrameRate;
int m_nFrameScale;
int m_nWidth;
int m_nHeight;
// Sound/.wav info
int m_nSampleRate;
int m_nSampleBits;
int m_nNumChannels;
};
//-----------------------------------------------------------------------------
// Handle to an BINK
//-----------------------------------------------------------------------------
typedef unsigned short BIKHandle_t;
enum
{
BIKHANDLE_INVALID = (BIKHandle_t)~0
};
//-----------------------------------------------------------------------------
// Handle to an BINK material
//-----------------------------------------------------------------------------
typedef unsigned short BIKMaterial_t;
enum
{
BIKMATERIAL_INVALID = (BIKMaterial_t)~0
};
//-----------------------------------------------------------------------------
// Main AVI interface
//-----------------------------------------------------------------------------
class IBik : public IAppSystem
{
public:
// Create/destroy a BINK material (a materialsystem IMaterial)
virtual BIKMaterial_t CreateMaterial( const char *pMaterialName, const char *pFileName, const char *pPathID, int flags = 0 ) = 0;
virtual void DestroyMaterial( BIKMaterial_t hMaterial ) = 0;
// Update the frame (if necessary)
virtual bool Update( BIKMaterial_t hMaterial ) = 0;
virtual bool ReadyForSwap( BIKMaterial_t hMaterial ) = 0;
// Gets the IMaterial associated with an BINK material
virtual IMaterial* GetMaterial( BIKMaterial_t hMaterial ) = 0;
// Returns the max texture coordinate of the BINK
virtual void GetTexCoordRange( BIKMaterial_t hMaterial, float *pMaxU, float *pMaxV ) = 0;
// Returns the frame size of the BINK (stored in a subrect of the material itself)
virtual void GetFrameSize( BIKMaterial_t hMaterial, int *pWidth, int *pHeight ) = 0;
// Returns the frame rate of the BINK
virtual int GetFrameRate( BIKMaterial_t hMaterial ) = 0;
// Returns the total frame count of the BINK
virtual int GetFrameCount( BIKMaterial_t hMaterial ) = 0;
// Get our current frame
virtual int GetFrame( BIKMaterial_t hMaterial ) = 0;
// Sets the frame for an BINK material (use instead of SetTime)
virtual void SetFrame( BIKMaterial_t hMaterial, float flFrame ) = 0;
#ifdef WIN32
#if !defined( _X360 )
// Sets the direct sound device that Bink will decode to
virtual bool SetDirectSoundDevice( void *pDevice ) = 0;
virtual bool SetMilesSoundDevice( void *pDevice ) = 0;
#else
//needs to be called after xaudio is initialized
virtual bool HookXAudio( void ) = 0;
#endif
#endif
#if defined( _PS3 )
virtual bool SetPS3SoundDevice( int nChannelCount ) = 0;
#endif // _PS3
// Pause and unpause the movie playback
virtual void Pause( BIKMaterial_t hMaterial ) = 0;
virtual void Unpause( BIKMaterial_t hMaterial ) = 0;
// Number for appending the current material name
virtual int GetGlobalMaterialAllocationNumber( void ) = 0;
virtual bool PrecacheMovie( const char *pFileName, const char *pPathID = NULL ) = 0;
virtual void *GetPrecachedMovie( const char *pFileName ) = 0;
virtual void EvictPrecachedMovie( const char *pFileName ) = 0;
virtual void EvictAllPrecachedMovies() = 0;
virtual void UpdateVolume( BIKMaterial_t hMaterial ) = 0;
virtual bool IsMovieResidentInMemory( BIKMaterial_t hMaterial ) = 0;
};
extern IBik *g_pBIK;
#endif // IBIK_H

121
public/avi/iquicktime.h Normal file
View File

@@ -0,0 +1,121 @@
//====== Copyright 2010, Valve Corporation, All rights reserved. ==============
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
//=============================================================================
#ifndef IQUICKTIME_H
#define IQUICKTIME_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/iappsystem.h"
#define QUICKTIME_LOOP_MOVIE 0x01
#define QUICKTIME_PRELOAD 0x02
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct BGR888_t;
class IMaterial;
//-----------------------------------------------------------------------------
// Parameters for creating a new BINK
//-----------------------------------------------------------------------------
struct QuickTimeParams_t
{
QuickTimeParams_t() :
m_nFrameRate( 0 ), m_nFrameScale( 1 ), m_nWidth( 0 ), m_nHeight( 0 ),
m_nSampleRate( 0 ), m_nSampleBits( 0 ), m_nNumChannels( 0 )
{
m_pFileName[ 0 ] = 0;
}
char m_pFileName[ 256 ];
char m_pPathID[ 256 ];
// fps = m_nFrameRate / m_nFrameScale
// for integer framerates, set framerate to the fps, and framescale to 1
// for ntsc-style framerates like 29.97 (or 23.976 or 59.94),
// set framerate to 30,000 (or 24,000 or 60,000) and framescale to 1001
// yes, framescale is an odd naming choice, but it matching MS's AVI api
int m_nFrameRate;
int m_nFrameScale;
int m_nWidth;
int m_nHeight;
// Sound/.wav info
int m_nSampleRate;
int m_nSampleBits;
int m_nNumChannels;
};
//-----------------------------------------------------------------------------
// Handle to an QUICKTIME
//-----------------------------------------------------------------------------
typedef unsigned short QUICKTIMEHandle_t;
enum
{
QUICKTIMEHANDLE_INVALID = (QUICKTIMEHandle_t)~0
};
//-----------------------------------------------------------------------------
// Handle to an QUICKTIME material
//-----------------------------------------------------------------------------
typedef unsigned short QUICKTIMEMaterial_t;
enum
{
QUICKTIMEMATERIAL_INVALID = (QUICKTIMEMaterial_t)~0
};
//-----------------------------------------------------------------------------
// Main QUICKTIME interface
//-----------------------------------------------------------------------------
#define QUICKTIME_INTERFACE_VERSION "IQuickTime001"
class IQuickTime : public IAppSystem
{
public:
// Create/destroy a QUICKTIME material (a materialsystem IMaterial)
virtual QUICKTIMEMaterial_t CreateMaterial( const char *pMaterialName, const char *pFileName, const char *pPathID, int flags = 0 ) = 0;
virtual void DestroyMaterial( QUICKTIMEMaterial_t hMaterial ) = 0;
// Update the frame (if necessary)
virtual bool Update( QUICKTIMEMaterial_t hMaterial ) = 0;
// Determines if a new frame of the movie is ready for display
virtual bool ReadyForSwap( QUICKTIMEMaterial_t hMaterial ) = 0;
// Gets the IMaterial associated with an BINK material
virtual IMaterial* GetMaterial( QUICKTIMEMaterial_t hMaterial ) = 0;
// Returns the max texture coordinate of the BINK
virtual void GetTexCoordRange( QUICKTIMEMaterial_t hMaterial, float *pMaxU, float *pMaxV ) = 0;
// Returns the frame size of the QUICKTIME Image Frame (stored in a subrect of the material itself)
virtual void GetFrameSize( QUICKTIMEMaterial_t hMaterial, int *pWidth, int *pHeight ) = 0;
// Returns the frame rate of the QUICKTIME
virtual int GetFrameRate( QUICKTIMEMaterial_t hMaterial ) = 0;
// Sets the frame for an BINK material (use instead of SetTime)
virtual void SetFrame( QUICKTIMEMaterial_t hMaterial, float flFrame ) = 0;
// Returns the total frame count of the BINK
virtual int GetFrameCount( QUICKTIMEMaterial_t hMaterial ) = 0;
virtual bool SetSoundDevice( void *pDevice ) = 0;
};
#endif // IQUICKTIME_H

217
public/basehandle.h Normal file
View File

@@ -0,0 +1,217 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef BASEHANDLE_H
#define BASEHANDLE_H
#ifdef _WIN32
#pragma once
#endif
#include "const.h"
#include "tier0/platform.h"
#include "tier0/dbg.h"
class IHandleEntity;
// -------------------------------------------------------------------------------------------------- //
// CBaseHandle.
// -------------------------------------------------------------------------------------------------- //
enum INVALID_EHANDLE_tag
{
INVALID_EHANDLE
};
class CBaseHandle
{
friend class CBaseEntityList;
public:
CBaseHandle();
CBaseHandle( INVALID_EHANDLE_tag );
CBaseHandle( const CBaseHandle &other );
explicit CBaseHandle( IHandleEntity* pHandleObj );
CBaseHandle( int iEntry, int iSerialNumber );
// NOTE: The following constructor is not type-safe, and can allow creating an
// arbitrary CBaseHandle that doesn't necessarily point to an actual object.
//
// It is your responsibility to ensure that the target of the handle actually points
// to the object you think it does. Generally, the argument to this function should
// have been obtained from CBaseHandle::ToInt() on a valid handle.
static CBaseHandle UnsafeFromIndex( int index );
void Init( int iEntry, int iSerialNumber );
void Term();
// Even if this returns true, Get() still can return return a non-null value.
// This just tells if the handle has been initted with any values.
bool IsValid() const;
int GetEntryIndex() const;
int GetSerialNumber() const;
int ToInt() const;
bool operator !=( const CBaseHandle &other ) const;
bool operator ==( const CBaseHandle &other ) const;
bool operator ==( const IHandleEntity* pEnt ) const;
bool operator !=( const IHandleEntity* pEnt ) const;
bool operator <( const CBaseHandle &other ) const;
bool operator <( const IHandleEntity* pEnt ) const;
// Assign a value to the handle.
const CBaseHandle& operator=( const IHandleEntity *pEntity );
const CBaseHandle& Set( const IHandleEntity *pEntity );
// Use this to dereference the handle.
// Note: this is implemented in game code (ehandle.h)
IHandleEntity* Get() const;
protected:
// The low NUM_SERIAL_BITS hold the index. If this value is less than MAX_EDICTS, then the entity is networkable.
// The high NUM_SERIAL_NUM_BITS bits are the serial number.
uint32 m_Index;
};
#include "ihandleentity.h"
inline CBaseHandle::CBaseHandle()
{
m_Index = INVALID_EHANDLE_INDEX;
}
inline CBaseHandle::CBaseHandle( INVALID_EHANDLE_tag )
{
m_Index = INVALID_EHANDLE_INDEX;
}
inline CBaseHandle::CBaseHandle( const CBaseHandle &other )
{
m_Index = other.m_Index;
}
inline CBaseHandle::CBaseHandle( IHandleEntity* pEntity )
{
Set( pEntity );
}
inline CBaseHandle::CBaseHandle( int iEntry, int iSerialNumber )
{
Init( iEntry, iSerialNumber );
}
inline CBaseHandle CBaseHandle::UnsafeFromIndex( int index )
{
CBaseHandle ret;
ret.m_Index = index;
return ret;
}
inline void CBaseHandle::Init( int iEntry, int iSerialNumber )
{
Assert( iEntry >= 0 && (iEntry & ENT_ENTRY_MASK) == iEntry);
Assert( iSerialNumber >= 0 && iSerialNumber < (1 << NUM_SERIAL_NUM_BITS) );
m_Index = iEntry | (iSerialNumber << NUM_SERIAL_NUM_SHIFT_BITS);
}
inline void CBaseHandle::Term()
{
m_Index = INVALID_EHANDLE_INDEX;
}
inline bool CBaseHandle::IsValid() const
{
return m_Index != INVALID_EHANDLE_INDEX;
}
inline int CBaseHandle::GetEntryIndex() const
{
// There is a hack here: due to a bug in the original implementation of the
// entity handle system, an attempt to look up an invalid entity index in
// certain cirumstances might fall through to the the mask operation below.
// This would mask an invalid index to be in fact a lookup of entity number
// NUM_ENT_ENTRIES, so invalid ent indexes end up actually looking up the
// last slot in the entities array. Since this slot is always empty, the
// lookup returns NULL and the expected behavior occurs through this unexpected
// route.
// A lot of code actually depends on this behavior, and the bug was only exposed
// after a change to NUM_SERIAL_NUM_BITS increased the number of allowable
// static props in the world. So the if-stanza below detects this case and
// retains the prior (bug-submarining) behavior.
if ( !IsValid() )
return NUM_ENT_ENTRIES-1;
return m_Index & ENT_ENTRY_MASK;
}
inline int CBaseHandle::GetSerialNumber() const
{
return m_Index >> NUM_SERIAL_NUM_SHIFT_BITS;
}
inline int CBaseHandle::ToInt() const
{
return (int)m_Index;
}
inline bool CBaseHandle::operator !=( const CBaseHandle &other ) const
{
return m_Index != other.m_Index;
}
inline bool CBaseHandle::operator ==( const CBaseHandle &other ) const
{
return m_Index == other.m_Index;
}
inline bool CBaseHandle::operator ==( const IHandleEntity* pEnt ) const
{
return Get() == pEnt;
}
inline bool CBaseHandle::operator !=( const IHandleEntity* pEnt ) const
{
return Get() != pEnt;
}
inline bool CBaseHandle::operator <( const CBaseHandle &other ) const
{
return m_Index < other.m_Index;
}
inline bool CBaseHandle::operator <( const IHandleEntity *pEntity ) const
{
uint32 otherIndex = (pEntity) ? pEntity->GetRefEHandle().m_Index : INVALID_EHANDLE_INDEX;
return m_Index < otherIndex;
}
inline const CBaseHandle& CBaseHandle::operator=( const IHandleEntity *pEntity )
{
return Set( pEntity );
}
inline const CBaseHandle& CBaseHandle::Set( const IHandleEntity *pEntity )
{
if ( pEntity )
{
*this = pEntity->GetRefEHandle();
}
else
{
m_Index = INVALID_EHANDLE_INDEX;
}
return *this;
}
#endif // BASEHANDLE_H

172
public/bitmap/bitmap.h Normal file
View File

@@ -0,0 +1,172 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//===========================================================================//
#ifndef BITMAP_H
#define BITMAP_H
#ifdef _WIN32
#pragma once
#endif
#include "bitmap/imageformat.h"
#include "color.h"
#include "dbg.h"
class CUtlBuffer;
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CUtlBuffer;
//-----------------------------------------------------------------------------
// A Bitmap
//-----------------------------------------------------------------------------
struct Bitmap_t
{
Bitmap_t() { Reset(); }
~Bitmap_t() { Clear(); }
//
// Accessors
//
inline int Width() const { return m_nWidth; }
inline int Height() const { return m_nHeight; }
inline ImageFormat Format() const { return m_ImageFormat; }
inline unsigned char *GetBits() const { return m_pBits; }
inline int Stride() const { return m_nStride; }
inline bool GetOwnsBuffer() const { return m_bOwnsBuffer; }
/// Allocate the buffer. Discards existing data, freeing it if we own it
void Init( int nWidth, int nHeight, ImageFormat imageFormat, int nStride = 0 );
/// Set the bitmap to the specified buffer. Any existing data is discarded/freed
/// as appropriate.
void SetBuffer( int nWidth, int nHeight, ImageFormat imageFormat, unsigned char *pBits, bool bAssumeOwnership, int nStride = 0 );
/// Sets / releases ownershp of the buffer. This does not otherwise alter the
/// state of the bitmap.
void SetOwnsBuffer( bool bOwnsBuffer )
{
Assert( m_pBits );
m_bOwnsBuffer = bOwnsBuffer;
}
/// Free up all memory and reset to default state
void Clear();
/// Return true if we have a valid size and buffer
bool IsValid() const;
/// Get pointer to raw pixel data.
unsigned char *GetPixel( int x, int y );
const unsigned char *GetPixel( int x, int y ) const;
/// Get pixel value at specified coordinates
Color GetColor( int x, int y ) const;
/// Set pixel value at specified coordinates
void SetColor( int x, int y, Color c );
/// Set this bitmap to be a logical copy of the specified
/// bitmap. No memory is allocated or copied, just copying
/// some pointers. We can also optionally transfer ownership
/// of the buffer.
void MakeLogicalCopyOf( Bitmap_t &src, bool bTransferBufferOwnership = false );
/// Set this bitmap to be a cropped rectangle from the given bitmap.
/// The source pointer can be NULL or point to this, which means to do
/// the crop in place.
void Crop( int x0, int y0, int nWidth, int nHeight, const Bitmap_t *pImgSource = NULL );
/// Blit a rectangle of pixel data into this image.
void SetPixelData( const Bitmap_t &src, int nSrcX1, int nSrcY1, int nCopySizeX, int nCopySizeY, int nDestX1, int nDestY1 );
/// Blit the entire source image into this image, at the specified offset.
/// the rectangle is clipped if necessary
void SetPixelData( const Bitmap_t &src, int nDestX1 = 0, int nDestY1 = 0 );
private:
void Reset();
/// Dimensions
int m_nWidth;
int m_nHeight;
/// Size, in bytes, of one pixel
int m_nPixelSize;
/// Image row stride, in bytes
int m_nStride;
// Do we own this buffer?
bool m_bOwnsBuffer;
/// Pixel format
ImageFormat m_ImageFormat;
/// Bitmap data. Must be allocated with malloc/free. Don't use
/// new/delete
unsigned char *m_pBits;
};
inline void Bitmap_t::Reset()
{
m_nWidth = 0;
m_nHeight = 0;
m_ImageFormat = IMAGE_FORMAT_UNKNOWN;
m_pBits = NULL;
m_nPixelSize = 0;
m_bOwnsBuffer = false;
m_nStride = 0;
}
inline unsigned char *Bitmap_t::GetPixel( int x, int y )
{
if ( !m_pBits )
return NULL;
return m_pBits + (y*m_nStride) + x* m_nPixelSize;
}
inline const unsigned char *Bitmap_t::GetPixel( int x, int y ) const
{
if ( !m_pBits )
return NULL;
return m_pBits + (y*m_nStride) + x* m_nPixelSize;
}
//-----------------------------------------------------------------------------
// Loads a bitmap from an arbitrary file: could be a TGA, PSD, or PFM.
// LoadBitmap autodetects which type, and returns it
//-----------------------------------------------------------------------------
enum BitmapFileType_t
{
BITMAP_FILE_TYPE_UNKNOWN = -1,
BITMAP_FILE_TYPE_PSD = 0,
BITMAP_FILE_TYPE_TGA,
BITMAP_FILE_TYPE_PFM,
};
BitmapFileType_t LoadBitmapFile( CUtlBuffer &buf, Bitmap_t *pBitmap );
//-----------------------------------------------------------------------------
// PFM file loading related methods
//-----------------------------------------------------------------------------
bool PFMReadFileR32F( CUtlBuffer &fileBuffer, Bitmap_t &bitmap, float pfmScale );
bool PFMReadFileRGB323232F( CUtlBuffer &fileBuffer, Bitmap_t &bitmap, float pfmScale );
bool PFMReadFileRGBA32323232F( CUtlBuffer &fileBuffer, Bitmap_t &bitmap, float pfmScale );
bool PFMGetInfo_AndAdvanceToTextureBits( CUtlBuffer &pfmBuffer, int &nWidth, int &nHeight, ImageFormat &imageFormat );
#endif // BITMAP_H

146
public/bitmap/colorformat.h Normal file
View File

@@ -0,0 +1,146 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef COLORFORMAT_H
#define COLORFORMAT_H
#ifdef _WIN32
#pragma once
#endif
#include <stdio.h>
#include "mathlib/vector.h"
#include "mathlib/vector2d.h"
#include "mathlib/vector4d.h"
#include "mathlib/vertexcolor.h"
enum ColorFormat_t
{
COLOR_FORMAT_UNKNOWN = 0,
COLOR_FORMAT_R32G32B32A32_TYPELESS = 1,
COLOR_FORMAT_R32G32B32A32_FLOAT = 2,
COLOR_FORMAT_R32G32B32A32_UINT = 3,
COLOR_FORMAT_R32G32B32A32_SINT = 4,
COLOR_FORMAT_R32G32B32_TYPELESS = 5,
COLOR_FORMAT_R32G32B32_FLOAT = 6,
COLOR_FORMAT_R32G32B32_UINT = 7,
COLOR_FORMAT_R32G32B32_SINT = 8,
COLOR_FORMAT_R16G16B16A16_TYPELESS = 9,
COLOR_FORMAT_R16G16B16A16_FLOAT = 10,
COLOR_FORMAT_R16G16B16A16_UNORM = 11,
COLOR_FORMAT_R16G16B16A16_UINT = 12,
COLOR_FORMAT_R16G16B16A16_SNORM = 13,
COLOR_FORMAT_R16G16B16A16_SINT = 14,
COLOR_FORMAT_R32G32_TYPELESS = 15,
COLOR_FORMAT_R32G32_FLOAT = 16,
COLOR_FORMAT_R32G32_UINT = 17,
COLOR_FORMAT_R32G32_SINT = 18,
COLOR_FORMAT_R32G8X24_TYPELESS = 19,
COLOR_FORMAT_D32_FLOAT_S8X24_UINT = 20,
COLOR_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
COLOR_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
COLOR_FORMAT_R10G10B10A2_TYPELESS = 23,
COLOR_FORMAT_R10G10B10A2_UNORM = 24,
COLOR_FORMAT_R10G10B10A2_UINT = 25,
COLOR_FORMAT_R11G11B10_FLOAT = 26,
COLOR_FORMAT_R8G8B8A8_TYPELESS = 27,
COLOR_FORMAT_R8G8B8A8_UNORM = 28,
COLOR_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
COLOR_FORMAT_R8G8B8A8_UINT = 30,
COLOR_FORMAT_R8G8B8A8_SNORM = 31,
COLOR_FORMAT_R8G8B8A8_SINT = 32,
COLOR_FORMAT_R16G16_TYPELESS = 33,
COLOR_FORMAT_R16G16_FLOAT = 34,
COLOR_FORMAT_R16G16_UNORM = 35,
COLOR_FORMAT_R16G16_UINT = 36,
COLOR_FORMAT_R16G16_SNORM = 37,
COLOR_FORMAT_R16G16_SINT = 38,
COLOR_FORMAT_R32_TYPELESS = 39,
COLOR_FORMAT_D32_FLOAT = 40,
COLOR_FORMAT_R32_FLOAT = 41,
COLOR_FORMAT_R32_UINT = 42,
COLOR_FORMAT_R32_SINT = 43,
COLOR_FORMAT_R24G8_TYPELESS = 44,
COLOR_FORMAT_D24_UNORM_S8_UINT = 45,
COLOR_FORMAT_R24_UNORM_X8_TYPELESS = 46,
COLOR_FORMAT_X24_TYPELESS_G8_UINT = 47,
COLOR_FORMAT_R8G8_TYPELESS = 48,
COLOR_FORMAT_R8G8_UNORM = 49,
COLOR_FORMAT_R8G8_UINT = 50,
COLOR_FORMAT_R8G8_SNORM = 51,
COLOR_FORMAT_R8G8_SINT = 52,
COLOR_FORMAT_R16_TYPELESS = 53,
COLOR_FORMAT_R16_FLOAT = 54,
COLOR_FORMAT_D16_UNORM = 55,
COLOR_FORMAT_R16_UNORM = 56,
COLOR_FORMAT_R16_UINT = 57,
COLOR_FORMAT_R16_SNORM = 58,
COLOR_FORMAT_R16_SINT = 59,
COLOR_FORMAT_R8_TYPELESS = 60,
COLOR_FORMAT_R8_UNORM = 61,
COLOR_FORMAT_R8_UINT = 62,
COLOR_FORMAT_R8_SNORM = 63,
COLOR_FORMAT_R8_SINT = 64,
COLOR_FORMAT_A8_UNORM = 65,
COLOR_FORMAT_R1_UNORM = 66,
COLOR_FORMAT_R9G9B9E5_SHAREDEXP = 67,
COLOR_FORMAT_R8G8_B8G8_UNORM = 68,
COLOR_FORMAT_G8R8_G8B8_UNORM = 69,
COLOR_FORMAT_BC1_TYPELESS = 70,
COLOR_FORMAT_BC1_UNORM = 71,
COLOR_FORMAT_BC1_UNORM_SRGB = 72,
COLOR_FORMAT_BC2_TYPELESS = 73,
COLOR_FORMAT_BC2_UNORM = 74,
COLOR_FORMAT_BC2_UNORM_SRGB = 75,
COLOR_FORMAT_BC3_TYPELESS = 76,
COLOR_FORMAT_BC3_UNORM = 77,
COLOR_FORMAT_BC3_UNORM_SRGB = 78,
COLOR_FORMAT_BC4_TYPELESS = 79,
COLOR_FORMAT_BC4_UNORM = 80,
COLOR_FORMAT_BC4_SNORM = 81,
COLOR_FORMAT_BC5_TYPELESS = 82,
COLOR_FORMAT_BC5_UNORM = 83,
COLOR_FORMAT_BC5_SNORM = 84,
COLOR_FORMAT_B5G6R5_UNORM = 85,
COLOR_FORMAT_B5G5R5A1_UNORM = 86,
COLOR_FORMAT_B8G8R8A8_UNORM = 87,
COLOR_FORMAT_B8G8R8X8_UNORM = 88,
COLOR_FORMAT_FORCE_UINT = 0xffffffffUL,
};
template < class T > inline ColorFormat_t ComputeColorFormat( T* )
{
return COLOR_FORMAT_UNKNOWN;
}
template <> inline ColorFormat_t ComputeColorFormat( float32* )
{
return COLOR_FORMAT_R32_FLOAT;
}
template <> inline ColorFormat_t ComputeColorFormat( Vector2D* )
{
return COLOR_FORMAT_R32G32_FLOAT;
}
template <> inline ColorFormat_t ComputeColorFormat( Vector* )
{
return COLOR_FORMAT_R32G32B32_FLOAT;
}
template <> inline ColorFormat_t ComputeColorFormat( Vector4D* )
{
return COLOR_FORMAT_R32G32B32A32_FLOAT;
}
template <> inline ColorFormat_t ComputeColorFormat( VertexColor_t* )
{
// FIXME: How to get at SRGB formats?
return COLOR_FORMAT_R8G8B8A8_UNORM;
}
#endif // COLORFORMAT_H

68
public/bitmap/cubemap.h Normal file
View File

@@ -0,0 +1,68 @@
//===== Copyright <20> 1996-2007, Valve Corporation, All rights reserved. ======//
//
// Purpose: a class for performing cube-mapped spherical sample lookups.
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//===========================================================================//
#ifndef CUBEMAP_H
#define CUBEMAP_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier1/utlmemory.h"
#include "mathlib/mathlib.h"
template<class T, int RES> struct CCubeMap
{
T m_Samples[6][RES][RES];
public:
FORCEINLINE void GetCoords( Vector const &vecNormalizedDirection, int &nX, int &nY, int &nFace )
{
// find largest magnitude component
int nLargest = 0;
int nAxis0 = 1;
int nAxis1 = 2;
if ( fabs( vecNormalizedDirection[1] ) > fabs( vecNormalizedDirection[0] ) )
{
nLargest = 1;
nAxis0 = 0;
nAxis1 = 2;
}
if ( fabs( vecNormalizedDirection[2] ) > fabs( vecNormalizedDirection[nLargest] ) )
{
nLargest = 2;
nAxis0 = 0;
nAxis1 = 1;
}
float flZ = vecNormalizedDirection[nLargest];
if ( flZ < 0 )
{
flZ = - flZ;
nLargest += 3;
}
nFace = nLargest;
flZ = 1.0 / flZ;
nX = RemapValClamped( vecNormalizedDirection[nAxis0] * flZ, -1, 1, 0, RES - 1 );
nY = RemapValClamped( vecNormalizedDirection[nAxis1] * flZ, -1, 1, 0, RES - 1 );
}
FORCEINLINE T & GetSample( Vector const &vecNormalizedDirection )
{
int nX, nY, nFace;
GetCoords( vecNormalizedDirection, nX, nY, nFace );
return m_Samples[nFace][nX][nY];
}
};
#endif // CUBEMAP_H

833
public/bitmap/floatbitmap.h Normal file
View File

@@ -0,0 +1,833 @@
//======= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#ifndef FLOATBITMAP_H
#define FLOATBITMAP_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "tier1/utlsoacontainer.h"
#include "mathlib/mathlib.h"
#include "bitmap/imageformat.h"
class IThreadPool;
struct PixRGBAF
{
float Red;
float Green;
float Blue;
float Alpha;
};
struct PixRGBA8
{
unsigned char Red;
unsigned char Green;
unsigned char Blue;
unsigned char Alpha;
};
inline PixRGBAF PixRGBA8_to_F( PixRGBA8 const &x )
{
PixRGBAF f;
f.Red = x.Red / float( 255.0f );
f.Green = x.Green / float( 255.0f );
f.Blue = x.Blue / float( 255.0f );
f.Alpha = x.Alpha / float( 255.0f );
return f;
}
inline PixRGBA8 PixRGBAF_to_8( PixRGBAF const &f )
{
PixRGBA8 x;
x.Red = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Red ) );
x.Green = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Green ) );
x.Blue = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Blue ) );
x.Alpha = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Alpha ) );
return x;
}
#define SPFLAGS_MAXGRADIENT 1
// bit flag options for ComputeSelfShadowedBumpmapFromHeightInAlphaChannel:
#define SSBUMP_OPTION_NONDIRECTIONAL 1 // generate ambient occlusion only
#define SSBUMP_MOD2X_DETAIL_TEXTURE 2 // scale so that a flat unshadowed
// value is 0.5, and bake rgb luminance
// in.
// attributes for csoaa container
enum FBMAttribute_t
{
FBM_ATTR_RED = 0,
FBM_ATTR_GREEN = 1,
FBM_ATTR_BLUE = 2,
FBM_ATTR_ALPHA = 3,
FBM_ATTR_COUNT
};
enum FBMAttributeMask_t
{
FBM_ATTR_RED_MASK = ( 1 << FBM_ATTR_RED ),
FBM_ATTR_GREEN_MASK = ( 1 << FBM_ATTR_GREEN ),
FBM_ATTR_BLUE_MASK = ( 1 << FBM_ATTR_BLUE ),
FBM_ATTR_ALPHA_MASK = ( 1 << FBM_ATTR_ALPHA ),
FBM_ATTR_RGB_MASK = FBM_ATTR_RED_MASK | FBM_ATTR_GREEN_MASK | FBM_ATTR_BLUE_MASK,
FBM_ATTR_RGBA_MASK = FBM_ATTR_RED_MASK | FBM_ATTR_GREEN_MASK | FBM_ATTR_BLUE_MASK | FBM_ATTR_ALPHA_MASK,
};
enum DownsampleFlags_t
{
DOWNSAMPLE_CLAMPS = 0x1,
DOWNSAMPLE_CLAMPT = 0x2,
DOWNSAMPLE_CLAMPU = 0x4,
DOWNSAMPLE_ALPHATEST = 0x10,
};
struct DownsampleInfo_t
{
int m_nFlags; // see DownsampleFlags_t
float m_flAlphaThreshhold;
float m_flAlphaHiFreqThreshhold;
};
//-----------------------------------------------------------------------------
// Float bitmap
//-----------------------------------------------------------------------------
class FloatBitMap_t : public CSOAContainer
{
typedef CSOAContainer BaseClass;
public:
FloatBitMap_t();
FloatBitMap_t( int nWidth, int nHeight, int nDepth = 1, int nAttributeMask = FBM_ATTR_RGBA_MASK ); // make one and allocate space
FloatBitMap_t( const char *pFilename ); // read one from a file (tga or pfm)
FloatBitMap_t( const FloatBitMap_t *pOrig );
// Initialize, shutdown
void Init( int nWidth, int nHeight, int nDepth = 1, int nAttributeMask = FBM_ATTR_RGBA_MASK );
void Shutdown();
// Computes the attribute mask
int GetAttributeMask() const;
// Does the bitmap have data for a particular component?
bool HasAttributeData( FBMAttribute_t a ) const;
// Compute valid attribute list
int ComputeValidAttributeList( int pIndex[4] ) const;
// Methods to initialize bitmap data
bool LoadFromPFM( const char *pFilename ); // load from floating point pixmap (.pfm) file
bool LoadFromPSD( const char *pFilename ); // load from psd file
void InitializeWithRandomPixelsFromAnotherFloatBM( const FloatBitMap_t &other );
void Clear( float r, float g, float b, float alpha ); // set all pixels to speicifed values (0..1 nominal)
void LoadFromBuffer( const void *pBuffer, size_t nBufSize, ImageFormat fmt, float flGamma ); // Assumes dimensions match the bitmap size
void LoadFromFloatBitmap( const FloatBitMap_t *pOrig );
// Methods to write bitmap data to files
bool WriteTGAFile( const char *pFilename ) const;
bool WritePFM( const char *pFilename ); // save to floating point pixmap (.pfm) file
void WriteToBuffer( void *pBuffer, size_t nBufSize, ImageFormat fmt, float flGamma ) const; // Assumes dimensions match the bitmap size
// Methods to read + write constant values
const float &ConstantValue( int comp ) const;
// Methods to read + write individual pixels
float &Pixel( int x, int y, int z, int comp ) const;
float &PixelWrapped( int x, int y, int z, int comp ) const;
float &PixelClamped( int x, int y, int z, int comp ) const;
float &Alpha( int x, int y, int z ) const;
// look up a pixel value with bilinear interpolation
float InterpolatedPixel( float x, float y, int comp ) const;
float InterpolatedPixel( float x, float y, float z, int comp ) const;
PixRGBAF PixelRGBAF( int x, int y, int z ) const;
void WritePixelRGBAF(int x, int y, int z, PixRGBAF value) const;
void WritePixel(int x, int y, int z, int comp, float value);
// Method to slam a particular channel to always be the same value
void SetChannel( int comp, float flValue );
// paste, performing boundary matching. Alpha channel can be used to make
// brush shape irregular
void SmartPaste( const FloatBitMap_t &brush, int xofs, int yofs, uint32 flags );
// force to be tileable using poisson formula
void MakeTileable( void );
void ReSize( int NewXSize, int NewYSize );
// Makes the image be a sub-range of the current image
void Crop( int x, int y, int z, int nWidth, int nHeight, int nDepth );
// find the bounds of the area that has non-zero alpha.
void GetAlphaBounds( int &minx, int &miny, int &maxx, int &maxy );
// Solve the poisson equation for an image. The alpha channel of the image controls which
// pixels are "modifiable", and can be used to set boundary conditions. Alpha=0 means the pixel
// is locked. deltas are in the order [(x,y)-(x,y-1),(x,y)-(x-1,y),(x,y)-(x+1,y),(x,y)-(x,y+1)
void Poisson( FloatBitMap_t * deltas[4],
int n_iters,
uint32 flags // SPF_xxx
);
void QuarterSize( FloatBitMap_t *pBitmap ); // get a new one downsampled
void QuarterSizeBlocky( FloatBitMap_t *pBitmap ); // get a new one downsampled
void QuarterSizeWithGaussian( FloatBitMap_t *pBitmap ); // downsample 2x using a gaussian
// Downsample using nice filter (NOTE: Dest bitmap needs to have been initialized w/ final size)
void DownsampleNiceFiltered( const DownsampleInfo_t& info, FloatBitMap_t *pBitmap );
void RaiseToPower( float pow );
void ScaleGradients( void );
void Logize( void ); // pix=log(1+pix)
void UnLogize( void ); // pix=exp(pix)-1
// compress to 8 bits converts the hdr texture to an 8 bit texture, encoding a scale factor
// in the alpha channel. upon return, the original pixel can be (approximately) recovered
// by the formula rgb*alpha*overbright.
// this function performs special numerical optimization on the texture to minimize the error
// when using bilinear filtering to read the texture.
void CompressTo8Bits( float overbright );
// decompress a bitmap converted by CompressTo8Bits
void Uncompress( float overbright );
Vector AverageColor( void ); // average rgb value of all pixels
float BrightestColor( void ); // highest vector magnitude
void ScaleRGB( float scale_factor ); // for all pixels, r,g,b*=scale_factor
// given a bitmap with height stored in the alpha channel, generate vector positions and normals
void ComputeVertexPositionsAndNormals( float flHeightScale, Vector ** ppPosOut, Vector ** ppNormalOut ) const;
// generate a normal map with height stored in alpha. uses hl2 tangent basis to support baked
// self shadowing. the bump scale maps the height of a pixel relative to the edges of the
// pixel. This function may take a while - many millions of rays may be traced. applications
// using this method need to link w/ raytrace.lib
FloatBitMap_t * ComputeSelfShadowedBumpmapFromHeightInAlphaChannel(
float bump_scale, int nrays_to_trace_per_pixel = 100,
uint32 nOptionFlags = 0 // SSBUMP_OPTION_XXX
) const;
// generate a conventional normal map from a source with height stored in alpha.
FloatBitMap_t *ComputeBumpmapFromHeightInAlphaChannel( float bump_scale ) const ;
// bilateral (edge preserving) smoothing filter. edge_threshold_value defines the difference in
// values over which filtering will not occur. Each channel is filtered independently. large
// radii will run slow, since the bilateral filter is neither separable, nor is it a
// convolution that can be done via fft.
void TileableBilateralFilter( int radius_in_pixels, float edge_threshold_value );
// Sets a thread pool for all float bitmap work to be done on
static void SetThreadPool( IThreadPool* pPool );
protected:
void QuarterSize2D( FloatBitMap_t *pDest, int nStart, int nCount );
void QuarterSize3D( FloatBitMap_t *pDest, int nStart, int nCount );
void QuarterSizeBlocky2D( FloatBitMap_t *pDest, int nStart, int nCount );
void QuarterSizeBlocky3D( FloatBitMap_t *pDest, int nStart, int nCount );
template< class T > void LoadFromBufferRGBFloat( const T *pBuffer, int nPixelCount );
template< class T > void LoadFromBufferRGB( const T *pBuffer, int nPixelCount, const float *pGammaTable );
template< class T > void LoadFromBufferRGBAFloat( const T *pBuffer, int nPixelCount );
template< class T > void LoadFromBufferRGBA( const T *pBuffer, int nPixelCount, const float *pGammaTable );
template< class T > void LoadFromBufferUV( const T *pBuffer, int nPixelCount );
template< class T > void LoadFromBufferUVWQ( const T *pBuffer, int nPixelCount );
template< class T > void LoadFromBufferUVLX( const T *pBuffer, int nPixelCount );
template< class T > void WriteToBufferRGB( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const;
template< class T > void WriteToBufferRGBFloat( T *pBuffer, int nPixelCount ) const;
template< class T > void WriteToBufferRGBA( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const;
template< class T > void WriteToBufferRGBAFloat( T *pBuffer, int nPixelCount ) const;
template< class T > void WriteToBufferUV( T *pBuffer, int nPixelCount ) const;
template< class T > void WriteToBufferUVWQ( T *pBuffer, int nPixelCount ) const;
template< class T > void WriteToBufferUVLX( T *pBuffer, int nPixelCount ) const;
static int CoordWrap( int nC, int nLimit );
static IThreadPool *sm_pFBMThreadPool;
};
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline FloatBitMap_t::FloatBitMap_t(void)
{
}
inline void FloatBitMap_t::Init( int nXSize, int nYSize, int nZSize, int nAttributeMask )
{
PurgeData();
SetAttributeType( FBM_ATTR_RED, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_RED_MASK ) != 0 );
SetAttributeType( FBM_ATTR_GREEN, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_GREEN_MASK ) != 0 );
SetAttributeType( FBM_ATTR_BLUE, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_BLUE_MASK ) != 0 );
SetAttributeType( FBM_ATTR_ALPHA, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_ALPHA_MASK ) != 0 );
AllocateData( nXSize, nYSize, nZSize );
// Default alpha to white. All others default to 0.0 by default
if ( ( nAttributeMask & FBM_ATTR_ALPHA_MASK ) == 0 )
{
FillAttr( FBM_ATTR_ALPHA, 1.0f );
}
}
//-----------------------------------------------------------------------------
// Computes the attribute mask
//-----------------------------------------------------------------------------
inline int FloatBitMap_t::GetAttributeMask() const
{
int nMask = 0;
if ( HasAllocatedMemory( FBM_ATTR_RED ) )
nMask |= FBM_ATTR_RED_MASK;
if ( HasAllocatedMemory( FBM_ATTR_GREEN ) )
nMask |= FBM_ATTR_GREEN_MASK;
if ( HasAllocatedMemory( FBM_ATTR_BLUE ) )
nMask |= FBM_ATTR_BLUE_MASK;
if ( HasAllocatedMemory( FBM_ATTR_ALPHA ) )
nMask |= FBM_ATTR_ALPHA_MASK;
return nMask;
}
//-----------------------------------------------------------------------------
// Compute valid attribute list
//-----------------------------------------------------------------------------
inline int FloatBitMap_t::ComputeValidAttributeList( int pIndex[4] ) const
{
int nCount = 0;
if ( HasAllocatedMemory( FBM_ATTR_RED ) )
pIndex[ nCount++ ] = FBM_ATTR_RED;
if ( HasAllocatedMemory( FBM_ATTR_GREEN ) )
pIndex[ nCount++ ] = FBM_ATTR_GREEN;
if ( HasAllocatedMemory( FBM_ATTR_BLUE ) )
pIndex[ nCount++ ] = FBM_ATTR_BLUE;
if ( HasAllocatedMemory( FBM_ATTR_ALPHA ) )
pIndex[ nCount++ ] = FBM_ATTR_ALPHA;
return nCount;
}
//-----------------------------------------------------------------------------
// Does the bitmap have data for a particular component?
//-----------------------------------------------------------------------------
inline bool FloatBitMap_t::HasAttributeData( FBMAttribute_t a ) const
{
return HasAllocatedMemory( a );
}
inline int FloatBitMap_t::CoordWrap( int nC, int nLimit )
{
if ( nC >= nLimit )
{
nC %= nLimit;
}
else if ( nC < 0 )
{
nC += nLimit * ( ( -nC + nLimit-1 ) / nLimit );
}
return nC;
}
inline float &FloatBitMap_t::Pixel(int x, int y, int z, int comp) const
{
Assert( (x >= 0 ) && (x < NumCols() ) );
Assert( (y >= 0) && (y < NumRows() ) );
Assert( (z >= 0) && (z < NumSlices() ) );
float *pData = ElementPointer<float>( comp, x, y, z );
return *pData;
}
inline const float &FloatBitMap_t::ConstantValue( int comp ) const
{
Assert( !HasAllocatedMemory( comp ) );
return Pixel( 0, 0, 0, comp );
}
inline float &FloatBitMap_t::PixelWrapped(int x, int y, int z, int comp) const
{
// like Pixel except wraps around to other side
x = CoordWrap( x, NumCols() );
y = CoordWrap( y, NumRows() );
z = CoordWrap( z, NumSlices() );
return Pixel( x, y, z, comp );
}
inline float &FloatBitMap_t::PixelClamped(int x, int y, int z, int comp) const
{
// like Pixel except wraps around to other side
x = clamp( x, 0, NumCols() - 1 );
y = clamp( y, 0, NumRows() - 1 );
z = clamp( z, 0, NumSlices() - 1 );
return Pixel( x, y, z, comp );
}
inline float &FloatBitMap_t::Alpha( int x, int y, int z ) const
{
Assert( ( x >= 0 ) && ( x < NumCols() ) );
Assert( ( y >= 0 ) && ( y < NumRows() ) );
Assert( ( z >= 0 ) && ( z < NumSlices() ) );
return Pixel( x, y, z, FBM_ATTR_ALPHA );
}
inline PixRGBAF FloatBitMap_t::PixelRGBAF( int x, int y, int z ) const
{
Assert( ( x >= 0 ) && ( x < NumCols() ) );
Assert( ( y >= 0 ) && ( y < NumRows() ) );
Assert( ( z >= 0 ) && ( z < NumSlices() ) );
PixRGBAF RetPix;
RetPix.Red = Pixel( x, y, z, FBM_ATTR_RED );
RetPix.Green = Pixel( x, y, z, FBM_ATTR_GREEN );
RetPix.Blue = Pixel( x, y, z, FBM_ATTR_BLUE );
RetPix.Alpha = Pixel( x, y, z, FBM_ATTR_ALPHA );
return RetPix;
}
inline void FloatBitMap_t::WritePixelRGBAF( int x, int y, int z, PixRGBAF value ) const
{
Pixel( x, y, z, FBM_ATTR_RED ) = value.Red;
Pixel( x, y, z, FBM_ATTR_GREEN ) = value.Green;
Pixel( x, y, z, FBM_ATTR_BLUE ) = value.Blue;
Pixel( x, y, z, FBM_ATTR_ALPHA ) = value.Alpha;
}
inline void FloatBitMap_t::WritePixel(int x, int y, int z, int comp, float value)
{
Pixel( x, y, z, comp ) = value;
}
//-----------------------------------------------------------------------------
// Loads an array of image data into a buffer
//-----------------------------------------------------------------------------
template< class T > void FloatBitMap_t::LoadFromBufferRGBFloat( const T *pBuffer, int nPixelCount )
{
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
Pixel( x, y, z, FBM_ATTR_RED ) = pBuffer[x].r;
Pixel( x, y, z, FBM_ATTR_GREEN ) = pBuffer[x].g;
Pixel( x, y, z, FBM_ATTR_BLUE ) = pBuffer[x].b;
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::LoadFromBufferRGB( const T *pBuffer, int nPixelCount, const float *pGammaTable )
{
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
Pixel( x, y, z, FBM_ATTR_RED ) = pGammaTable[ pBuffer[x].RTo10Bit( ) ];
Pixel( x, y, z, FBM_ATTR_GREEN ) = pGammaTable[ pBuffer[x].GTo10Bit( ) ];
Pixel( x, y, z, FBM_ATTR_BLUE ) = pGammaTable[ pBuffer[x].BTo10Bit( ) ];
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::LoadFromBufferRGBAFloat( const T *pBuffer, int nPixelCount )
{
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
Pixel( x, y, z, FBM_ATTR_RED ) = pBuffer[x].r;
Pixel( x, y, z, FBM_ATTR_GREEN ) = pBuffer[x].g;
Pixel( x, y, z, FBM_ATTR_BLUE ) = pBuffer[x].b;
Pixel( x, y, z, FBM_ATTR_ALPHA ) = pBuffer[x].a;
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::LoadFromBufferRGBA( const T *pBuffer, int nPixelCount, const float *pGammaTable )
{
float flOO1023 = 1.0f / 1023.0f;
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
Pixel( x, y, z, FBM_ATTR_RED ) = pGammaTable[ pBuffer[x].RTo10Bit( ) ];
Pixel( x, y, z, FBM_ATTR_GREEN ) = pGammaTable[ pBuffer[x].GTo10Bit( ) ];
Pixel( x, y, z, FBM_ATTR_BLUE ) = pGammaTable[ pBuffer[x].BTo10Bit( ) ];
Pixel( x, y, z, FBM_ATTR_ALPHA ) = pBuffer[x].ATo10Bit( ) * flOO1023;
}
pBuffer += NumCols();
}
}
}
//-----------------------------------------------------------------------------
// Loads from UV buffers
//-----------------------------------------------------------------------------
template< class T > void FloatBitMap_t::LoadFromBufferUV( const T *pBuffer, int nPixelCount )
{
float fl2O255 = 2.0f / 255.0f;
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
Pixel( x, y, z, FBM_ATTR_RED ) = ( pBuffer[x].u + 128 ) * fl2O255 - 1.0f;
Pixel( x, y, z, FBM_ATTR_GREEN ) = ( pBuffer[x].v + 128 ) * fl2O255 - 1.0f;
Pixel( x, y, z, FBM_ATTR_BLUE ) = 0.0f;
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::LoadFromBufferUVWQ( const T *pBuffer, int nPixelCount )
{
float fl2O255 = 2.0f / 255.0f;
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
Pixel( x, y, z, FBM_ATTR_RED ) = ( pBuffer[x].u + 128 ) * fl2O255 - 1.0f;
Pixel( x, y, z, FBM_ATTR_GREEN ) = ( pBuffer[x].v + 128 ) * fl2O255 - 1.0f;
Pixel( x, y, z, FBM_ATTR_BLUE ) = ( pBuffer[x].w + 128 ) * fl2O255 - 1.0f;
Pixel( x, y, z, FBM_ATTR_ALPHA ) = ( pBuffer[x].q + 128 ) * fl2O255 - 1.0f;
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::LoadFromBufferUVLX( const T *pBuffer, int nPixelCount )
{
float flOO255 = 1.0f / 255.0f;
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
Pixel( x, y, z, FBM_ATTR_RED ) = ( pBuffer[x].u + 128 ) * 2.0f * flOO255 - 1.0f;
Pixel( x, y, z, FBM_ATTR_GREEN ) = ( pBuffer[x].v + 128 ) * 2.0f * flOO255 - 1.0f;
Pixel( x, y, z, FBM_ATTR_BLUE ) = pBuffer[x].l * flOO255;
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
}
pBuffer += NumCols();
}
}
}
//-----------------------------------------------------------------------------
// Writes an array of image data into a buffer
//-----------------------------------------------------------------------------
template< class T > void FloatBitMap_t::WriteToBufferRGBFloat( T *pBuffer, int nPixelCount ) const
{
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
pBuffer[x].r = Pixel( x, y, z, FBM_ATTR_RED );
pBuffer[x].g = Pixel( x, y, z, FBM_ATTR_GREEN );
pBuffer[x].b = Pixel( x, y, z, FBM_ATTR_BLUE );
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::WriteToBufferRGB( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const
{
int c;
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_RED ) + 0.5f );
pBuffer[x].RFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_GREEN ) + 0.5f );
pBuffer[x].GFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_BLUE ) + 0.5f );
pBuffer[x].BFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::WriteToBufferRGBAFloat( T *pBuffer, int nPixelCount ) const
{
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
pBuffer[x].r = Pixel( x, y, z, FBM_ATTR_RED );
pBuffer[x].g = Pixel( x, y, z, FBM_ATTR_GREEN );
pBuffer[x].b = Pixel( x, y, z, FBM_ATTR_BLUE );
pBuffer[x].a = Pixel( x, y, z, FBM_ATTR_ALPHA );
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::WriteToBufferRGBA( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const
{
int c;
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_RED ) + 0.5f );
pBuffer[x].RFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_GREEN ) + 0.5f );
pBuffer[x].GFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_BLUE ) + 0.5f );
pBuffer[x].BFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_ALPHA ) + 0.5f );
pBuffer[x].AFrom10Bit( clamp( c, 0, 1023 ) );
}
pBuffer += NumCols();
}
}
}
//-----------------------------------------------------------------------------
// Writes to UV buffers
//-----------------------------------------------------------------------------
template< class T > void FloatBitMap_t::WriteToBufferUV( T *pBuffer, int nPixelCount ) const
{
int c;
float fl255O2 = 255.0f / 2.0f;
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_RED ) + 1.0f ) );
pBuffer[x].u = clamp( c, 0, 255 ) - 128;
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_GREEN ) + 1.0f ) );
pBuffer[x].v = clamp( c, 0, 255 ) - 128;
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::WriteToBufferUVWQ( T *pBuffer, int nPixelCount ) const
{
int c;
float fl255O2 = 255.0f / 2.0f;
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_RED ) + 1.0f ) );
pBuffer[x].u = clamp( c, 0, 255 ) - 128;
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_GREEN ) + 1.0f ) );
pBuffer[x].v = clamp( c, 0, 255 ) - 128;
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_BLUE ) + 1.0f ) );
pBuffer[x].w = clamp( c, 0, 255 ) - 128;
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_ALPHA ) + 1.0f ) );
pBuffer[x].q = clamp( c, 0, 255 ) - 128;
}
pBuffer += NumCols();
}
}
}
template< class T > void FloatBitMap_t::WriteToBufferUVLX( T *pBuffer, int nPixelCount ) const
{
int c;
float fl255O2 = 255.0f / 2.0f;
for( int z = 0; z < NumSlices(); ++z )
{
for( int y = 0; y < NumRows(); ++y )
{
for( int x = 0; x < NumCols(); ++x )
{
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_RED ) + 1.0f ) );
pBuffer[x].u = clamp( c, 0, 255 ) - 128;
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_GREEN ) + 1.0f ) );
pBuffer[x].v = clamp( c, 0, 255 ) - 128;
c = ( int )( 255.0f * Pixel( x, y, z, FBM_ATTR_BLUE ) );
pBuffer[x].l = clamp( c, 0, 255 );
pBuffer[x].x = 255;
}
pBuffer += NumCols();
}
}
}
// a FloatCubeMap_t holds the floating point bitmaps for 6 faces of a cube map
class FloatCubeMap_t
{
public:
FloatBitMap_t face_maps[6];
FloatCubeMap_t(int xfsize, int yfsize)
{
// make an empty one with face dimensions xfsize x yfsize
for(int f=0;f<6;f++)
{
face_maps[f].Init(xfsize,yfsize);
}
}
// load basenamebk,pfm, basenamedn.pfm, basenameft.pfm, ...
FloatCubeMap_t(const char *basename);
// save basenamebk,pfm, basenamedn.pfm, basenameft.pfm, ...
void WritePFMs(const char *basename);
Vector AverageColor(void)
{
Vector ret(0,0,0);
int nfaces = 0;
for( int f = 0;f < 6;f ++ )
if ( face_maps[f].NumElements() )
{
nfaces++;
ret += face_maps[f].AverageColor();
}
if ( nfaces )
ret *= ( 1.0 / nfaces );
return ret;
}
float BrightestColor( void )
{
float ret = 0.0;
for( int f = 0;f < 6;f ++ )
if ( face_maps[f].NumElements() )
{
ret = MAX( ret, face_maps[f].BrightestColor() );
}
return ret;
}
// generate the N-order spherical harmonic coeffcients to approxiamte this cubemap.
// for order N, this will fill in 1 + 2 * N + N^2 vectors ( 0 = 0, 1 = 4, 2 = 9 .. )
// vectors are used to hold the r,g,b coeffs
void CalculateSphericalHarmonicApproximation( int nOrder, Vector *flCoeffs );
// inverse of above
void GenerateFromSphericalHarmonics( int nOrder, Vector const *flCoeffs );
// resample a cubemap to one of possibly a lower resolution, using a given phong exponent.
// dot-product weighting will be used for the filtering operation.
void Resample(FloatCubeMap_t &dest, float flPhongExponent);
// returns the normalized direciton vector through a given pixel of a given face
Vector PixelDirection(int face, int x, int y);
// returns the direction vector throught the center of a cubemap face
Vector FaceNormal( int nFaceNumber );
};
// Image Pyramid class.
#define MAX_IMAGE_PYRAMID_LEVELS 16 // up to 64kx64k
enum ImagePyramidMode_t
{
PYRAMID_MODE_GAUSSIAN,
};
class FloatImagePyramid_t
{
public:
int m_nLevels;
FloatBitMap_t *m_pLevels[MAX_IMAGE_PYRAMID_LEVELS]; // level 0 is highest res
FloatImagePyramid_t(void)
{
m_nLevels = 0;
memset( m_pLevels, 0, sizeof( m_pLevels ));
}
// build one. clones data from src for level 0.
FloatImagePyramid_t(const FloatBitMap_t &src, ImagePyramidMode_t mode);
// read or write a Pixel from a given level. All coordinates are specified in the same domain as the base level.
float &Pixel(int x, int y, int component, int level) const;
FloatBitMap_t *Level(int lvl) const
{
Assert( lvl < m_nLevels );
return m_pLevels[lvl];
}
// rebuild all levels above the specified level
void ReconstructLowerResolutionLevels(int starting_level);
~FloatImagePyramid_t(void);
void WriteTGAs(const char *basename) const; // outputs name_00.tga, name_01.tga,...
};
#endif

679
public/bitmap/imageformat.h Normal file
View File

@@ -0,0 +1,679 @@
//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef IMAGEFORMAT_H
#define IMAGEFORMAT_H
#ifdef _WIN32
#pragma once
#endif
#include <stdio.h>
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "bitmap/imageformat_declarations.h"
//-----------------------------------------------------------------------------
// Color structures
//-----------------------------------------------------------------------------
#pragma warning ( disable : 4293 )
template< int nBitCount > FORCEINLINE int ConvertTo10Bit( int x )
{
switch ( nBitCount )
{
case 1:
return ( x & 0x1 ) ? 0x3FF : 0;
case 2:
return ( x << 8 ) | ( x << 6 ) | ( x << 4 ) | ( x << 2 ) | x;
case 3:
return ( x << 7 ) | ( x << 4 ) | ( x << 1 ) | ( x >> 2 );
case 4:
return ( x << 6 ) | ( x << 2 ) | ( x >> 2 );
default:
#if defined(POSIX) || defined(_PS3)
return ( x << ( 10 - nBitCount ) ) | ( x >> MAX( 0, MIN( 32, ( nBitCount - ( 10 - nBitCount ) ) ) ) );
#else // !_PS3
return ( x << ( 10 - nBitCount ) ) | ( x >> ( nBitCount - ( 10 - nBitCount ) ) );
#endif
}
}
#pragma warning ( default : 4293 )
template< int nBitCount > FORCEINLINE int ConvertFrom10Bit( int x )
{
return ( x >> ( 10 - nBitCount ) );
}
struct R32F_t
{
float32 r;
};
struct RG3232F_t
{
float32 r;
float32 g;
};
struct RGB323232F_t
{
float32 r;
float32 g;
float32 b;
};
struct RGBA32323232F_t
{
float32 r;
float32 g;
float32 b;
float32 a;
};
struct RGBA1010102_t
{
uint32 r : 10;
uint32 g : 10;
uint32 b : 10;
uint32 a : 2;
inline int RTo10Bit( ) const { return ConvertTo10Bit<10>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<10>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<10>( b ); }
inline int ATo10Bit( ) const { return ConvertTo10Bit<2>( a ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<10>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<10>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<10>( b10 ); }
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<10>( a10 ); }
};
struct BGRA1010102_t
{
uint32 b : 10;
uint32 g : 10;
uint32 r : 10;
uint32 a : 2;
inline int RTo10Bit( ) const { return ConvertTo10Bit<10>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<10>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<10>( b ); }
inline int ATo10Bit( ) const { return ConvertTo10Bit<2>( a ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<10>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<10>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<10>( b10 ); }
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<10>( a10 ); }
};
struct BGRA8888_t
{
uint8 b; // change the order of names to change the
uint8 g; // order of the output ARGB or BGRA, etc...
uint8 r; // Last one is MSB, 1st is LSB.
uint8 a;
inline BGRA8888_t& operator=( const BGRA8888_t& in )
{
*( unsigned int * )this = *( unsigned int * )&in;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
};
struct ABGR8888_t
{
uint8 a;
uint8 b; // change the order of names to change the
uint8 g; // order of the output ARGB or BGRA, etc...
uint8 r; // Last one is MSB, 1st is LSB.
inline ABGR8888_t& operator=( const BGRA8888_t& in )
{
r = in.r;
g = in.g;
b = in.b;
a = in.a;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
};
struct RGBA8888_t
{
uint8 r; // change the order of names to change the
uint8 g; // order of the output ARGB or BGRA, etc...
uint8 b; // Last one is MSB, 1st is LSB.
uint8 a;
inline RGBA8888_t& operator=( const BGRA8888_t& in )
{
r = in.r;
g = in.g;
b = in.b;
a = in.a;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
};
struct RGB888_t
{
uint8 r;
uint8 g;
uint8 b;
inline RGB888_t& operator=( const BGRA8888_t& in )
{
r = in.r;
g = in.g;
b = in.b;
return *this;
}
inline bool operator==( const RGB888_t& in ) const
{
return ( r == in.r ) && ( g == in.g ) && ( b == in.b );
}
inline bool operator!=( const RGB888_t& in ) const
{
return ( r != in.r ) || ( g != in.g ) || ( b != in.b );
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
};
struct BGR888_t
{
uint8 b;
uint8 g;
uint8 r;
inline BGR888_t& operator=( const BGRA8888_t& in )
{
r = in.r;
g = in.g;
b = in.b;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
};
struct BGRX8888_t
{
uint8 b;
uint8 g;
uint8 r;
uint8 x;
inline BGRX8888_t& operator=( const BGRA8888_t& in )
{
r = in.r;
g = in.g;
b = in.b;
x = 255;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
};
// 360 uses this structure for x86 dxt decoding
#if defined( _X360 )
#pragma bitfield_order( push, lsb_to_msb )
#elif defined( _PS3 )
#pragma ms_struct on
#pragma reverse_bitfields on
#endif
struct BGR565_t
{
uint16 b : 5; // order of names changes
uint16 g : 6; // byte order of output to 32 bit
uint16 r : 5;
inline BGR565_t& operator=( const BGRA8888_t& in )
{
r = in.r >> 3;
g = in.g >> 2;
b = in.b >> 3;
return *this;
}
inline BGR565_t &Set( int red, int green, int blue )
{
r = red >> 3;
g = green >> 2;
b = blue >> 3;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<6>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<6>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
};
#if defined( _X360 )
#pragma bitfield_order( pop )
#elif defined( _PS3 )
#pragma ms_struct off
#pragma reverse_bitfields off
#endif
struct BGRA5551_t
{
uint16 b : 5; // order of names changes
uint16 g : 5; // byte order of output to 32 bit
uint16 r : 5;
uint16 a : 1;
inline BGRA5551_t& operator=( const BGRA8888_t& in )
{
r = in.r >> 3;
g = in.g >> 3;
b = in.b >> 3;
a = in.a >> 7;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<5>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
inline int ATo10Bit( ) const { return ConvertTo10Bit<1>( a ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<5>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<1>( a10 ); }
};
struct BGRA4444_t
{
uint16 b : 4; // order of names changes
uint16 g : 4; // byte order of output to 32 bit
uint16 r : 4;
uint16 a : 4;
inline BGRA4444_t& operator=( const BGRA8888_t& in )
{
r = in.r >> 4;
g = in.g >> 4;
b = in.b >> 4;
a = in.a >> 4;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<4>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<4>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<4>( b ); }
inline int ATo10Bit( ) const { return ConvertTo10Bit<4>( a ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<4>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<4>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<4>( b10 ); }
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<4>( a10 ); }
};
struct RGBX5551_t
{
uint16 r : 5;
uint16 g : 5;
uint16 b : 5;
uint16 x : 1;
inline RGBX5551_t& operator=( const BGRA8888_t& in )
{
r = in.r >> 3;
g = in.g >> 3;
b = in.b >> 3;
return *this;
}
inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
inline int GTo10Bit( ) const { return ConvertTo10Bit<5>( g ); }
inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<5>( g10 ); }
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
};
struct UV88_t
{
int8 u;
int8 v;
};
struct UVWQ8888_t
{
int8 u;
int8 v;
int8 w;
int8 q;
};
struct UVLX8888_t
{
int8 u;
int8 v;
uint8 l;
uint8 x;
};
//-----------------------------------------------------------------------------
// some important constants
//-----------------------------------------------------------------------------
#define ARTWORK_GAMMA ( 2.2f )
#define IMAGE_MAX_DIM ( 2048 )
//-----------------------------------------------------------------------------
// information about each image format
//-----------------------------------------------------------------------------
struct ImageFormatInfo_t
{
const char* m_pName;
uint8 m_nNumBytes;
uint8 m_nNumRedBits;
uint8 m_nNumGreenBits;
uint8 m_nNumBlueBits;
uint8 m_nNumAlphaBits;
uint8 m_nNumDepthBits;
uint8 m_nNumStencilBits;
bool m_bIsCompressed:1;
bool m_bIsFloat:1;
bool m_bIsDepthFormat : 1;
};
//-----------------------------------------------------------------------------
// Computes nice filters for a compression ratio
//-----------------------------------------------------------------------------
struct KernelInfo_t
{
float *m_pKernel;
float *m_pInvKernel;
int m_nWidth;
int m_nHeight;
int m_nDepth;
int m_nDiameter;
};
//-----------------------------------------------------------------------------
// Indicates the target console type that a given operation is for.
// (e.g. you may be running on the PC but you're generating textures
// for X360 or PS3, so IsPC, IsX360, etc. do not work)
//-----------------------------------------------------------------------------
enum VtfConsoleFormatType_t
{
VTF_CONSOLE_360,
VTF_CONSOLE_PS3
};
//-----------------------------------------------------------------------------
// Various methods related to pixelmaps and color formats
//-----------------------------------------------------------------------------
namespace ImageLoader
{
bool GetInfo( const char *fileName, int *width, int *height, enum ImageFormat *imageFormat, float *sourceGamma );
// Generates a nice filter kernel
void ComputeNiceFilterKernel( float flWRatio, float flHRatio, float flDRatio, KernelInfo_t *pKernel );
void CleanupNiceFilterKernel( KernelInfo_t *pKernel );
// adjustedheight received the height adjusted for compression (/4 for dxt)
int GetMemRequired( int width, int height, int depth, ImageFormat imageFormat, bool mipmap, int *pAdjustedHeightOut = NULL );
int GetMemRequired( int width, int height, int depth, int nMipmapCount, ImageFormat imageFormat, int *pAdjustedHeightOut = NULL );
// This version is for mipmaps which are stored biggest level to smallest level in memory
int GetMipMapLevelByteOffset( int width, int height, ImageFormat imageFormat, int skipMipLevels, int nDepth = 1 );
// This version is for mipmaps which are stored smallest level to largest level in memory
int GetMipMapLevelByteOffsetReverse( int nWidth, int nHeight, int nDepth, int nTotalMipCount, ImageFormat imageFormat, int nMipLevel );
void GetMipMapLevelDimensions( int *width, int *height, int skipMipLevels );
void GetMipMapLevelDimensions( int &nWidth, int &nHeight, int &nDepth, int nMipLevel );
int GetNumMipMapLevels( int width, int height, int depth = 1 );
bool Load( unsigned char *imageData, const char *fileName, int width, int height, ImageFormat imageFormat, float targetGamma, bool mipmap );
bool Load( unsigned char *imageData, FILE *fp, int width, int height,
enum ImageFormat imageFormat, float targetGamma, bool mipmap );
// convert from any image format to any other image format.
// return false if the conversion cannot be performed.
// Strides denote the number of bytes per each line,
// by default assumes width * # of bytes per pixel
bool ConvertImageFormat( const unsigned char *src, enum ImageFormat srcImageFormat,
unsigned char *dst, enum ImageFormat dstImageFormat,
int width, int height, int srcStride = 0, int dstStride = 0 );
// must be used in conjunction with ConvertImageFormat() to pre-swap and post-swap
void PreConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width = 0, int stride = 0 );
void PostConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width = 0, int stride = 0 );
void ByteSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0 );
bool IsFormatValidForConversion( ImageFormat fmt );
//-----------------------------------------------------------------------------
// convert back and forth from D3D format to ImageFormat, regardless of
// whether it's supported or not
// FIXME: Move into shaderapidx8/rendersystemdx9
//-----------------------------------------------------------------------------
ImageFormat D3DFormatToImageFormat( D3DFORMAT format );
D3DFORMAT ImageFormatToD3DFormat( ImageFormat format );
// Flags for ResampleRGBA8888
enum
{
RESAMPLE_NORMALMAP = 0x1,
RESAMPLE_ALPHATEST = 0x2,
RESAMPLE_NICE_FILTER = 0x4,
RESAMPLE_CLAMPS = 0x8,
RESAMPLE_CLAMPT = 0x10,
RESAMPLE_CLAMPU = 0x20,
};
struct ResampleInfo_t
{
ResampleInfo_t() : m_nFlags(0), m_flAlphaThreshhold(0.4f), m_flAlphaHiFreqThreshhold(0.4f), m_nSrcDepth(1), m_nDestDepth(1)
{
m_flColorScale[0] = 1.0f, m_flColorScale[1] = 1.0f, m_flColorScale[2] = 1.0f, m_flColorScale[3] = 1.0f;
m_flColorGoal[0] = 0.0f, m_flColorGoal[1] = 0.0f, m_flColorGoal[2] = 0.0f, m_flColorGoal[3] = 0.0f;
}
unsigned char *m_pSrc;
unsigned char *m_pDest;
int m_nSrcWidth;
int m_nSrcHeight;
int m_nSrcDepth;
int m_nDestWidth;
int m_nDestHeight;
int m_nDestDepth;
float m_flSrcGamma;
float m_flDestGamma;
float m_flColorScale[4]; // Color scale factors RGBA
float m_flColorGoal[4]; // Color goal values RGBA DestColor = ColorGoal + scale * (SrcColor - ColorGoal)
float m_flAlphaThreshhold;
float m_flAlphaHiFreqThreshhold;
int m_nFlags;
};
bool ResampleRGBA8888( const ResampleInfo_t &info );
bool ResampleRGBA16161616( const ResampleInfo_t &info );
bool ResampleRGB323232F( const ResampleInfo_t &info );
bool ResampleRGBA32323232F( const ResampleInfo_t &info );
void ConvertNormalMapRGBA8888ToDUDVMapUVLX8888( const unsigned char *src, int width, int height, unsigned char *dst_ );
void ConvertNormalMapRGBA8888ToDUDVMapUVWQ8888( const unsigned char *src, int width, int height, unsigned char *dst_ );
void ConvertNormalMapRGBA8888ToDUDVMapUV88( const unsigned char *src, int width, int height, unsigned char *dst_ );
void ConvertNormalMapARGB8888ToDXT5GA( const unsigned char *src, unsigned char *dst, int width, int height );
void ConvertIA88ImageToNormalMapRGBA8888( const unsigned char *src, int width,
int height, unsigned char *dst,
float bumpScale );
void NormalizeNormalMapRGBA8888( unsigned char *src, int numTexels );
//-----------------------------------------------------------------------------
// Gamma correction
//-----------------------------------------------------------------------------
void GammaCorrectRGBA8888( unsigned char *src, unsigned char* dst,
int width, int height, int depth, float srcGamma, float dstGamma );
//-----------------------------------------------------------------------------
// Makes a gamma table
//-----------------------------------------------------------------------------
void ConstructGammaTable( unsigned char* pTable, float srcGamma, float dstGamma );
//-----------------------------------------------------------------------------
// Gamma corrects using a previously constructed gamma table
//-----------------------------------------------------------------------------
void GammaCorrectRGBA8888( unsigned char* pSrc, unsigned char* pDst,
int width, int height, int depth, unsigned char* pGammaTable );
//-----------------------------------------------------------------------------
// Generates a number of mipmap levels
//-----------------------------------------------------------------------------
void GenerateMipmapLevels( unsigned char* pSrc, unsigned char* pDst, int width,
int height, int depth, ImageFormat imageFormat, float srcGamma, float dstGamma,
int numLevels = 0 );
//-----------------------------------------------------------------------------
// operations on square images (src and dst can be the same)
//-----------------------------------------------------------------------------
bool RotateImageLeft( const unsigned char *src, unsigned char *dst,
int widthHeight, ImageFormat imageFormat );
bool RotateImage180( const unsigned char *src, unsigned char *dst,
int widthHeight, ImageFormat imageFormat );
bool FlipImageVertically( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 );
bool FlipImageHorizontally( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 );
bool SwapAxes( unsigned char *src,
int widthHeight, ImageFormat imageFormat );
//-----------------------------------------------------------------------------
// Returns info about each image format
//-----------------------------------------------------------------------------
const ImageFormatInfo_t &ImageFormatInfo( ImageFormat fmt );
//-----------------------------------------------------------------------------
// Gets the name of the image format
//-----------------------------------------------------------------------------
inline char const* GetName( ImageFormat fmt )
{
return ImageFormatInfo(fmt).m_pName;
}
//-----------------------------------------------------------------------------
// Gets the size of the image format in bytes. Be careful - compressed formats will return 0
//-----------------------------------------------------------------------------
inline int SizeInBytes( ImageFormat fmt )
{
return ImageFormatInfo(fmt).m_nNumBytes;
}
/// return the byte size of a given w/h. Works with compressed formats
inline int SizeInBytes( ImageFormat fmt, int nWidth, int nHeight )
{
ImageFormatInfo_t const &info = ImageFormatInfo( fmt );
if ( info.m_bIsCompressed )
{
// !!BUG!! hardcoded 4x4 block size, dxt1, dxt5
int nNumBytesPerBlock = 8;
if ( fmt == IMAGE_FORMAT_DXT5 )
{
nNumBytesPerBlock = 16;
}
return nNumBytesPerBlock * ( ( nWidth + 3 ) / 4 ) * ( ( nHeight +3 )/ 4 );
}
else
{
return info.m_nNumBytes * nWidth * nHeight;
}
}
//-----------------------------------------------------------------------------
// Does the image format support transparency?
//-----------------------------------------------------------------------------
inline bool IsTransparent( ImageFormat fmt )
{
return ImageFormatInfo(fmt).m_nNumAlphaBits > 0;
}
//-----------------------------------------------------------------------------
// Is the image format compressed?
//-----------------------------------------------------------------------------
inline bool IsCompressed( ImageFormat fmt )
{
return ImageFormatInfo(fmt).m_bIsCompressed;
}
//-----------------------------------------------------------------------------
// Is the image format compressed?
//-----------------------------------------------------------------------------
inline bool IsDepthFormat( ImageFormat fmt )
{
return ImageFormatInfo(fmt).m_bIsDepthFormat;
}
//-----------------------------------------------------------------------------
// Is any channel > 8 bits?
//-----------------------------------------------------------------------------
inline bool HasChannelLargerThan8Bits( ImageFormat fmt )
{
ImageFormatInfo_t info = ImageFormatInfo(fmt);
return ( info.m_nNumRedBits > 8 || info.m_nNumGreenBits > 8 || info.m_nNumBlueBits > 8 || info.m_nNumAlphaBits > 8 );
}
inline bool IsFloatFormat( ImageFormat fmt )
{
return ( fmt == IMAGE_FORMAT_RGBA16161616F ) ||
( fmt == IMAGE_FORMAT_RG1616F ) ||
( fmt == IMAGE_FORMAT_R32F ) ||
( fmt == IMAGE_FORMAT_RG3232F ) ||
( fmt == IMAGE_FORMAT_RGB323232F ) ||
( fmt == IMAGE_FORMAT_RGBA32323232F );
}
inline bool IsRuntimeCompressed( ImageFormat fmt )
{
return ( fmt == IMAGE_FORMAT_DXT1_RUNTIME ) || ( fmt == IMAGE_FORMAT_DXT5_RUNTIME );
}
} // end namespace ImageLoader
#endif // IMAGEFORMAT_H

View File

@@ -0,0 +1,189 @@
//========== Copyright <20> Valve Corporation, All rights reserved. ========
#ifndef IMAGEFORMAT_DECLARATIONS_HDR
#define IMAGEFORMAT_DECLARATIONS_HDR
enum NormalDecodeMode_t
{
NORMAL_DECODE_NONE = 0,
NORMAL_DECODE_ATI2N = 1,
NORMAL_DECODE_ATI2N_ALPHA = 2
};
// Forward declaration
#ifdef _WIN32
typedef enum _D3DFORMAT D3DFORMAT;
typedef enum DXGI_FORMAT;
#endif
//-----------------------------------------------------------------------------
// The various image format types
//-----------------------------------------------------------------------------
// don't bitch that inline functions aren't used!!!!
#ifndef SPU
#pragma warning(disable : 4514)
#endif
enum ImageFormat
{
IMAGE_FORMAT_DEFAULT = -2, // Use this image format if you want to perform tool operations on the texture
IMAGE_FORMAT_UNKNOWN = -1,
IMAGE_FORMAT_RGBA8888 = 0,
IMAGE_FORMAT_ABGR8888,
IMAGE_FORMAT_RGB888,
IMAGE_FORMAT_BGR888,
IMAGE_FORMAT_RGB565,
IMAGE_FORMAT_I8,
IMAGE_FORMAT_IA88,
IMAGE_FORMAT_P8,
IMAGE_FORMAT_A8,
IMAGE_FORMAT_RGB888_BLUESCREEN,
IMAGE_FORMAT_BGR888_BLUESCREEN,
IMAGE_FORMAT_ARGB8888,
IMAGE_FORMAT_BGRA8888,
IMAGE_FORMAT_DXT1,
IMAGE_FORMAT_DXT3,
IMAGE_FORMAT_DXT5,
IMAGE_FORMAT_BGRX8888,
IMAGE_FORMAT_BGR565,
IMAGE_FORMAT_BGRX5551,
IMAGE_FORMAT_BGRA4444,
IMAGE_FORMAT_DXT1_ONEBITALPHA,
IMAGE_FORMAT_BGRA5551,
IMAGE_FORMAT_UV88,
IMAGE_FORMAT_UVWQ8888,
IMAGE_FORMAT_RGBA16161616F,
IMAGE_FORMAT_RGBA16161616,
IMAGE_FORMAT_UVLX8888,
IMAGE_FORMAT_R32F, // Single-channel 32-bit floating point
IMAGE_FORMAT_RGB323232F, // NOTE: D3D9 does not have this format
IMAGE_FORMAT_RGBA32323232F,
IMAGE_FORMAT_RG1616F,
IMAGE_FORMAT_RG3232F,
IMAGE_FORMAT_RGBX8888,
IMAGE_FORMAT_NULL, // Dummy format which takes no video memory
// Compressed normal map formats
IMAGE_FORMAT_ATI2N, // One-surface ATI2N / DXN format
IMAGE_FORMAT_ATI1N, // Two-surface ATI1N format
IMAGE_FORMAT_RGBA1010102, // 10 bit-per component render targets
IMAGE_FORMAT_BGRA1010102,
IMAGE_FORMAT_R16F, // 16 bit FP format
// Depth-stencil texture formats
IMAGE_FORMAT_D16,
IMAGE_FORMAT_D15S1,
IMAGE_FORMAT_D32,
IMAGE_FORMAT_D24S8,
IMAGE_FORMAT_LINEAR_D24S8,
IMAGE_FORMAT_D24X8,
IMAGE_FORMAT_D24X4S4,
IMAGE_FORMAT_D24FS8,
IMAGE_FORMAT_D16_SHADOW, // Specific formats for shadow mapping
IMAGE_FORMAT_D24X8_SHADOW, // Specific formats for shadow mapping
// supporting these specific formats as non-tiled for procedural cpu access (360-specific)
IMAGE_FORMAT_LINEAR_BGRX8888,
IMAGE_FORMAT_LINEAR_RGBA8888,
IMAGE_FORMAT_LINEAR_ABGR8888,
IMAGE_FORMAT_LINEAR_ARGB8888,
IMAGE_FORMAT_LINEAR_BGRA8888,
IMAGE_FORMAT_LINEAR_RGB888,
IMAGE_FORMAT_LINEAR_BGR888,
IMAGE_FORMAT_LINEAR_BGRX5551,
IMAGE_FORMAT_LINEAR_I8,
IMAGE_FORMAT_LINEAR_RGBA16161616,
IMAGE_FORMAT_LINEAR_A8,
IMAGE_FORMAT_LINEAR_DXT1,
IMAGE_FORMAT_LINEAR_DXT3,
IMAGE_FORMAT_LINEAR_DXT5,
IMAGE_FORMAT_LE_BGRX8888,
IMAGE_FORMAT_LE_BGRA8888,
// these are used for runtime conversion to DXT1/5
IMAGE_FORMAT_DXT1_RUNTIME,
IMAGE_FORMAT_DXT5_RUNTIME,
// special depth format
IMAGE_FORMAT_INTZ,
NUM_IMAGE_FORMATS
};
#if defined( DX_TO_GL_ABSTRACTION ) || defined( _PS3 )
typedef enum _D3DFORMAT
{
D3DFMT_INDEX16,
D3DFMT_D16,
D3DFMT_D24S8,
D3DFMT_A8R8G8B8,
D3DFMT_A4R4G4B4,
D3DFMT_X8R8G8B8,
D3DFMT_R5G6R5,
D3DFMT_X1R5G5B5,
D3DFMT_A1R5G5B5,
D3DFMT_L8,
D3DFMT_A8L8,
D3DFMT_A,
D3DFMT_DXT1,
D3DFMT_DXT3,
D3DFMT_DXT5,
D3DFMT_V8U8,
D3DFMT_Q8W8V8U8,
D3DFMT_X8L8V8U8,
D3DFMT_A16B16G16R16F,
D3DFMT_A16B16G16R16,
D3DFMT_R32F,
D3DFMT_A32B32G32R32F,
D3DFMT_R8G8B8,
D3DFMT_D24X4S4,
D3DFMT_A8,
D3DFMT_R5G6B5,
D3DFMT_D15S1,
D3DFMT_D24X8,
D3DFMT_VERTEXDATA,
D3DFMT_INDEX32,
// new d3d format enums for Source main engine (i.e Portal2, AS, Dota)
D3DFMT_D24FS8,
D3DFMT_A8B8G8R8,
D3DFMT_P8,
D3DFMT_G16R16F,
D3DFMT_G32R32F,
D3DFMT_X8B8G8R8,
D3DFMT_A2B10G10R10,
D3DFMT_A2R10G10B10,
D3DFMT_R16F,
D3DFMT_D32,
// adding fake D3D format names for the vendor specific ones (eases debugging/logging)
// NV shadow depth tex
D3DFMT_NV_INTZ = 0x5a544e49, // MAKEFOURCC('I','N','T','Z')
D3DFMT_NV_RAWZ = 0x5a574152, // MAKEFOURCC('R','A','W','Z')
// NV null tex
D3DFMT_NV_NULL = 0x4c4c554e, // MAKEFOURCC('N','U','L','L')
// ATI shadow depth tex
D3DFMT_ATI_D16 = 0x36314644, // MAKEFOURCC('D','F','1','6')
D3DFMT_ATI_D24S8 = 0x34324644, // MAKEFOURCC('D','F','2','4')
// ATI 1N and 2N compressed tex
D3DFMT_ATI_2N = 0x32495441, // MAKEFOURCC('A', 'T', 'I', '2')
D3DFMT_ATI_1N = 0x31495441, // MAKEFOURCC('A', 'T', 'I', '1')
D3DFMT_UNKNOWN
} D3DFORMAT;
#endif
#endif

105
public/bitmap/psd.h Normal file
View File

@@ -0,0 +1,105 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Methods relating to saving + loading PSD files (photoshop)
//
// $NoKeywords: $
//===========================================================================//
#ifndef PSD_H
#define PSD_H
#ifdef _WIN32
#pragma once
#endif
#include "bitmap/imageformat.h" //ImageFormat enum definition
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CUtlBuffer;
struct Bitmap_t;
class PSDImageResources
{
public:
enum Resource {
eResFileInfo = 0x0404
};
struct ResElement {
Resource m_eType;
// unsigned char m_pReserved[4];
unsigned short m_numBytes;
unsigned char const *m_pvData;
};
public:
explicit PSDImageResources( unsigned int numBytes, unsigned char const *pvBuffer ) : m_numBytes( numBytes ), m_pvBuffer( pvBuffer ) {}
public:
ResElement FindElement( Resource eType ) const;
protected:
unsigned int m_numBytes;
unsigned char const * m_pvBuffer;
};
class PSDResFileInfo
{
public:
enum ResFileInfo {
eTitle = 0x05,
eAuthor = 0x50,
eAuthorTitle = 0x55,
eDescription = 0x78,
eDescriptionWriter = 0x7A,
eKeywords = 0x19,
eCopyrightNotice = 0x74
};
struct ResFileInfoElement {
ResFileInfo m_eType;
unsigned short m_numBytes;
unsigned char const *m_pvData;
};
public:
explicit PSDResFileInfo( PSDImageResources::ResElement res ) : m_res( res ) {}
public:
ResFileInfoElement FindElement( ResFileInfo eType ) const;
protected:
PSDImageResources::ResElement m_res;
};
//-----------------------------------------------------------------------------
// Is a file a PSD file?
//-----------------------------------------------------------------------------
bool IsPSDFile( const char *pFileName, const char *pPathID );
bool IsPSDFile( CUtlBuffer &buf );
//-----------------------------------------------------------------------------
// Returns information about the PSD file
//-----------------------------------------------------------------------------
bool PSDGetInfo( const char *pFileName, const char *pPathID, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma );
bool PSDGetInfo( CUtlBuffer &buf, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma );
//-----------------------------------------------------------------------------
// Get PSD file image resources, pointers refer into the utlbuffer
//-----------------------------------------------------------------------------
PSDImageResources PSDGetImageResources( CUtlBuffer &buf );
//-----------------------------------------------------------------------------
// Reads the PSD file into the specified buffer
//-----------------------------------------------------------------------------
bool PSDReadFileRGBA8888( CUtlBuffer &buf, Bitmap_t &bitmap );
bool PSDReadFileRGBA8888( const char *pFileName, const char *pPathID, Bitmap_t &bitmap );
#endif // PSD_H

136
public/bitmap/psheet.h Normal file
View File

@@ -0,0 +1,136 @@
//===== Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose: sheet definitions for particles and other sprite functions
//
//===========================================================================//
#ifndef PSHEET_H
#define PSHEET_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/utlobjectreference.h"
#include "materialsystem/MaterialSystemUtil.h"
#include "tier1/utlvector.h"
class CUtlBuffer;
// classes for keeping a dictionary of sheet files in memory. A sheet is a bunch of frames packewd
// within one texture. Each sheet has 1 or more frame sequences stored for it.
// for fast lookups to retrieve sequence data, we store the sequence information discretized into
// a fixed # of frames. If this discretenesss is a visual problem, you can lerp the blend values to get it
// perfect.
#define SEQUENCE_SAMPLE_COUNT 512
#define MAX_IMAGES_PER_FRAME_ON_DISK 4
#define MAX_IMAGES_PER_FRAME_IN_MEMORY 2
struct SequenceSampleTextureCoords_t
{
float m_fLeft_U0;
float m_fTop_V0;
float m_fRight_U0;
float m_fBottom_V0;
float m_fLeft_U1;
float m_fTop_V1;
float m_fRight_U1;
float m_fBottom_V1;
};
struct SheetSequenceSample_t
{
// coordinates of two rectangles (old and next frame coords)
SequenceSampleTextureCoords_t m_TextureCoordData[MAX_IMAGES_PER_FRAME_IN_MEMORY];
float m_fBlendFactor;
void CopyFirstFrameToOthers(void)
{
// for old format files only supporting one image per frame
for(int i=1; i < MAX_IMAGES_PER_FRAME_IN_MEMORY; i++)
{
m_TextureCoordData[i] = m_TextureCoordData[0];
}
}
};
enum SheetSequenceFlags_t
{
SEQ_FLAG_CLAMP = 0x1, // as opposed to loop
SEQ_FLAG_NO_ALPHA = 0x2, // packed as sequence-rgb (alpha channel should be ignored)
SEQ_FLAG_NO_COLOR = 0x4, // packed as sequence-a (color channels should be ignored)
};
class CSheet
{
public:
// read form a .sht file. This is the usual thing to do
CSheet( CUtlBuffer &buf );
CSheet( void );
~CSheet( void );
const SheetSequenceSample_t *GetSampleForSequence( float flAge, float flAgeScale, int nSequence, bool bForceLoop );
// references for smart ptrs
CUtlReferenceList<CSheet> m_References;
struct SheetInfo_t
{
SheetSequenceSample_t *m_pSamples;
uint8 m_SeqFlags;
bool m_bSequenceIsCopyOfAnotherSequence;
int16 m_nNumFrames;
float m_flFrameSpan;
};
CUtlVector< SheetInfo_t > m_SheetInfo;
};
//////////////////////////////////////////////////////////////////////////
class IMesh;
class IMaterial;
// A heavier-weight version of CSheet with more bells and whistles
class CSheetExtended
{
public:
explicit CSheetExtended( IMaterial* pMaterial );
~CSheetExtended();
int GetSheetSequenceCount();
int GetNthSequenceIndex( int nSequenceNumber );
const SheetSequenceSample_t *GetSampleForSequence( float flAge, float flAgeScale, int nSequence, bool bForceLoop );
float GetSequenceTimeSpan( int nSequenceIndex );
void DrawSheet( IMesh *pMesh, const Vector &vCenter, float flRadius, int nSheetSequence, float flAge, float flSheetPreviewSpeed, bool bLoopSheetPreview, int nSecondarySequence=-1, bool bOverrideSpriteCard=false );
bool ValidSheetData();
bool SequenceHasAlphaData( int nSequenceIndex );
bool SequenceHasColorData( int nSequenceIndex );
// Helper
static bool IsMaterialSeparateAlphaColorMaterial( IMaterial* pMat );
static bool IsMaterialDualSequence( IMaterial* pMat );
private:
void LoadFromBuffer( CUtlBuffer& buf );
void LoadFromMaterial( IMaterial* pMaterial );
// TEMP: Store in a CSheet for now - eventually we'll want more data
CSheet* m_pSheetData;
CMaterialReference m_Material;
};
#endif // PSHEET_H

624
public/bitmap/stb_dxt.h Normal file
View File

@@ -0,0 +1,624 @@
// stb_dxt.h - v1.04 - DXT1/DXT5 compressor - public domain
// original by fabian "ryg" giesen - ported to C by stb
// use '#define STB_DXT_IMPLEMENTATION' before including to create the implementation
//
// USAGE:
// call stb_compress_dxt_block() for every block (you must pad)
// source should be a 4x4 block of RGBA data in row-major order;
// A is ignored if you specify alpha=0; you can turn on dithering
// and "high quality" using mode.
//
// version history:
// v1.04 - (ryg) default to no rounding bias for lerped colors (as per S3TC/DX10 spec);
// single color match fix (allow for inexact color interpolation);
// optimal DXT5 index finder; "high quality" mode that runs multiple refinement steps.
// v1.03 - (stb) endianness support
// v1.02 - (stb) fix alpha encoding bug
// v1.01 - (stb) fix bug converting to RGB that messed up quality, thanks ryg & cbloom
// v1.00 - (stb) first release
#ifndef STB_INCLUDE_STB_DXT_H
#define STB_INCLUDE_STB_DXT_H
// compression mode (bitflags)
#define STB_DXT_NORMAL 0
#define STB_DXT_DITHER 1 // use dithering. dubious win. never use for normal maps and the like!
#define STB_DXT_HIGHQUAL 2 // high quality mode, does two refinement steps instead of 1. ~30-40% slower.
void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode);
#define STB_COMPRESS_DXT_BLOCK
#ifdef STB_DXT_IMPLEMENTATION
// configuration options for DXT encoder. set them in the project/makefile or just define
// them at the top.
// STB_DXT_USE_ROUNDING_BIAS
// use a rounding bias during color interpolation. this is closer to what "ideal"
// interpolation would do but doesn't match the S3TC/DX10 spec. old versions (pre-1.03)
// implicitly had this turned on.
//
// in case you're targeting a specific type of hardware (e.g. console programmers):
// NVidia and Intel GPUs (as of 2010) as well as DX9 ref use DXT decoders that are closer
// to STB_DXT_USE_ROUNDING_BIAS. AMD/ATI, S3 and DX10 ref are closer to rounding with no bias.
// you also see "(a*5 + b*3) / 8" on some old GPU designs.
// #define STB_DXT_USE_ROUNDING_BIAS
#include <stdlib.h>
#include <math.h>
#include <string.h> // memset
static unsigned char stb__Expand5[32];
static unsigned char stb__Expand6[64];
static unsigned char stb__OMatch5[256][2];
static unsigned char stb__OMatch6[256][2];
static unsigned char stb__QuantRBTab[256+16];
static unsigned char stb__QuantGTab[256+16];
static int stb__Mul8Bit(int a, int b)
{
int t = a*b + 128;
return (t + (t >> 8)) >> 8;
}
static void stb__From16Bit(unsigned char *out, unsigned short v)
{
int rv = (v & 0xf800) >> 11;
int gv = (v & 0x07e0) >> 5;
int bv = (v & 0x001f) >> 0;
out[0] = stb__Expand5[rv];
out[1] = stb__Expand6[gv];
out[2] = stb__Expand5[bv];
out[3] = 0;
}
static unsigned short stb__As16Bit(int r, int g, int b)
{
return (stb__Mul8Bit(r,31) << 11) + (stb__Mul8Bit(g,63) << 5) + stb__Mul8Bit(b,31);
}
// linear interpolation at 1/3 point between a and b, using desired rounding type
static int stb__Lerp13(int a, int b)
{
#ifdef STB_DXT_USE_ROUNDING_BIAS
// with rounding bias
return a + stb__Mul8Bit(b-a, 0x55);
#else
// without rounding bias
// replace "/ 3" by "* 0xaaab) >> 17" if your compiler sucks or you really need every ounce of speed.
return (2*a + b) / 3;
#endif
}
// lerp RGB color
static void stb__Lerp13RGB(unsigned char *out, unsigned char *p1, unsigned char *p2)
{
out[0] = stb__Lerp13(p1[0], p2[0]);
out[1] = stb__Lerp13(p1[1], p2[1]);
out[2] = stb__Lerp13(p1[2], p2[2]);
}
/****************************************************************************/
// compute table to reproduce constant colors as accurately as possible
static void stb__PrepareOptTable(unsigned char *Table,const unsigned char *expand,int size)
{
int i,mn,mx;
for (i=0;i<256;i++) {
int bestErr = 256;
for (mn=0;mn<size;mn++) {
for (mx=0;mx<size;mx++) {
int mine = expand[mn];
int maxe = expand[mx];
int err = abs(stb__Lerp13(maxe, mine) - i);
// DX10 spec says that interpolation must be within 3% of "correct" result,
// add this as error term. (normally we'd expect a random distribution of
// +-1.5% error, but nowhere in the spec does it say that the error has to be
// unbiased - better safe than sorry).
err += abs(maxe - mine) * 3 / 100;
if(err < bestErr)
{
Table[i*2+0] = mx;
Table[i*2+1] = mn;
bestErr = err;
}
}
}
}
}
static void stb__EvalColors(unsigned char *color,unsigned short c0,unsigned short c1)
{
stb__From16Bit(color+ 0, c0);
stb__From16Bit(color+ 4, c1);
stb__Lerp13RGB(color+ 8, color+0, color+4);
stb__Lerp13RGB(color+12, color+4, color+0);
}
// Block dithering function. Simply dithers a block to 565 RGB.
// (Floyd-Steinberg)
static void stb__DitherBlock(unsigned char *dest, unsigned char *block)
{
int err[8],*ep1 = err,*ep2 = err+4, *et;
int ch,y;
// process channels seperately
for (ch=0; ch<3; ++ch) {
unsigned char *bp = block+ch, *dp = dest+ch;
unsigned char *quant = (ch == 1) ? stb__QuantGTab+8 : stb__QuantRBTab+8;
memset(err, 0, sizeof(err));
for(y=0; y<4; ++y) {
dp[ 0] = quant[bp[ 0] + ((3*ep2[1] + 5*ep2[0]) >> 4)];
ep1[0] = bp[ 0] - dp[ 0];
dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)];
ep1[1] = bp[ 4] - dp[ 4];
dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)];
ep1[2] = bp[ 8] - dp[ 8];
dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)];
ep1[3] = bp[12] - dp[12];
bp += 16;
dp += 16;
et = ep1, ep1 = ep2, ep2 = et; // swap
}
}
}
// The color matching function
static unsigned int stb__MatchColorsBlock(unsigned char *block, unsigned char *color,int dither)
{
unsigned int mask = 0;
int dirr = color[0*4+0] - color[1*4+0];
int dirg = color[0*4+1] - color[1*4+1];
int dirb = color[0*4+2] - color[1*4+2];
int dots[16];
int stops[4];
int i;
int c0Point, halfPoint, c3Point;
for(i=0;i<16;i++)
dots[i] = block[i*4+0]*dirr + block[i*4+1]*dirg + block[i*4+2]*dirb;
for(i=0;i<4;i++)
stops[i] = color[i*4+0]*dirr + color[i*4+1]*dirg + color[i*4+2]*dirb;
// think of the colors as arranged on a line; project point onto that line, then choose
// next color out of available ones. we compute the crossover points for "best color in top
// half"/"best in bottom half" and then the same inside that subinterval.
//
// relying on this 1d approximation isn't always optimal in terms of euclidean distance,
// but it's very close and a lot faster.
// http://cbloomrants.blogspot.com/2008/12/12-08-08-dxtc-summary.html
c0Point = (stops[1] + stops[3]) >> 1;
halfPoint = (stops[3] + stops[2]) >> 1;
c3Point = (stops[2] + stops[0]) >> 1;
if(!dither) {
// the version without dithering is straightforward
for (i=15;i>=0;i--) {
int dot = dots[i];
mask <<= 2;
if(dot < halfPoint)
mask |= (dot < c0Point) ? 1 : 3;
else
mask |= (dot < c3Point) ? 2 : 0;
}
} else {
// with floyd-steinberg dithering
int err[8],*ep1 = err,*ep2 = err+4;
int *dp = dots, y;
c0Point <<= 4;
halfPoint <<= 4;
c3Point <<= 4;
for(i=0;i<8;i++)
err[i] = 0;
for(y=0;y<4;y++)
{
int dot,lmask,step;
dot = (dp[0] << 4) + (3*ep2[1] + 5*ep2[0]);
if(dot < halfPoint)
step = (dot < c0Point) ? 1 : 3;
else
step = (dot < c3Point) ? 2 : 0;
ep1[0] = dp[0] - stops[step];
lmask = step;
dot = (dp[1] << 4) + (7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]);
if(dot < halfPoint)
step = (dot < c0Point) ? 1 : 3;
else
step = (dot < c3Point) ? 2 : 0;
ep1[1] = dp[1] - stops[step];
lmask |= step<<2;
dot = (dp[2] << 4) + (7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]);
if(dot < halfPoint)
step = (dot < c0Point) ? 1 : 3;
else
step = (dot < c3Point) ? 2 : 0;
ep1[2] = dp[2] - stops[step];
lmask |= step<<4;
dot = (dp[3] << 4) + (7*ep1[2] + 5*ep2[3] + ep2[2]);
if(dot < halfPoint)
step = (dot < c0Point) ? 1 : 3;
else
step = (dot < c3Point) ? 2 : 0;
ep1[3] = dp[3] - stops[step];
lmask |= step<<6;
dp += 4;
mask |= lmask << (y*8);
{ int *et = ep1; ep1 = ep2; ep2 = et; } // swap
}
}
return mask;
}
// The color optimization function. (Clever code, part 1)
static void stb__OptimizeColorsBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16)
{
int mind = 0x7fffffff,maxd = -0x7fffffff;
unsigned char *minp, *maxp;
double magn;
int v_r,v_g,v_b;
static const int nIterPower = 4;
float covf[6],vfr,vfg,vfb;
// determine color distribution
int cov[6];
int mu[3],min[3],max[3];
int ch,i,iter;
for(ch=0;ch<3;ch++)
{
const unsigned char *bp = ((const unsigned char *) block) + ch;
int muv,minv,maxv;
muv = minv = maxv = bp[0];
for(i=4;i<64;i+=4)
{
muv += bp[i];
if (bp[i] < minv) minv = bp[i];
else if (bp[i] > maxv) maxv = bp[i];
}
mu[ch] = (muv + 8) >> 4;
min[ch] = minv;
max[ch] = maxv;
}
// determine covariance matrix
for (i=0;i<6;i++)
cov[i] = 0;
for (i=0;i<16;i++)
{
int r = block[i*4+0] - mu[0];
int g = block[i*4+1] - mu[1];
int b = block[i*4+2] - mu[2];
cov[0] += r*r;
cov[1] += r*g;
cov[2] += r*b;
cov[3] += g*g;
cov[4] += g*b;
cov[5] += b*b;
}
// convert covariance matrix to float, find principal axis via power iter
for(i=0;i<6;i++)
covf[i] = cov[i] / 255.0f;
vfr = (float) (max[0] - min[0]);
vfg = (float) (max[1] - min[1]);
vfb = (float) (max[2] - min[2]);
for(iter=0;iter<nIterPower;iter++)
{
float r = vfr*covf[0] + vfg*covf[1] + vfb*covf[2];
float g = vfr*covf[1] + vfg*covf[3] + vfb*covf[4];
float b = vfr*covf[2] + vfg*covf[4] + vfb*covf[5];
vfr = r;
vfg = g;
vfb = b;
}
magn = fabs(vfr);
if (fabs(vfg) > magn) magn = fabs(vfg);
if (fabs(vfb) > magn) magn = fabs(vfb);
if(magn < 4.0f) { // too small, default to luminance
v_r = 299; // JPEG YCbCr luma coefs, scaled by 1000.
v_g = 587;
v_b = 114;
} else {
magn = 512.0 / magn;
v_r = (int) (vfr * magn);
v_g = (int) (vfg * magn);
v_b = (int) (vfb * magn);
}
// Pick colors at extreme points
for(i=0;i<16;i++)
{
int dot = block[i*4+0]*v_r + block[i*4+1]*v_g + block[i*4+2]*v_b;
if (dot < mind) {
mind = dot;
minp = block+i*4;
}
if (dot > maxd) {
maxd = dot;
maxp = block+i*4;
}
}
*pmax16 = stb__As16Bit(maxp[0],maxp[1],maxp[2]);
*pmin16 = stb__As16Bit(minp[0],minp[1],minp[2]);
}
static int stb__sclamp(float y, int p0, int p1)
{
int x = (int) y;
if (x < p0) return p0;
if (x > p1) return p1;
return x;
}
// The refinement function. (Clever code, part 2)
// Tries to optimize colors to suit block contents better.
// (By solving a least squares system via normal equations+Cramer's rule)
static int stb__RefineBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16, unsigned int mask)
{
static const int w1Tab[4] = { 3,0,2,1 };
static const int prods[4] = { 0x090000,0x000900,0x040102,0x010402 };
// ^some magic to save a lot of multiplies in the accumulating loop...
// (precomputed products of weights for least squares system, accumulated inside one 32-bit register)
float frb,fg;
unsigned short oldMin, oldMax, min16, max16;
int i, akku = 0, xx,xy,yy;
int At1_r,At1_g,At1_b;
int At2_r,At2_g,At2_b;
unsigned int cm = mask;
oldMin = *pmin16;
oldMax = *pmax16;
if((mask ^ (mask<<2)) < 4) // all pixels have the same index?
{
// yes, linear system would be singular; solve using optimal
// single-color match on average color
int r = 8, g = 8, b = 8;
for (i=0;i<16;++i) {
r += block[i*4+0];
g += block[i*4+1];
b += block[i*4+2];
}
r >>= 4; g >>= 4; b >>= 4;
max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0];
min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1];
} else {
At1_r = At1_g = At1_b = 0;
At2_r = At2_g = At2_b = 0;
for (i=0;i<16;++i,cm>>=2) {
int step = cm&3;
int w1 = w1Tab[step];
int r = block[i*4+0];
int g = block[i*4+1];
int b = block[i*4+2];
akku += prods[step];
At1_r += w1*r;
At1_g += w1*g;
At1_b += w1*b;
At2_r += r;
At2_g += g;
At2_b += b;
}
At2_r = 3*At2_r - At1_r;
At2_g = 3*At2_g - At1_g;
At2_b = 3*At2_b - At1_b;
// extract solutions and decide solvability
xx = akku >> 16;
yy = (akku >> 8) & 0xff;
xy = (akku >> 0) & 0xff;
frb = 3.0f * 31.0f / 255.0f / (xx*yy - xy*xy);
fg = frb * 63.0f / 31.0f;
// solve.
max16 = stb__sclamp((At1_r*yy - At2_r*xy)*frb+0.5f,0,31) << 11;
max16 |= stb__sclamp((At1_g*yy - At2_g*xy)*fg +0.5f,0,63) << 5;
max16 |= stb__sclamp((At1_b*yy - At2_b*xy)*frb+0.5f,0,31) << 0;
min16 = stb__sclamp((At2_r*xx - At1_r*xy)*frb+0.5f,0,31) << 11;
min16 |= stb__sclamp((At2_g*xx - At1_g*xy)*fg +0.5f,0,63) << 5;
min16 |= stb__sclamp((At2_b*xx - At1_b*xy)*frb+0.5f,0,31) << 0;
}
*pmin16 = min16;
*pmax16 = max16;
return oldMin != min16 || oldMax != max16;
}
// Color block compression
static void stb__CompressColorBlock(unsigned char *dest, unsigned char *block, int mode)
{
unsigned int mask;
int i;
int dither;
int refinecount;
unsigned short max16, min16;
unsigned char dblock[16*4],color[4*4];
dither = mode & STB_DXT_DITHER;
refinecount = (mode & STB_DXT_HIGHQUAL) ? 2 : 1;
// check if block is constant
for (i=1;i<16;i++)
if (((unsigned int *) block)[i] != ((unsigned int *) block)[0])
break;
if(i == 16) { // constant color
int r = block[0], g = block[1], b = block[2];
mask = 0xaaaaaaaa;
max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0];
min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1];
} else {
// first step: compute dithered version for PCA if desired
if(dither)
stb__DitherBlock(dblock,block);
// second step: pca+map along principal axis
stb__OptimizeColorsBlock(dither ? dblock : block,&max16,&min16);
if (max16 != min16) {
stb__EvalColors(color,max16,min16);
mask = stb__MatchColorsBlock(block,color,dither);
} else
mask = 0;
// third step: refine (multiple times if requested)
for (i=0;i<refinecount;i++) {
unsigned int lastmask = mask;
if (stb__RefineBlock(dither ? dblock : block,&max16,&min16,mask)) {
if (max16 != min16) {
stb__EvalColors(color,max16,min16);
mask = stb__MatchColorsBlock(block,color,dither);
} else {
mask = 0;
break;
}
}
if(mask == lastmask)
break;
}
}
// write the color block
if(max16 < min16)
{
unsigned short t = min16;
min16 = max16;
max16 = t;
mask ^= 0x55555555;
}
dest[0] = (unsigned char) (max16);
dest[1] = (unsigned char) (max16 >> 8);
dest[2] = (unsigned char) (min16);
dest[3] = (unsigned char) (min16 >> 8);
dest[4] = (unsigned char) (mask);
dest[5] = (unsigned char) (mask >> 8);
dest[6] = (unsigned char) (mask >> 16);
dest[7] = (unsigned char) (mask >> 24);
}
// Alpha block compression (this is easy for a change)
static void stb__CompressAlphaBlock(unsigned char *dest,unsigned char *src,int mode)
{
int i,dist,bias,dist4,dist2,bits,mask;
// find min/max color
int mn,mx;
mn = mx = src[3];
for (i=1;i<16;i++)
{
if (src[i*4+3] < mn) mn = src[i*4+3];
else if (src[i*4+3] > mx) mx = src[i*4+3];
}
// encode them
((unsigned char *)dest)[0] = mx;
((unsigned char *)dest)[1] = mn;
dest += 2;
// determine bias and emit color indices
// given the choice of mx/mn, these indices are optimal:
// http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/
dist = mx-mn;
dist4 = dist*4;
dist2 = dist*2;
bias = (dist < 8) ? (dist - 1) : (dist/2 + 2);
bias -= mn * 7;
bits = 0,mask=0;
for (i=0;i<16;i++) {
int a = src[i*4+3]*7 + bias;
int ind,t;
// select index. this is a "linear scale" lerp factor between 0 (val=min) and 7 (val=max).
t = (a >= dist4) ? -1 : 0; ind = t & 4; a -= dist4 & t;
t = (a >= dist2) ? -1 : 0; ind += t & 2; a -= dist2 & t;
ind += (a >= dist);
// turn linear scale into DXT index (0/1 are extremal pts)
ind = -ind & 7;
ind ^= (2 > ind);
// write index
mask |= ind << bits;
if((bits += 3) >= 8) {
*dest++ = mask;
mask >>= 8;
bits -= 8;
}
}
}
static void stb__InitDXT()
{
int i;
for(i=0;i<32;i++)
stb__Expand5[i] = (i<<3)|(i>>2);
for(i=0;i<64;i++)
stb__Expand6[i] = (i<<2)|(i>>4);
for(i=0;i<256+16;i++)
{
int v = i-8 < 0 ? 0 : i-8 > 255 ? 255 : i-8;
stb__QuantRBTab[i] = stb__Expand5[stb__Mul8Bit(v,31)];
stb__QuantGTab[i] = stb__Expand6[stb__Mul8Bit(v,63)];
}
stb__PrepareOptTable(&stb__OMatch5[0][0],stb__Expand5,32);
stb__PrepareOptTable(&stb__OMatch6[0][0],stb__Expand6,64);
}
void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode)
{
static int init=1;
if (init) {
stb__InitDXT();
init=0;
}
if (alpha) {
stb__CompressAlphaBlock(dest,(unsigned char*) src,mode);
dest += 8;
}
stb__CompressColorBlock(dest,(unsigned char*) src,mode);
}
#endif // STB_DXT_IMPLEMENTATION
#endif // STB_INCLUDE_STB_DXT_H

5099
public/bitmap/stb_image.c Normal file

File diff suppressed because it is too large Load Diff

80
public/bitmap/stb_image.h Normal file
View File

@@ -0,0 +1,80 @@
/* stbi-1.29 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
when you control the images you're loading
no warranty implied; use at your own risk
QUICK NOTES:
Primarily of interest to game developers and other people who can
avoid problematic images and only need the trivial interface
JPEG baseline (no JPEG progressive)
PNG 8-bit only
TGA (not sure what subset, if a subset)
BMP non-1bpp, non-RLE
PSD (composited view only, no extra channels)
GIF (*comp always reports as 4-channel)
HDR (radiance rgbE format)
PIC (Softimage PIC)
- decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code)
- supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
Latest revisions:
1.29 (2010-08-16) various warning fixes from Aurelien Pocheville
1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ)
1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila)
allow trailing 0s at end of image data (Laurent Gomila)
1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ
1.25 (2010-07-17) refix trans_data warning (Won Chun)
1.24 (2010-07-12) perf improvements reading from files
minor perf improvements for jpeg
deprecated type-specific functions in hope of feedback
attempt to fix trans_data warning (Won Chun)
1.23 fixed bug in iPhone support
1.22 (2010-07-10) removed image *writing* support to stb_image_write.h
stbi_info support from Jetro Lauha
GIF support from Jean-Marc Lienher
iPhone PNG-extensions from James Brown
warning-fixes from Nicolas Schulz and Janez Zemva
1.21 fix use of 'uint8' in header (reported by jon blow)
1.20 added support for Softimage PIC, by Tom Seddon
See end of file for full revision history.
TODO:
stbi_info support for BMP,PSD,HDR,PIC
rewrite stbi_info and load_file variations to share file handling code
(current system allows individual functions to be called directly,
since each does all the work, but I doubt anyone uses this in practice)
============================ Contributors =========================
Image formats Optimizations & bugfixes
Sean Barrett (jpeg, png, bmp) Fabian "ryg" Giesen
Nicolas Schulz (hdr, psd)
Jonathan Dummer (tga) Bug fixes & warning fixes
Jean-Marc Lienher (gif) Marc LeBlanc
Tom Seddon (pic) Christpher Lloyd
Thatcher Ulrich (psd) Dave Moore
Won Chun
the Horde3D community
Extensions, features Janez Zemva
Jetro Lauha (stbi_info) Jonathan Blow
James "moose2000" Brown (iPhone PNG) Laurent Gomila
Aruelien Pocheville
If your name should be here but isn't, let Sean know.
*/
#ifndef STBI_INCLUDE_STB_IMAGE_H
#define STBI_INCLUDE_STB_IMAGE_H
// To get a header file for this, either cut and paste the header,
// or create stb_image.h, #define STBI_HEADER_FILE_ONLY, and
// then include stb_image.c from it.
#define STBI_HEADER_FILE_ONLY
#include "stb_image.c"

View File

@@ -0,0 +1,72 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef TEXTUREPACKER_H
#define TEXTUREPACKER_H
#ifdef _WIN32
#pragma once
#endif
#include "utlntree.h"
#define DEFAULT_TEXTURE_PAGE_WIDTH 1024
#define DEFAULT_TEXTURE_PAGE_WIDTH 1024
//-----------------------------------------------------------------------------
// Purpose: manages texture packing of textures as they are added.
//-----------------------------------------------------------------------------
class CTexturePacker
{
public:
struct TreeEntry_t
{
Rect_t rc;
bool bInUse;
};
CTexturePacker( int texWidth = DEFAULT_TEXTURE_PAGE_WIDTH, int texHeight = DEFAULT_TEXTURE_PAGE_WIDTH, int pixelGap = 0 );
~CTexturePacker();
// Use -1 if you want to insert at the root.
int InsertRect( const Rect_t& texRect, int nodeIndex = -1 );
bool RemoveRect( int nodeIndex );
const TreeEntry_t &GetEntry( int i )
{
return m_Tree[i];
}
int GetPageWidth()
{
return m_PageWidth;
}
int GetPageHeight()
{
return m_PageHeight;
}
// clears the tree
void Clear();
private:
bool IsLeaf( int nodeIndex );
bool IsLeftChild( int nodeIndexParent, int nodeIndexChild );
bool IsRightChild( int nodeIndexParent, int nodeIndexChild );
// Pixel gap between textures.
int m_PixelGap;
int m_PageWidth;
int m_PageHeight;
CUtlNTree< TreeEntry_t > m_Tree;
};
#endif // TEXTUREPACKER_H

45
public/bitmap/tgaloader.h Normal file
View File

@@ -0,0 +1,45 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//===========================================================================//
#ifndef TGALOADER_H
#define TGALOADER_H
#ifdef _WIN32
#pragma once
#endif
#include "bitmap/imageformat.h"
#include "tier1/utlmemory.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CUtlBuffer;
namespace TGALoader
{
int TGAHeaderSize();
bool GetInfo( const char *fileName, int *width, int *height, ImageFormat *imageFormat, float *sourceGamma );
bool GetInfo( CUtlBuffer &buf, int *width, int *height, ImageFormat *imageFormat, float *sourceGamma );
bool Load( unsigned char *imageData, const char *fileName, int width, int height,
ImageFormat imageFormat, float targetGamma, bool mipmap );
bool Load( unsigned char *imageData, CUtlBuffer &buf, int width, int height,
ImageFormat imageFormat, float targetGamma, bool mipmap );
bool LoadRGBA8888( const char *pFileName, CUtlMemory<unsigned char> &outputData, int &outWidth, int &outHeight );
bool LoadRGBA8888( CUtlBuffer &buf, CUtlMemory<unsigned char> &outputData, int &outWidth, int &outHeight );
} // end namespace TGALoader
#endif // TGALOADER_H

35
public/bitmap/tgawriter.h Normal file
View File

@@ -0,0 +1,35 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef TGAWRITER_H
#define TGAWRITER_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/interface.h"
#include "bitmap/imageformat.h" //ImageFormat enum definition
class CUtlBuffer;
namespace TGAWriter
{
bool WriteToBuffer( unsigned char *pImageData, CUtlBuffer &buffer, int width, int height, ImageFormat srcFormat, ImageFormat dstFormat );
// Write out a simple tga file from a memory buffer.
bool WriteTGAFile( const char *fileName, int width, int height, enum ImageFormat srcFormat, uint8 const *srcData, int nStride );
// Routines for writing to files without allocating any memory in the TGA writer
// Useful for very large files such as posters, which are rendered as sub-rects
bool WriteDummyFileNoAlloc( const char *fileName, int width, int height, ImageFormat dstFormat );
bool WriteRectNoAlloc( unsigned char *pImageData, const char *fileName, int nXOrigin, int nYOrigin, int width, int height, int nStride, ImageFormat srcFormat );
bool WriteRectNoAllocFeather( unsigned char *pImageData, const char *fileName, int nXOrigin, int nYOrigin, int width, int height, int nGuardBandWidth, int nGuardBandHeight, int nStride, enum ImageFormat srcFormat );
} // end namespace TGAWriter
#endif // TGAWRITER_H

46
public/bittools.h Normal file
View File

@@ -0,0 +1,46 @@
//===== Copyright <20> 1996-2009, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef BITTOOLS_H
#define BITTOOLS_H
#ifdef _WIN32
#pragma once
#endif
namespace bittools
{
template<int N, int C = 0>
struct RecurseBit
{
enum {result = RecurseBit<N/2, C+1>::result};
};
template<int C>
struct RecurseBit<0, C>
{
enum {result = C};
};
template<int N, int C = 1>
struct RecursePow2
{
enum {result = RecursePow2<N/2, C*2>::result};
};
template<int C>
struct RecursePow2<0, C>
{
enum {result = C};
};
}
#define ROUND_TO_POWER_OF_2( n ) ( bittools::RecursePow2< (n) - 1 >::result )
#define MINIMUM_BITS_NEEDED( n ) ( bittools::RecurseBit< (n) - 1 >::result )
#endif //BITTOOLS_H

1630
public/bitvec.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,170 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#if defined(_WIN32) && !defined(_X360)
#include <winsock.h>
#elif defined( _PS3 )
#include "blockingudpsocket.h"
#elif POSIX
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define closesocket close
#endif
#include "blockingudpsocket.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
#ifdef _PS3
CBlockingUDPSocket::CBlockingUDPSocket() : m_pImpl( NULL ), m_Socket( 0 ) {}
CBlockingUDPSocket::~CBlockingUDPSocket() {}
bool CBlockingUDPSocket::WaitForMessage( float timeOutInSeconds ) { return false; }
unsigned int CBlockingUDPSocket::ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize ) { return 0; }
bool CBlockingUDPSocket::SendSocketMessage( const struct sockaddr_in& rRecipient, const unsigned char *buf, size_t bufsize ) { return false; }
bool CBlockingUDPSocket::CreateSocket (void) { return false; }
#else
class CBlockingUDPSocket::CImpl
{
public:
struct sockaddr_in m_SocketIP;
fd_set m_FDSet;
};
CBlockingUDPSocket::CBlockingUDPSocket() :
m_cserIP(),
m_Socket( 0 ),
m_pImpl( new CImpl )
{
CreateSocket();
}
CBlockingUDPSocket::~CBlockingUDPSocket()
{
delete m_pImpl;
closesocket( static_cast<unsigned int>( m_Socket ));
}
bool CBlockingUDPSocket::CreateSocket (void)
{
struct sockaddr_in address;
m_Socket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
if ( m_Socket == INVALID_SOCKET )
{
return false;
}
address = m_pImpl->m_SocketIP;
if ( SOCKET_ERROR == bind( m_Socket, ( struct sockaddr * )&address, sizeof( address ) ) )
{
return false;
}
#ifdef _WIN32
if ( m_pImpl->m_SocketIP.sin_addr.S_un.S_addr == INADDR_ANY )
{
m_pImpl->m_SocketIP.sin_addr.S_un.S_addr = 0L;
}
#elif POSIX
if ( m_pImpl->m_SocketIP.sin_addr.s_addr == INADDR_ANY )
{
m_pImpl->m_SocketIP.sin_addr.s_addr = 0L;
}
#endif
return true;
}
bool CBlockingUDPSocket::WaitForMessage( float timeOutInSeconds )
{
struct timeval tv;
FD_ZERO( &m_pImpl->m_FDSet );
FD_SET( m_Socket, &m_pImpl->m_FDSet );//lint !e717
tv.tv_sec = (int)timeOutInSeconds;
float remainder = timeOutInSeconds - (int)timeOutInSeconds;
tv.tv_usec = (int)( remainder * 1000000 + 0.5f ); /* micro seconds */
if ( SOCKET_ERROR == select( ( int )m_Socket + 1, &m_pImpl->m_FDSet, NULL, NULL, &tv ) )
{
return false;
}
if ( FD_ISSET( m_Socket, &m_pImpl->m_FDSet) )
{
return true;
}
// Timed out
return false;
}
unsigned int CBlockingUDPSocket::ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize )
{
memset( packet_from, 0, sizeof( *packet_from ) );
struct sockaddr fromaddress;
int fromlen = sizeof( fromaddress );
int packet_length = recvfrom
(
m_Socket,
(char *)buf,
(int)bufsize,
0,
&fromaddress,
(socklen_t *)&fromlen
);
if ( SOCKET_ERROR == packet_length )
{
return 0;
}
// In case it's parsed as a string
buf[ packet_length ] = 0;
// Copy over the receive address
*packet_from = *( struct sockaddr_in * )&fromaddress;
return ( unsigned int )packet_length;
}
bool CBlockingUDPSocket::SendSocketMessage( const struct sockaddr_in & rRecipient, const unsigned char *buf, size_t bufsize )
{
// Send data
int bytesSent = sendto
(
m_Socket,
(const char *)buf,
(int)bufsize,
0,
reinterpret_cast< const sockaddr * >( &rRecipient ),
sizeof( rRecipient )
);
if ( SOCKET_ERROR == bytesSent )
{
return false;
}
return true;
}
#endif

View File

@@ -0,0 +1,41 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef BLOCKINGUDPSOCKET_H
#define BLOCKINGUDPSOCKET_H
#ifdef _WIN32
#pragma once
#endif
#include "netadr.h"
class CBlockingUDPSocket
{
public:
explicit CBlockingUDPSocket();
virtual ~CBlockingUDPSocket();
bool WaitForMessage( float timeOutInSeconds );
unsigned int ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize );
bool SendSocketMessage( const struct sockaddr_in& rRecipient, const unsigned char *buf, size_t bufsize );
bool IsValid() const { return m_Socket != 0; }
protected:
bool CreateSocket (void);
class CImpl;
CImpl *m_pImpl;
netadr_t m_cserIP;
unsigned int m_Socket;
private:
CBlockingUDPSocket( const CBlockingUDPSocket& ); // = delete
CBlockingUDPSocket& operator= ( const CBlockingUDPSocket& ); // = delete
};
#endif // BLOCKINGUDPSOCKET_H

64
public/bone_accessor.cpp Normal file
View File

@@ -0,0 +1,64 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "bone_accessor.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
bool CBoneAccessor::isBoneAvailableForRead( int iBone ) const
{
if ( m_pAnimating )
{
CStudioHdr *pHdr = m_pAnimating->GetModelPtr();
if ( pHdr )
{
return ( pHdr->boneFlags( iBone ) & m_ReadableBones ) != 0;
}
}
return false;
}
bool CBoneAccessor::isBoneAvailableForWrite( int iBone ) const
{
if ( m_pAnimating )
{
CStudioHdr *pHdr = m_pAnimating->GetModelPtr();
if ( pHdr )
{
// double check consistency
// !!! DbgAssert( pHdr->pBone( iBone )->flags == pHdr->boneFlags( iBone ) );
return ( pHdr->boneFlags( iBone ) & m_WritableBones ) != 0;
}
}
return false;
}
#if defined( CLIENT_DLL ) && defined( _DEBUG )
void CBoneAccessor::SanityCheckBone( int iBone, bool bReadable ) const
{
if ( !m_pAnimating )
{
return;
}
if ( bReadable )
{
Assert( isBoneAvailableForRead( iBone ) );
}
else
{
Assert( isBoneAvailableForWrite( iBone ) );
}
}
#endif

135
public/bone_accessor.h Normal file
View File

@@ -0,0 +1,135 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef BONE_ACCESSOR_H
#define BONE_ACCESSOR_H
#ifdef _WIN32
#pragma once
#endif
#include "studio.h"
class C_BaseAnimating;
class CBoneAccessor
{
public:
CBoneAccessor();
explicit CBoneAccessor( matrix3x4a_t *pBones ); // This can be used to allow access to all bones.
// Initialize.
#if defined( CLIENT_DLL )
void Init( const C_BaseAnimating *pAnimating, matrix3x4a_t *pBones );
#endif
int GetReadableBones();
void SetReadableBones( int flags );
int GetWritableBones();
void SetWritableBones( int flags );
bool isBoneAvailableForRead( int iBone ) const;
bool isBoneAvailableForWrite( int iBone ) const;
// Get bones for read or write access.
const matrix3x4a_t& GetBone( int iBone ) const;
const matrix3x4a_t& operator[]( int iBone ) const;
matrix3x4a_t& GetBoneForWrite( int iBone );
matrix3x4a_t *GetBoneArrayForWrite( ) const;
private:
#if defined( CLIENT_DLL ) && defined( _DEBUG )
void SanityCheckBone( int iBone, bool bReadable ) const;
#endif
// Only used in the client DLL for debug verification.
const C_BaseAnimating *m_pAnimating;
matrix3x4a_t *m_pBones;
int m_ReadableBones; // Which bones can be read.
int m_WritableBones; // Which bones can be written.
};
inline CBoneAccessor::CBoneAccessor()
{
m_pAnimating = NULL;
m_pBones = NULL;
m_ReadableBones = m_WritableBones = 0;
}
inline CBoneAccessor::CBoneAccessor( matrix3x4a_t *pBones )
{
m_pAnimating = NULL;
m_pBones = pBones;
}
#if defined( CLIENT_DLL )
inline void CBoneAccessor::Init( const C_BaseAnimating *pAnimating, matrix3x4a_t *pBones )
{
m_pAnimating = pAnimating;
m_pBones = pBones;
}
#endif
inline int CBoneAccessor::GetReadableBones()
{
return m_ReadableBones;
}
inline void CBoneAccessor::SetReadableBones( int flags )
{
m_ReadableBones = flags;
}
inline int CBoneAccessor::GetWritableBones()
{
return m_WritableBones;
}
inline void CBoneAccessor::SetWritableBones( int flags )
{
m_WritableBones = flags;
}
inline const matrix3x4a_t& CBoneAccessor::GetBone( int iBone ) const
{
#if defined( CLIENT_DLL ) && defined( _DEBUG )
SanityCheckBone( iBone, true );
#endif
return m_pBones[iBone];
}
inline const matrix3x4a_t& CBoneAccessor::operator[]( int iBone ) const
{
#if defined( CLIENT_DLL ) && defined( _DEBUG )
SanityCheckBone( iBone, true );
#endif
return m_pBones[iBone];
}
inline matrix3x4a_t& CBoneAccessor::GetBoneForWrite( int iBone )
{
#if defined( CLIENT_DLL ) && defined( _DEBUG )
SanityCheckBone( iBone, false );
#endif
return m_pBones[iBone];
}
inline matrix3x4a_t *CBoneAccessor::GetBoneArrayForWrite( void ) const
{
return m_pBones;
}
#endif // BONE_ACCESSOR_H

200
public/bone_constraints.h Normal file
View File

@@ -0,0 +1,200 @@
//============ Copyright (c) Valve Corporation, All rights reserved. ============
//
// Generic constraint functions to compute bone constraints
// Used by studio/engine, SFM & Maya
//
// Studio interface functions to the generic constraint functions
//
//===============================================================================
#ifndef BONE_CONSTRAINTS_H
#define BONE_CONSTRAINTS_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct mstudiobone_t;
class CBoneAccessor;
class CStudioHdr;
struct mstudioconstrainttarget_t;
struct mstudioconstraintslave_t;
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
class CConstraintBones
{
public:
enum AimConstraintUpType_t
{
AC_UP_TYPE_OBJECT_ROTATION, // Use supplied vector rotated by the specified object as up vector (Maya: Object Rotation Up), if no dag is supplied, reverts to Vector
AC_UP_TYPE_VECTOR, // Use supplied vector as up vector (Maya: Vector)
AC_UP_TYPE_OBJECT, // Use vector from slave to specified object in world space as up vector( Maya: Object Up), if no dag is supplied, reverts to Vector
AC_UP_TYPE_PARENT_ROTATION, // Use supplied vector rotated by the parent object as up vector (Maya: None)
AC_UP_TYPE_FIRST = AC_UP_TYPE_OBJECT_ROTATION, // The smallest possible value
AC_UP_TYPE_LAST = AC_UP_TYPE_PARENT_ROTATION, // The largest possible value
};
// Compute the aggregate target position and orientation from the weighted target list and return
// the resulting position and orientation in addition to updating the target dag.
// All passed arrays must be nTargetCount in length
static float ComputeTargetPosition(
Vector &vTargetPosition,
int nTargetCount,
float *flTargetWeights,
Vector *vTargetPositions,
Vector *vTargetOffsets );
// Compute the aggregate target orientation from the weighted target list and
// return the total weight
// All passed arrays must be nTargetCount in length
static float ComputeTargetOrientation(
Quaternion &qTargetOrientation,
int nTargetCount,
float *pflTargetWeights,
Quaternion *pqTargetOrientations,
Quaternion *pqTargetOffsets );
// Compute the aggregate target position and orientation from the weighted
// target list and return the total weight
// All passed arrays must be nTargetCount in length
static float ComputeTargetPositionOrientation(
Vector &vTargetPosition,
Quaternion &qTargetOrientation,
int nTargetCount,
float *pflTargetWeights,
Vector *vTargetPositions,
Vector *vTargetOffsets,
Quaternion *pqTargetOrientations,
Quaternion *pqTargetOffsets );
// Compute the aggregate target position and orientation from the weighted
// target list and return the total weight
// All passed arrays must be nTargetCount in length
static float ComputeTargetPositionOrientation(
Vector &vTargetPosition,
Quaternion &qTargetOrientation,
int nTargetCount,
float *pflTargetWeights,
matrix3x4a_t *pmTargets,
matrix3x4a_t *pmOffsets );
static void ComputeAimConstraintOffset(
Quaternion &qAimOffset,
bool bPreserveOffset,
const Vector &vTargetWorldPos,
const matrix3x4_t &mSlaveParentToWorld,
const Vector &vUp,
const Vector &vSlaveLocalPos,
const Quaternion &qSlaveLocal,
matrix3x4_t *pmUpToWorld,
AimConstraintUpType_t eUpType );
// Calculate the orientation needed to make a transform where the y
// vector of the transform matches the forward vector and the z vector matches
// the up reference vector as closely as possible. The x vector will be in the
// plane defined by using the forward vector as the normal.
static void ComputeAimConstraintAimAt(
Quaternion &qAim,
const Vector &vForward,
const Vector &vReferenceUp );
// Given the various parameters, computes the local vForward & vReferenceUp
// and calls ComputeAimConstraintAimAt
static void ComputeAimConstraint(
Quaternion &qAim,
const Vector &vTargetWorldPos,
const matrix3x4_t &mParentToWorld,
const Vector &vUp,
const Vector &vSlaveLocalPos,
const matrix3x4_t *pmUpToWorld,
AimConstraintUpType_t eUpType );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static void ComputeWorldUpVector(
Vector *pvWorldUp,
const matrix3x4_t & mParentToWorld,
const Vector &vUp,
const Vector &vSlaveLocalPos,
const matrix3x4_t *pmUpToWorld,
AimConstraintUpType_t eUpType );
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
class CStudioConstraintBones : public CConstraintBones
{
public:
// Utilities
static float ComputeTargetPosition(
Vector &vTargetPosition,
mstudioconstrainttarget_t *pTargets,
int nTargetCount,
CBoneAccessor &boneToWorld );
static float ComputeTargetOrientation(
Quaternion &qTargetOrientation,
mstudioconstrainttarget_t *pTargets,
int nTargetCount,
CBoneAccessor &boneToWorld );
static float ComputeTargetPositionOrientation(
Vector &vTargetPosition,
Quaternion &qTargetOrientation,
mstudioconstrainttarget_t *pTargets,
int nTargetCount,
CBoneAccessor &boneToWorld );
static void ComputeBaseWorldMatrix(
matrix3x4a_t &mBaseWorldMatrix,
mstudioconstraintslave_t *pSlave,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr,
const matrix3x4_t *pmViewTransform = NULL );
// constraints
static void ComputePointConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr );
static void ComputeOrientConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr,
const matrix3x4_t *pmViewTransform );
static void ComputeAimConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr,
const matrix3x4_t *pmViewTransform,
AimConstraintUpType_t eType );
static void ComputeParentConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr );
};
#endif // BONE_CONSTRAINTS_H

491
public/bone_setup.h Normal file
View File

@@ -0,0 +1,491 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BONE_SETUP_H
#define BONE_SETUP_H
#ifdef _WIN32
#pragma once
#endif
#include "studio.h"
#include "cmodel.h"
#include "bitvec.h"
class CBoneToWorld;
class CIKContext;
class CBoneAccessor;
class IPoseDebugger;
// This provides access to networked arrays, so if this code actually changes a value,
// the entity is marked as changed.
abstract_class IParameterAccess
{
public:
virtual float GetParameter( int iParam ) = 0;
virtual void SetParameter( int iParam, float flValue ) = 0;
};
class CBoneBitList : public CBitVec<MAXSTUDIOBONES>
{
public:
inline void MarkBone(int iBone)
{
Set(iBone);
}
inline bool IsBoneMarked(int iBone)
{
return Get(iBone) != 0 ? true : false;
}
};
//-----------------------------------------------------------------------------
// Purpose: blends together all the bones from two p:q lists
//
// p1 = p1 * (1 - s) + p2 * s
// q1 = q1 * (1 - s) + q2 * s
//-----------------------------------------------------------------------------
void SlerpBones(
const CStudioHdr *pStudioHdr,
BoneQuaternion q1[MAXSTUDIOBONES],
BoneVector pos1[MAXSTUDIOBONES],
mstudioseqdesc_t &seqdesc, // source of q2 and pos2
int sequence,
const BoneQuaternionAligned q2[MAXSTUDIOBONES],
const BoneVector pos2[MAXSTUDIOBONES],
float s,
int boneMask
);
class CBoneSetup;
class IBoneSetup
{
public:
IBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger = NULL );
~IBoneSetup( void );
void InitPose( BoneVector pos[], BoneQuaternionAligned q[] );
void AccumulatePose( BoneVector pos[], BoneQuaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext );
void CalcAutoplaySequences( BoneVector pos[], BoneQuaternion q[], float flRealTime, CIKContext *pIKContext );
void CalcBoneAdj( BoneVector pos[], BoneQuaternion q[], const float controllers[] );
CStudioHdr *GetStudioHdr();
private:
CBoneSetup *m_pBoneSetup;
};
// Given two samples of a bone separated in time by dt,
// compute the velocity and angular velocity of that bone
void CalcBoneDerivatives( Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &prev, const matrix3x4_t &current, float dt );
// Give a derivative of a bone, compute the velocity & angular velocity of that bone
void CalcBoneVelocityFromDerivative( const QAngle &vecAngles, Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &current );
// This function sets up the local transform for a single frame of animation. It doesn't handle
// pose parameters or interpolation between frames.
void SetupSingleBoneMatrix(
CStudioHdr *pOwnerHdr,
int nSequence,
int iFrame,
int iBone,
matrix3x4_t &mBoneLocal );
// Purpose: build boneToWorld transforms for a specific bone
void BuildBoneChain(
const CStudioHdr *pStudioHdr,
const matrix3x4a_t &rootxform,
const BoneVector pos[],
const BoneQuaternion q[],
int iBone,
matrix3x4a_t *pBoneToWorld );
void BuildBoneChain(
const CStudioHdr *pStudioHdr,
const matrix3x4a_t &rootxform,
const BoneVector pos[],
const BoneQuaternion q[],
int iBone,
matrix3x4a_t *pBoneToWorld,
CBoneBitList &boneComputed );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
// ik info
class CIKTarget
{
public:
void SetOwner( int entindex, const Vector &pos, const QAngle &angles );
void ClearOwner( void );
int GetOwner( void );
void UpdateOwner( int entindex, const Vector &pos, const QAngle &angles );
void SetPos( const Vector &pos );
void SetAngles( const QAngle &angles );
void SetQuaternion( const Quaternion &q );
void SetNormal( const Vector &normal );
void SetPosWithNormalOffset( const Vector &pos, const Vector &normal );
void SetOnWorld( bool bOnWorld = true );
bool IsActive( void );
void IKFailed( void );
int chain;
int type;
void MoveReferenceFrame( Vector &deltaPos, QAngle &deltaAngles );
// accumulated offset from ideal footplant location
public:
struct x2 {
char *pAttachmentName;
Vector pos;
Quaternion q;
} offset;
private:
struct x3 {
Vector pos;
Quaternion q;
} ideal;
public:
struct x4 {
float latched;
float release;
float height;
float floor;
float radius;
float flTime;
float flWeight;
Vector pos;
Quaternion q;
bool onWorld;
} est; // estimate contact position
struct x5 {
float hipToFoot; // distance from hip
float hipToKnee; // distance from hip to knee
float kneeToFoot; // distance from knee to foot
Vector hip; // location of hip
Vector closest; // closest valid location from hip to foot that the foot can move to
Vector knee; // pre-ik location of knee
Vector farthest; // farthest valid location from hip to foot that the foot can move to
Vector lowest; // lowest position directly below hip that the foot can drop to
} trace;
private:
// internally latched footset, position
struct x1 {
// matrix3x4a_t worldTarget;
bool bNeedsLatch;
bool bHasLatch;
float influence;
int iFramecounter;
int owner;
Vector absOrigin;
QAngle absAngles;
Vector pos;
Quaternion q;
Vector deltaPos; // acculated error
Quaternion deltaQ;
Vector debouncePos;
Quaternion debounceQ;
} latched;
struct x6 {
float flTime; // time last error was detected
float flErrorTime;
float ramp;
bool bInError;
} error;
friend class CIKContext;
};
struct ikchainresult_t
{
// accumulated offset from ideal footplant location
int target;
Vector pos;
Quaternion q;
float flWeight;
};
struct ikcontextikrule_t
{
int index;
int type;
int chain;
int bone;
int slot; // iktarget slot. Usually same as chain.
float height;
float radius;
float floor;
Vector pos;
float pad1;
Quaternion q;
float start; // beginning of influence
float peak; // start of full influence
float tail; // end of full influence
float end; // end of all influence
float top;
float drop;
float commit; // frame footstep target should be committed
float release; // frame ankle should end rotation from latched orientation
float flWeight; // processed version of start-end cycle
float flRuleWeight; // blending weight
float latched; // does the IK rule use a latched value?
char *szLabel;
Vector kneeDir;
float pad2;
Vector kneePos;
float pad3;
ikcontextikrule_t() {}
private:
// No copy constructors allowed
ikcontextikrule_t(const ikcontextikrule_t& vOther);
};
void Studio_AlignIKMatrix( matrix3x4a_t &mMat, const Vector &vAlignTo );
bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, matrix3x4a_t* pBoneToWorld );
bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4a_t* pBoneToWorld );
class CIKContext
{
public:
CIKContext( );
void Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask );
void AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight = 1.0f );
#if defined( _PS3 )
void AddAllDependencies_PS3( ikcontextikrule_t *ikRules, int numRules );
#endif
void ClearTargets( void );
void UpdateTargets( BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed );
void AutoIKRelease( void );
void SolveDependencies( BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed );
void AddAutoplayLocks( BoneVector pos[], BoneQuaternion q[] );
void SolveAutoplayLocks( BoneVector pos[], BoneQuaternion q[] );
void AddSequenceLocks( mstudioseqdesc_t &SeqDesc, BoneVector pos[], BoneQuaternion q[] );
void SolveSequenceLocks( mstudioseqdesc_t &SeqDesc, BoneVector pos[], BoneQuaternion q[] );
void AddAllLocks( BoneVector pos[], BoneQuaternion q[] );
void SolveAllLocks( BoneVector pos[], BoneQuaternion q[] );
void SolveLock( const mstudioiklock_t *plock, int i, BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed );
CUtlVectorFixed< CIKTarget, 12 > m_target;
void CopyTo( CIKContext* pOther, const unsigned short * iRemapping );
void BuildBoneChain( const BoneVector pos[], const BoneQuaternion q[], int iBone, matrix3x4a_t *pBoneToWorld, CBoneBitList &boneComputed );
const int GetBoneMask( void ) { return m_boneMask; }
private:
CStudioHdr const *m_pStudioHdr;
bool Estimate( int iSequence, float flCycle, int iTarget, const float poseParameter[], float flWeight = 1.0f );
// virtual IK rules, filtered and combined from each sequence
CUtlVector< CUtlVector< ikcontextikrule_t > > m_ikChainRule;
CUtlVector< ikcontextikrule_t > m_ikLock;
matrix3x4a_t m_rootxform;
int m_iFramecounter;
float m_flTime;
int m_boneMask;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
// replaces the bonetoworld transforms for all bones that are procedural
bool CalcProceduralBone(
const CStudioHdr *pStudioHdr,
int iBone,
CBoneAccessor &bonetoworld
);
void Studio_BuildMatrices(
const CStudioHdr *pStudioHdr,
const QAngle& angles,
const Vector& origin,
const BoneVector pos[],
const BoneQuaternion q[],
int iBone,
float flScale,
matrix3x4a_t bonetoworld[MAXSTUDIOBONES],
int boneMask
);
// Get a bone->bone relative transform
void Studio_CalcBoneToBoneTransform( const CStudioHdr *pStudioHdr, int inputBoneIndex, int outputBoneIndex, matrix3x4_t &matrixOut );
// Given a bone rotation value, figures out the value you need to give to the controller
// to have the bone at that value.
// [in] flValue = the desired bone rotation value
// [out] ctlValue = the (0-1) value to set the controller t.
// return value = flValue, unwrapped to lie between the controller's start and end.
float Studio_SetController( const CStudioHdr *pStudioHdr, int iController, float flValue, float &ctlValue );
// Given a 0-1 controller value, maps it into the controller's start and end and returns the bone rotation angle.
// [in] ctlValue = value in controller space (0-1).
// return value = value in bone space
float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float ctlValue );
void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[MAXSTUDIOPOSEPARAM], int nCount );
float Studio_GetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float ctlValue );
float Studio_SetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float flValue, float &ctlValue );
// converts a global 0..1 pose parameter into the local sequences blending value
int Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting );
void Studio_SeqAnims( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[], mstudioanimdesc_t *panim[4], float *weight );
int Studio_MaxFrame( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
float Studio_FPS( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
float Studio_CPS( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[] );
float Studio_Duration( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
void Studio_MovementRate( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
float Studio_SeqMovementAndDuration( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaPos );
// void Studio_Movement( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
//void Studio_AnimPosition( mstudioanimdesc_t *panim, float flCycle, Vector &vecPos, Vector &vecAngle );
//void Studio_AnimVelocity( mstudioanimdesc_t *panim, float flCycle, Vector &vecVelocity );
//float Studio_FindAnimDistance( mstudioanimdesc_t *panim, float flDist );
bool Studio_AnimMovement( mstudioanimdesc_t *panim, float flCycleFrom, float flCycleTo, Vector &deltaPos, QAngle &deltaAngle );
bool Studio_SeqMovement( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaMovement, QAngle &deltaAngle );
bool Studio_SeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, float flCycle, const float poseParameter[], Vector &vecVelocity );
float Studio_FindSeqDistance( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flDist );
float Studio_FindSeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flVelocity );
int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName );
const char *Studio_GetDefaultSurfaceProps( CStudioHdr *pstudiohdr );
float Studio_GetMass( CStudioHdr *pstudiohdr );
const char *Studio_GetKeyValueText( const CStudioHdr *pStudioHdr, int iSequence );
FORWARD_DECLARE_HANDLE( memhandle_t );
struct bonecacheparams_t
{
CStudioHdr *pStudioHdr;
matrix3x4a_t *pBoneToWorld;
float curtime;
int boneMask;
};
class CBoneCache
{
public:
// you must implement these static functions for the ResourceManager
// -----------------------------------------------------------
static CBoneCache *CreateResource( const bonecacheparams_t &params );
static unsigned int EstimatedSize( const bonecacheparams_t &params );
// -----------------------------------------------------------
// member functions that must be present for the ResourceManager
void DestroyResource();
CBoneCache *GetData() { return this; }
unsigned int Size() { return m_size; }
// -----------------------------------------------------------
CBoneCache();
// was constructor, but placement new is messy wrt memdebug - so cast & init instead
void Init( const bonecacheparams_t &params, unsigned int size, short *pStudioToCached, short *pCachedToStudio, int cachedBoneCount );
void UpdateBones( const matrix3x4a_t *pBoneToWorld, int numbones, float curtime );
matrix3x4a_t *GetCachedBone( int studioIndex );
void ReadCachedBones( matrix3x4a_t *pBoneToWorld );
void ReadCachedBonePointers( matrix3x4_t **bones, int numbones );
bool IsValid( float curtime, float dt = 0.1f );
public:
float m_timeValid;
int m_boneMask;
private:
matrix3x4a_t *BoneArray();
short *StudioToCached();
short *CachedToStudio();
unsigned int m_size;
unsigned short m_cachedBoneCount;
unsigned short m_matrixOffset;
unsigned short m_cachedToStudioOffset;
unsigned short m_boneOutOffset;
};
void Studio_LockBoneCache();
void Studio_UnlockBoneCache();
CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle, bool bLock = false );
void Studio_ReleaseBoneCache( memhandle_t cacheHandle );
memhandle_t Studio_CreateBoneCache( bonecacheparams_t &params );
void Studio_DestroyBoneCache( memhandle_t cacheHandle );
void Studio_InvalidateBoneCacheIfNotMatching( memhandle_t cacheHandle, float flTimeValid );
// Given a ray, trace for an intersection with this studiomodel. Get the array of bones from StudioSetupHitboxBones
bool TraceToStudio( class IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, matrix3x4_t **hitboxbones, int fContentsMask, const Vector &vecOrigin, float flScale, trace_t &trace );
// Given a ray, trace for an intersection with this studiomodel, bullets will hit bodyparts that result in higher damage
bool TraceToStudioCsgoHitgroupsPriority( class IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, matrix3x4_t **hitboxbones, int fContentsMask, const Vector &vecOrigin, float flScale, trace_t &trace );
// TERROR: TraceToStudio variant that prioritizes hitgroups, so bullets can pass through arms and chest to hit the head, for instance
bool TraceToStudioGrouped( IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set,
matrix3x4_t **hitboxbones, int fContentsMask, trace_t &tr, const CUtlVector< int > &sortedHitgroups );
void QuaternionSM( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt );
void QuaternionMA( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt );
bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence );
void Studio_RunBoneFlexDrivers( float *pFlexController, const CStudioHdr *pStudioHdr, const Vector *pPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld );
//-----------------------------------------------------------------------------
// Computes a number of twist bones given a parent/child pair
// pqTwists, pflWeights, pqTwistBinds must all have at least nCount elements
//-----------------------------------------------------------------------------
void ComputeTwistBones(
Quaternion *pqTwists,
int nCount,
bool bInverse,
const Vector &vUp,
const Quaternion &qParent,
const matrix3x4_t &mChild,
const Quaternion &qBaseInv,
const float *pflWeights,
const Quaternion *pqTwistBinds );
#endif // BONE_SETUP_H

917
public/bone_setup_PS3.h Normal file
View File

@@ -0,0 +1,917 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BONE_SETUP_PS3_H
#define BONE_SETUP_PS3_H
#ifndef __SPU__
#include "studio.h"
#endif
#include "studio_PS3.h"
#ifndef __SPU__
#include "bone_setup.h"
#include "vjobs/root.h"
#include "vjobs/accumpose_shared.h"
#include <vjobs_interface.h>
#include <ps3/vjobutils.h>
#include <ps3/vjobutils_shared.h>
#endif // __SPU__
#if defined( _PS3 )
#if defined(__SPU__)
#include "ps3/spu_job_shared.h"
#define SNPROF(name) ((void)0)
#define SNPROF_ANIM(name) ((void)0)
#endif
//#define _DEBUG_SPUvPPU_ANIMATION 1
#define ANIM_EPS 0.3f
//-----------------------------------------------------------------------------
// Purpose: SPU version of data collected and required by AccumulatePose
// this data gets sent to SPU
//-----------------------------------------------------------------------------
#define MAX_ACCUMPOSECALLS (20) //(MAX_OVERLAYS)
#define MAX_LAYERS_SPU MAX_ACCUMPOSECALLS
#define MAX_PQSTACKLEVEL 4
#define MAX_IKCHAINELEMENTS 32
#define MAX_IKCHAINS 16
#define MAX_IKLOCKS 16
#define MAX_IKRULES 48
#define MAX_IKTARGETS 12
#define MAX_BLENDANIMS 4
class CBoneBitList_PS3
{
public:
CBoneBitList_PS3()
{
memset( &m_markedBones, 0, MAXSTUDIOBONES_PS3 );
}
inline void MarkBone( int iBone )
{
m_markedBones[ iBone ] = 1;
}
inline bool IsBoneMarked( int iBone )
{
return m_markedBones[ iBone ];
}
inline void ResetMarkedBones( int numbones )
{
memset( &m_markedBones, 0, numbones );
}
byte m_markedBones[ MAXSTUDIOBONES_PS3 ];
};
struct animData_SPU
{
void *pEA_animdesc; // mstudioanimdesc_t *
int animstudiohdr_numbones;
int seqdesc_anim;
float flStall;
float seqdesc_weight;
int animdesc_iLocalFrame;
void *pEA_animdesc_panim; // mstudio_rle_anim_t *
void *pEA_animdesc_pFrameanim; // mstudio_frame_anim_t_PS3 *
void *pEA_animdesc_ikrule; // mstudioikrule_t_PS3 *
void *pEA_animdesc_ikrulezeroframe; // zero frame rule of above
void *pEA_animgroup_masterbone; // int *
void *pEA_anim_bones_pos; // Vector *, start of Vector pos, Quaternion quat, RadianEuler rot, Vector posscale, Vector rotscale, matrix3x4_t poseToBone, Quaternion qAlignment, int flags
void *pEA_anim_bones_flags; // int *, start of flags
void *pEA_anim_linearBones; // mstudiolinearbone_t_PS3 *
};
struct ALIGN128 accumposeentry_SPU
{
void *pEA_seqdesc; // mstudioseqdesc_t_PS3 *
void *pEA_seqgroup_boneMap; // const int *
void *pEA_seqgroup_masterBone; // const int *
void *pEA_seqdesc_boneWeight; // float *
void *pEA_seqdesc_iklocks; // mstudioiklock_t *
// from seqstudiohdr
void *pEA_seq_linearBones; // mstudiolinearbone_t_PS3 *
void *pEA_seq_linearbones_pos; // Vector *
void *pEA_seq_linearbones_quat; // Quaternion *
void *pEA_seq_bones_pos; // mstudiobone_t_PS3 * offset to .pos
int seqdesc_flags;
int cpsPath; // CalcPoseSingle path
animData_SPU anims[ MAX_BLENDANIMS ];
int8 animIndices[ MAX_BLENDANIMS ]; // index into anims[]
int pqStackLevel;
int iSeq;
float cycle;
float weight;
int i0;
int i1;
int seqdesc_numiklocks;
int seqdesc_numikrules;
float s0;
float s1;
float cyclePoseSingle;
int numLocalLayers;
int numSequenceLayers;
#if !defined(__SPU__)
bool SetAnimData( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int x, int y, int animIndex );
#endif
} ALIGN128_POST;
struct ALIGN128 bonejob_SPU
{
accumposeentry_SPU accumPoseEntry[ MAX_LAYERS_SPU ];
int numTotalPoses;
int numPoses_PreAutoSeq;
int numPoses_AutoSeq;
// same for all calls
int boneFlags[ MAXSTUDIOBONES_PS3 ]; // 1k
int boneParent[ MAXSTUDIOBONES_PS3 ]; // 1k
float poseparam[ MAXSTUDIOPOSEPARAM_PS3 ]; // 96B
void *pEA_IKAutoplayLocks[ MAX_IKLOCKS ]; // mstudioiklock_t
float currentTime;
int numBones;
int maxBones; // takes into account virtual bonemapping, used for SPU mem worst-case allocations
int numikchains;
int boneMask;
int studiobone_posoffset; // mstudiobone_t offset in bytes to pos field
BoneVector autoikOrigin;
QAngle autoikAngles;
int autoikFramecount;
int numikAutoplayLocks;
void *pEA_hdr; // CStudioHdr*
void *pEA_IKContext; // CIKContext *
void *pEA_studiohdr_ikchains; // mstudioikchain_t *
void *pEA_studiohdr_ikautoplaylocks; // mstudioiklock_t *
void *pEA_studiohdr_vmodel; // virtualmodel_t *
void *pEA_studiohdr_bones; // mstudiobone_t_PS3 *
void *pEA_studiohdr_bones_pos; // Vector *, start of Vector pos, Quaternion quat, RadianEuler rot, Vector posscale, Vector rotscale, matrix3x4_t poseToBone, Quaternion qAlignment, int flags
void *pEA_studiohdr_linearBones; // mstudiolinearbone_t_PS3 *
void *pEA_linearbones_posscale; // Vector *
void *pEA_linearbones_pos; // Vector *
void *pEA_linearbones_rot; // RadianEuler *
void *pEA_linearbones_rotscale; // Vector *
void *pEA_linearbones_flags; // int *
void *pEA_linearbones_quat; // Quaternion *
void *pEA_linearbones_qalignment; // Quaternion *
// dst data ea ptrs
void *pEA_pos; // BoneVector *
void *pEA_q; // BoneQuaternion *
void *pEA_addDep_IKRules; // ikcontextikrule_t *
void *pEA_addDep_numIKRules; // int *
void *pEA_flags; // int *
int debugJob; // for dynamic switching of DebuggerBreak
} ALIGN128_POST;
#if !defined(__SPU__)
struct bonejob_PPU
{
public:
matrix3x4_t parentTransform;
float cycle;
int maxBones;
int boneMask;
int bonesMaskNeedsRecalc;
int oldReadableBones;
void *pBaseAnimating; // C_BaseAnimating*
CStudioHdr *pStudioHdr;
matrix3x4a_t *pBoneToWorldOut;
};
struct ALIGN128 PS3BoneJobData
{
public:
job_accumpose::JobDescriptor_t jobDescriptor ALIGN128;
// dst. SPU in/out - could be init'd entirely from SPU, in which case it's out only
BoneVector pos[ MAXSTUDIOBONES_PS3 ] ALIGN16; // 2k
BoneQuaternion q[ MAXSTUDIOBONES_PS3 ] ALIGN16; // 2k
// dst, SPU out only
ikcontextikrule_t addDep_IKRules[ MAX_IKRULES ] ALIGN16; // 4k
int addDep_numIKRules ALIGN16; // [4] to pad to 16B
int pad[3];
// src, SPU in only, going to SPU at start of job
bonejob_SPU bonejobSPU;
// src, PPU only, work data, and data required if job needs to be executed from scratch on PPU if SPU fails
bonejob_PPU bonejobPPU;
} ALIGN128_POST;
class CBoneJobs : public VJobInstance
{
public:
CBoneJobs()
{
}
~CBoneJobs()
{
Shutdown();
}
void Init( void );
void Shutdown( void );
void OnVjobsInit( void ); // gets called after m_pRoot was created and assigned
void OnVjobsShutdown( void ); // gets called before m_pRoot is about to be destructed and NULL'ed
void StartFrame( int maxBoneJobs );
void EndFrame( void );
void ResetBoneJobs( void );
int AddBoneJob( void );
int GetNumBoneJobs( void );
int GetNextFreeSPURSPort( void );
PS3BoneJobData *GetJobData( int job );
private:
CUtlVector<PS3BoneJobData> m_boneJobData;
int m_boneJobCount;
int m_boneJobNextSPURSPort;
bool m_bEnabled;
};
extern CBoneJobs* g_pBoneJobs;
#endif // #if !defined SPU
//-----------------------------------------------------------------------------
//
// Main spu job class
//
//-----------------------------------------------------------------------------
class C_AccumulatePose_SPU
{
public:
C_AccumulatePose_SPU( bonejob_SPU *pBoneJob ) { m_pBoneJob = pBoneJob; };
inline void ResetCount() { m_iCount = 0; };
inline int GetCount() { return m_iCount; };
void AccumulatePose( BoneVector pos[], BoneQuaternion q[] );
void AddLocalLayers( accumposeentry_SPU *pAccPoseEntry, BoneVector pos[], BoneQuaternion q[] );
void AddSequenceLayers( accumposeentry_SPU *pAccPoseEntry, BoneVector pos[], BoneQuaternion q[] );
void SetIKContext( void *pIKContext ) { m_pIKContext = pIKContext; };
void *GetIKContext( void ) { return m_pIKContext; };
private:
bool CalcPoseSingle(
const bonejob_SPU *pBonejob,
accumposeentry_SPU *pPoseEntry,
BoneVector *pos,
BoneQuaternion *q,
int *boneMap,
float *boneWeight,
int sequence,
const float poseParameter[],
int boneMask,
float flTime
);
void *m_pIKContext; // CIKContext *
bonejob_SPU *m_pBoneJob;
// next index into bonejob accumposeentry to execute
int m_iCount;
};
//-----------------------------------------------------------------------------
// Purpose: blends together all the bones from two p:q lists
//
// p1 = p1 * (1 - s) + p2 * s
// q1 = q1 * (1 - s) + q2 * s
//-----------------------------------------------------------------------------
void SlerpBones_SPU(
bonejob_SPU* pSPUJob,
accumposeentry_SPU *pPoseEntry,
BoneQuaternion *q1,
BoneVector *pos1,
const BoneQuaternion *q2,
const BoneVector *pos2,
const int *boneMap,
const float *boneWeight,
float s,
int boneMask );
#if !defined(__SPU__)
class CBoneSetup_PS3;
class IBoneSetup_PS3
{
public:
IBoneSetup_PS3( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], bonejob_SPU *pBoneJobSPU );
~IBoneSetup_PS3( void );
void InitPose_PS3( BoneVector pos[], BoneQuaternion q[] );
void CalcAutoplaySequences_AddPoseCalls( float flRealTime );
void AccumulatePose_AddToBoneJob( bonejob_SPU* pBonejobSPU, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel );
int RunAccumulatePoseJobs_PPU( bonejob_SPU *pBoneJobSPU );
int RunAccumulatePoseJobs_SPU( bonejob_SPU *pBoneJobSPU, job_accumpose::JobDescriptor_t *pJobDescriptor );
CStudioHdr *GetStudioHdr();
void ResetErrorFlags();
int ErrorFlags();
bonejob_SPU *GetBoneJobSPU();
private:
CBoneSetup_PS3 *m_pBoneSetup;
};
#endif
// Given two samples of a bone separated in time by dt,
// compute the velocity and angular velocity of that bone
//void CalcBoneDerivatives( Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &prev, const matrix3x4_t &current, float dt );
// Give a derivative of a bone, compute the velocity & angular velocity of that bone
//void CalcBoneVelocityFromDerivative( const QAngle &vecAngles, Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &current );
// This function sets up the local transform for a single frame of animation. It doesn't handle
// pose parameters or interpolation between frames.
// void SetupSingleBoneMatrix_PS3(
// CStudioHdr_PS3 *pOwnerHdr,
// int nSequence,
// int iFrame,
// int iBone,
// matrix3x4_t &mBoneLocal );
// Purpose: build boneToWorld transforms for a specific bone
void BuildBoneChain_PS3(
const int *pBoneParent,
const matrix3x4a_t &rootxform,
const BoneVector pos[],
const BoneQuaternion q[],
int iBone,
matrix3x4a_t *pBoneToWorld
);
void BuildBoneChain_PS3(
const int *pBoneParent,
const matrix3x4a_t &rootxform,
const BoneVector pos[],
const BoneQuaternion q[],
int iBone,
matrix3x4a_t *pBoneToWorld,
CBoneBitList_PS3 &boneComputed );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
// ik info
class CIKTarget_PS3
{
public:
// void SetOwner( int entindex, const Vector &pos, const QAngle &angles );
// void ClearOwner( void );
// int GetOwner( void );
// void UpdateOwner( int entindex, const Vector &pos, const QAngle &angles );
// void SetPos( const Vector &pos );
// void SetAngles( const QAngle &angles );
// void SetQuaternion( const Quaternion &q );
// void SetNormal( const Vector &normal );
// void SetPosWithNormalOffset( const Vector &pos, const Vector &normal );
// void SetOnWorld( bool bOnWorld = true );
// bool IsActive( void );
// void IKFailed( void );
int chain;
int type;
// void MoveReferenceFrame( Vector &deltaPos, QAngle &deltaAngles );
// accumulated offset from ideal footplant location
public:
struct x2 {
char *pAttachmentName;
Vector pos;
Quaternion q;
} offset;
//private:
struct x3 {
Vector pos;
Quaternion q;
} ideal;
public:
struct x4 {
float latched;
float release;
float height;
float floor;
float radius;
float flTime;
float flWeight;
Vector pos;
Quaternion q;
bool onWorld;
} est; // estimate contact position
struct x5 {
float hipToFoot; // distance from hip
float hipToKnee; // distance from hip to knee
float kneeToFoot; // distance from knee to foot
Vector hip; // location of hip
Vector closest; // closest valid location from hip to foot that the foot can move to
Vector knee; // pre-ik location of knee
Vector farthest; // farthest valid location from hip to foot that the foot can move to
Vector lowest; // lowest position directly below hip that the foot can drop to
} trace;
//private:
// internally latched footset, position
struct x1 {
// matrix3x4a_t worldTarget;
bool bNeedsLatch;
bool bHasLatch;
float influence;
int iFramecounter;
int owner;
Vector absOrigin;
QAngle absAngles;
Vector pos;
Quaternion q;
Vector deltaPos; // accumulated error
Quaternion deltaQ;
Vector debouncePos;
Quaternion debounceQ;
} latched;
struct x6 {
float flTime; // time last error was detected
float flErrorTime;
float ramp;
bool bInError;
} error;
// friend class CIKContext_PS3;
};
struct ikchainresult_t_PS3
{
// accumulated offset from ideal footplant location
int target;
Vector pos;
Quaternion q;
float flWeight;
};
struct ikcontextikrule_t_PS3
{
int index;
int type;
int chain;
int bone;
int slot; // iktarget slot. Usually same as chain.
float height;
float radius;
float floor;
Vector pos;
float pad1;
Quaternion q;
float start; // beginning of influence
float peak; // start of full influence
float tail; // end of full influence
float end; // end of all influence
float top;
float drop;
float commit; // frame footstep target should be committed
float release; // frame ankle should end rotation from latched orientation
float flWeight; // processed version of start-end cycle
float flRuleWeight; // blending weight
float latched; // does the IK rule use a latched value?
char *szLabel;
Vector kneeDir;
float pad2;
Vector kneePos;
float pad3;
ikcontextikrule_t_PS3() {}
private:
// No copy constructors allowed
ikcontextikrule_t_PS3(const ikcontextikrule_t_PS3& vOther);
};
void Studio_AlignIKMatrix_PS3( matrix3x4a_t &mMat, const Vector &vAlignTo );
bool Studio_SolveIK_PS3( int8 iThigh, int8 iKnee, int8 iFoot, Vector &targetFoot, matrix3x4a_t* pBoneToWorld );
bool Studio_SolveIK_PS3( int8 iThigh, int8 iKnee, int8 iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4a_t* pBoneToWorld );
class CIKContext_PS3
{
public:
CIKContext_PS3( );
// void Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const BoneVector &pos, float flTime, int iFramecounter, int boneMask );
void Init( bonejob_SPU *pBonejobSPU, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask );
// void AddDependencies( mstudioseqdesc_t_PS3 &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight = 1.0f );
void ClearTargets( void );
// void UpdateTargets( Vector pos[], Quaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed );
// void AutoIKRelease( void );
void AddAutoplayLocks( bonejob_SPU *pBonejob, BoneVector pos[], BoneQuaternion q[] );
void SolveAutoplayLocks( bonejob_SPU *pBonejob, BoneVector pos[], BoneQuaternion q[] );
// void AddSequenceLocks( mstudioseqdesc_t &SeqDesc, BoneVector pos[], BoneQuaternion q[] );
void AddSequenceLocks( bonejob_SPU *pBonejob, accumposeentry_SPU* pPoseEntry, BoneVector pos[], BoneQuaternion q[] );
void SolveSequenceLocks( bonejob_SPU *pBonejob, accumposeentry_SPU* pPoseEntry, BoneVector pos[], BoneQuaternion q[] );
// void AddAllLocks( BoneVector pos[], BoneQuaternion q[] );
// void SolveAllLocks( BoneVector pos[], BoneQuaternion q[] );
void SolveLock( bonejob_SPU *pBonejob, const mstudioiklock_t_PS3 *plock, int i, BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList_PS3 &boneComputed );
// CUtlVectorFixed< CIKTarget, 12 > m_target;
CIKTarget_PS3 m_target[ 12 ];
int m_targetCount;
int m_numTarget;
private:
// CStudioHdr const *m_pStudioHdr;
//
// bool Estimate( int iSequence, float flCycle, int iTarget, const float poseParameter[], float flWeight = 1.0f );
void BuildBoneChain( const bonejob_SPU *pBonejob, const BoneVector pos[], const BoneQuaternion q[], int iBone, matrix3x4a_t *pBoneToWorld, CBoneBitList_PS3 &boneComputed );
//
// // virtual IK rules, filtered and combined from each sequence
// CUtlVector< CUtlVector< ikcontextikrule_t_PS3 > > m_ikChainRule;
// CUtlVector< ikcontextikrule_t_PS3 > m_ikLock;
ikcontextikrule_t_PS3 m_ikLock[ MAX_IKLOCKS ];
matrix3x4a_t m_rootxform;
int m_iFramecounter;
float m_flTime;
int m_boneMask;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
// replaces the bonetoworld transforms for all bones that are procedural
// bool CalcProceduralBone_PS3(
// const CStudioHdr_PS3 *pStudioHdr,
// int iBone,
// CBoneAccessor_PS3 &bonetoworld
// );
// void Studio_BuildMatrices(
// const CStudioHdr_PS3 *pStudioHdr,
// const QAngle& angles,
// const BoneVector& origin,
// const BoneVector pos[],
// const BoneQuaternion q[],
// int iBone,
// float flScale,
// matrix3x4a_t bonetoworld[MAXSTUDIOBONES],
// int boneMask
// );
// Get a bone->bone relative transform
//void Studio_CalcBoneToBoneTransform( const CStudioHdr *pStudioHdr, int inputBoneIndex, int outputBoneIndex, matrix3x4_t &matrixOut );
// Given a bone rotation value, figures out the value you need to give to the controller
// to have the bone at that value.
// [in] flValue = the desired bone rotation value
// [out] ctlValue = the (0-1) value to set the controller t.
// return value = flValue, unwrapped to lie between the controller's start and end.
//float Studio_SetController( const CStudioHdr *pStudioHdr, int iController, float flValue, float &ctlValue );
// Given a 0-1 controller value, maps it into the controller's start and end and returns the bone rotation angle.
// [in] ctlValue = value in controller space (0-1).
// return value = value in bone space
//float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float ctlValue );
//void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[MAXSTUDIOPOSEPARAM], int nCount );
//float Studio_GetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float ctlValue );
//float Studio_SetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float flValue, float &ctlValue );
// converts a global 0..1 pose parameter into the local sequences blending value
//int Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting );
//void Studio_SeqAnims( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[], mstudioanimdesc_t *panim[4], float *weight );
//int Studio_MaxFrame( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
//float Studio_FPS( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
//float Studio_CPS( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[] );
//float Studio_Duration( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
//void Studio_MovementRate( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
//float Studio_SeqMovementAndDuration( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaPos );
// void Studio_Movement( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
//void Studio_AnimPosition( mstudioanimdesc_t *panim, float flCycle, Vector &vecPos, Vector &vecAngle );
//void Studio_AnimVelocity( mstudioanimdesc_t *panim, float flCycle, Vector &vecVelocity );
//float Studio_FindAnimDistance( mstudioanimdesc_t *panim, float flDist );
// bool Studio_AnimMovement( mstudioanimdesc_t *panim, float flCycleFrom, float flCycleTo, Vector &deltaPos, QAngle &deltaAngle );
// bool Studio_SeqMovement( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaMovement, QAngle &deltaAngle );
// bool Studio_SeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, float flCycle, const float poseParameter[], Vector &vecVelocity );
// float Studio_FindSeqDistance( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flDist );
// float Studio_FindSeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flVelocity );
// int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
// int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
// int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName );
// const char *Studio_GetDefaultSurfaceProps( CStudioHdr *pstudiohdr );
// float Studio_GetMass( CStudioHdr *pstudiohdr );
// const char *Studio_GetKeyValueText( const CStudioHdr *pStudioHdr, int iSequence );
// FORWARD_DECLARE_HANDLE( memhandle_t );
// struct bonecacheparams_t
// {
// CStudioHdr *pStudioHdr;
// matrix3x4a_t *pBoneToWorld;
// float curtime;
// int boneMask;
// };
//
// class CBoneCache
// {
// public:
//
// // you must implement these static functions for the ResourceManager
// // -----------------------------------------------------------
// static CBoneCache *CreateResource( const bonecacheparams_t &params );
// static unsigned int EstimatedSize( const bonecacheparams_t &params );
// // -----------------------------------------------------------
// // member functions that must be present for the ResourceManager
// void DestroyResource();
// CBoneCache *GetData() { return this; }
// unsigned int Size() { return m_size; }
// // -----------------------------------------------------------
//
// CBoneCache();
//
// // was constructor, but placement new is messy wrt memdebug - so cast & init instead
// void Init( const bonecacheparams_t &params, unsigned int size, short *pStudioToCached, short *pCachedToStudio, int cachedBoneCount );
//
// void UpdateBones( const matrix3x4a_t *pBoneToWorld, int numbones, float curtime );
// matrix3x4a_t *GetCachedBone( int studioIndex );
// void ReadCachedBones( matrix3x4a_t *pBoneToWorld );
// void ReadCachedBonePointers( matrix3x4_t **bones, int numbones );
//
// bool IsValid( float curtime, float dt = 0.1f );
//
// public:
// float m_timeValid;
// int m_boneMask;
//
// private:
// matrix3x4a_t *BoneArray();
// short *StudioToCached();
// short *CachedToStudio();
//
// unsigned int m_size;
// unsigned short m_cachedBoneCount;
// unsigned short m_matrixOffset;
// unsigned short m_cachedToStudioOffset;
// unsigned short m_boneOutOffset;
// };
//
// void Studio_LockBoneCache();
// void Studio_UnlockBoneCache();
//
// CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle, bool bLock = false );
// void Studio_ReleaseBoneCache( memhandle_t cacheHandle );
// memhandle_t Studio_CreateBoneCache( bonecacheparams_t &params );
// void Studio_DestroyBoneCache( memhandle_t cacheHandle );
// void Studio_InvalidateBoneCacheIfNotMatching( memhandle_t cacheHandle, float flTimeValid );
// Given a ray, trace for an intersection with this studiomodel. Get the array of bones from StudioSetupHitboxBones
// bool TraceToStudio( class IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, matrix3x4_t **hitboxbones, int fContentsMask, const Vector &vecOrigin, float flScale, trace_t &trace );
// TERROR: TraceToStudio variant that prioritizes hitgroups, so bullets can pass through arms and chest to hit the head, for instance
// bool TraceToStudioGrouped( IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set,
// matrix3x4_t **hitboxbones, int fContentsMask, trace_t &tr, const CUtlVector< int > &sortedHitgroups );
void QuaternionSM_PS3( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt );
void QuaternionMA_PS3( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt );
//
// bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence );
//
// void Studio_RunBoneFlexDrivers( float *pFlexController, const CStudioHdr *pStudioHdr, const Vector *pPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld );
//-----------------------------------------------------------------------------
// Computes a number of twist bones given a parent/child pair
// pqTwists, pflWeights, pqTwistBinds must all have at least nCount elements
//-----------------------------------------------------------------------------
// void ComputeTwistBones(
// Quaternion *pqTwists,
// int nCount,
// bool bInverse,
// const Vector &vUp,
// const Quaternion &qParent,
// const matrix3x4_t &mChild,
// const Quaternion &qBaseInv,
// const float *pflWeights,
// const Quaternion *pqTwistBinds );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// round up to next 16B boundary, then add 16B
#define ROUNDUPTONEXT16B( a ) (0x10 + (a + (0x10 - (a%0x10))))
//-----------------------------------------------------------------------------
// Squeezing memory for SPU - manual float and int allocs
//-----------------------------------------------------------------------------
#define LS_FLOATSTACK_SIZE ((MAXSTUDIOBONES_PS3 + 32) * 4 * 3 * 3) // 24k
#define LS_INTSTACK_SIZE ((MAXSTUDIOBONES_PS3 * 2) + 16) // 1k
extern ALIGN16 byte g_ls_Stack[ (LS_FLOATSTACK_SIZE * sizeof(float)) + (LS_INTSTACK_SIZE * sizeof(int)) ];
extern byte *g_ls_StackPtr;
extern byte *g_ls_StackPtr_MAX;
// init when starting Job
FORCEINLINE void InitLSStack()
{
g_ls_StackPtr = g_ls_Stack;
}
// term when exiting Job
FORCEINLINE void TermLSStack()
{
#if !defined( _CERT )
// ensure pop'd to start
if( g_ls_StackPtr != g_ls_Stack )
{
Msg("*** IMPROPER LS STACK ON TERM ***\n");
Msg("*** IMPROPER LS STACK ON TERM ***\n");
Msg("*** IMPROPER LS STACK ON TERM ***\n");
Msg("*** IMPROPER LS STACK ON TERM ***\n");
DebuggerBreak();
}
#endif
// float watermark
// Msg("LS stack - high: %d, max: %d\n", (int)(g_ls_StackPtr_MAX - g_ls_Stack), (int)sizeof(g_ls_Stack) );
}
// keep it simple, ensure allocation is multiple of 16B to keep vectors aligned
// size is number of bytes
FORCEINLINE byte *PushLSStack( int size )
{
byte *pStack = g_ls_StackPtr;
g_ls_StackPtr += ROUNDUPTONEXT16B( size );
#if !defined( _CERT )
if( g_ls_StackPtr > (g_ls_Stack + sizeof(g_ls_Stack)) )
{
Msg("*** EXCEEDED LS STACK ***\n");
Msg("*** EXCEEDED LS STACK ***\n");
Msg("*** EXCEEDED LS STACK ***\n");
Msg("*** EXCEEDED LS STACK ***\n");
DebuggerBreak();
}
#endif
// maintain watermark
if( g_ls_StackPtr > g_ls_StackPtr_MAX )
{
g_ls_StackPtr_MAX = g_ls_StackPtr;
}
return pStack;
}
FORCEINLINE void PopLSStack( int size )
{
g_ls_StackPtr -= ROUNDUPTONEXT16B( size );
#if !defined( _CERT )
if( g_ls_StackPtr < g_ls_Stack )
{
Msg("*** EXCEEDED LS STACK - POP ***\n");
Msg("*** EXCEEDED LS STACK - POP ***\n");
Msg("*** EXCEEDED LS STACK - POP ***\n");
Msg("*** EXCEEDED LS STACK - POP ***\n");
DebuggerBreak();
}
#endif
}
// class CLSStack
// {
// public:
// CLSStack( int size )
// {
// ;
// }
// ~CLSStack()
// {
// ;
// }
// };
//
// #define LSSTACK(size) CLSStack
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
#if defined(__SPU__)
extern BoneVector *g_posInit;
extern BoneQuaternion *g_qInit;
extern ikcontextikrule_t_PS3 *g_addDep_IKRules;
extern int g_addDep_numIKRules;
#else
extern BoneVector g_posInit[ MAXSTUDIOBONES_PS3 ];
extern BoneQuaternion g_qInit[ MAXSTUDIOBONES_PS3 ];
extern ikcontextikrule_t_PS3 g_addDep_IKRules[ MAX_IKRULES ] ALIGN16;
extern int g_addDep_numIKRules;
#endif
#endif // _PS3
#endif // BONE_SETUP_H

View File

@@ -0,0 +1,48 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Macros for defining branching singletons.
//
// A branching singleton defines a singleton class within another class, and subclasses
// of the outer class can automatically expand on that singleton at their node in the
// class branching tree with the confidence that changes will be reflected in all
// subclasses.
//
// The primary reason to have a branching singleton is to centralize management code
// without being tied explicitly to one interface. The interface can possibly change
// vastly as it gets passed down the tree to the point where all the original functions
// are stubs and the interface uses an entirely different set of functions.
//
// $NoKeywords: $
//=============================================================================//
#ifndef BRANCHINGSINGLETON_H
#define BRANCHINGSINGLETON_H
#ifdef _WIN32
#pragma once
#endif
#define START_BRANCHING_SINGLETON_DEFINITION_NOBASE( classname ) class classname
#define START_BRANCHING_SINGLETON_DEFINITION( classname ) class classname : public Base##classname
#define _END_BRANCHING_SINGLETON_DEFINITION( classname );\
static classname *Get_##classname##_Static( void )\
{\
static classname s_Singleton;\
return &s_Singleton;\
}\
\
virtual Root##classname *Get_##classname##( void )\
{\
return Get_##classname##_Static();\
}\
typedef classname Base##classname;
#define END_BRANCHING_SINGLETON_DEFINITION( classname ) _END_BRANCHING_SINGLETON_DEFINITION( classname )
#define END_BRANCHING_SINGLETON_DEFINITION_NOBASE( classname );\
typedef classname Root##classname;\
_END_BRANCHING_SINGLETON_DEFINITION( classname );
#endif //#ifndef BRANCHINGSINGLETON_H

1305
public/bspfile.h Normal file

File diff suppressed because it is too large Load Diff

156
public/bspflags.h Normal file
View File

@@ -0,0 +1,156 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef BSPFLAGS_H
#define BSPFLAGS_H
#ifdef _WIN32
#pragma once
#endif
// contents flags are seperate bits
// a given brush can contribute multiple content bits
// multiple brushes can be in a single leaf
// these definitions also need to be in q_shared.h!
// lower bits are stronger, and will eat weaker brushes completely
#define CONTENTS_EMPTY 0 // No contents
#define CONTENTS_SOLID 0x1 // an eye is never valid in a solid
#define CONTENTS_WINDOW 0x2 // translucent, but not watery (glass)
#define CONTENTS_AUX 0x4
#define CONTENTS_GRATE 0x8 // alpha-tested "grate" textures. Bullets/sight pass through, but solids don't
#define CONTENTS_SLIME 0x10
#define CONTENTS_WATER 0x20
#define CONTENTS_BLOCKLOS 0x40 // block AI line of sight
#define CONTENTS_OPAQUE 0x80 // things that cannot be seen through (may be non-solid though)
#define LAST_VISIBLE_CONTENTS CONTENTS_OPAQUE
#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1))
#define CONTENTS_TESTFOGVOLUME 0x100
#define CONTENTS_UNUSED 0x200
// unused
// NOTE: If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS
// if not visible, then grab from the bottom.
// CONTENTS_OPAQUE + SURF_NODRAW count as CONTENTS_OPAQUE (shadow-casting toolsblocklight textures)
#define CONTENTS_BLOCKLIGHT 0x400
#define CONTENTS_TEAM1 0x800 // per team contents used to differentiate collisions
#define CONTENTS_TEAM2 0x1000 // between players and objects on different teams
// ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW
#define CONTENTS_IGNORE_NODRAW_OPAQUE 0x2000
// hits entities which are MOVETYPE_PUSH (doors, plats, etc.)
#define CONTENTS_MOVEABLE 0x4000
// remaining contents are non-visible, and don't eat brushes
#define CONTENTS_AREAPORTAL 0x8000
#define CONTENTS_PLAYERCLIP 0x10000
#define CONTENTS_MONSTERCLIP 0x20000
#define CONTENTS_BRUSH_PAINT 0x40000
#define CONTENTS_GRENADECLIP 0x80000
#define CONTENTS_UNUSED2 0x100000
#define CONTENTS_UNUSED3 0x200000
#define CONTENTS_UNUSED4 0x400000
#define CONTENTS_UNUSED5 0x800000
#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity
#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game
#define CONTENTS_DEBRIS 0x4000000
#define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs
#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
#define CONTENTS_LADDER 0x20000000
#define CONTENTS_HITBOX 0x40000000 // use accurate hitboxes on trace
// NOTE: These are stored in a short in the engine now. Don't use more than 16 bits
#define SURF_LIGHT 0x0001 // value will hold the light strength
#define SURF_SKY2D 0x0002 // don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox
#define SURF_SKY 0x0004 // don't draw, but add to skybox
#define SURF_WARP 0x0008 // turbulent water warp
#define SURF_TRANS 0x0010
#define SURF_NOPORTAL 0x0020 // the surface can not have a portal placed on it
#define SURF_TRIGGER 0x0040 // FIXME: This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders
#define SURF_NODRAW 0x0080 // don't bother referencing the texture
#define SURF_HINT 0x0100 // make a primary bsp splitter
#define SURF_SKIP 0x0200 // completely ignore, allowing non-closed brushes
#define SURF_NOLIGHT 0x0400 // Don't calculate light
#define SURF_BUMPLIGHT 0x0800 // calculate three lightmaps for the surface for bumpmapping
#define SURF_NOSHADOWS 0x1000 // Don't receive shadows
#define SURF_NODECALS 0x2000 // Don't receive decals
#define SURF_NOPAINT SURF_NODECALS // the surface can not have paint placed on it
#define SURF_NOCHOP 0x4000 // Don't subdivide patches on this surface
#define SURF_HITBOX 0x8000 // surface is part of a hitbox
// -----------------------------------------------------
// spatial content masks - used for spatial queries (traceline,etc.)
// -----------------------------------------------------
#define MASK_ALL (0xFFFFFFFF)
// everything that is normally solid
#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// everything that blocks player movement
#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// blocks npc movement
#define MASK_NPCSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// blocks fluid movement
#define MASK_NPCFLUID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER)
// water physics in these contents
#define MASK_WATER (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME)
// everything that blocks lighting
#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE)
// everything that blocks lighting, but with monsters added.
#define MASK_OPAQUE_AND_NPCS (MASK_OPAQUE|CONTENTS_MONSTER)
// everything that blocks line of sight for AI
#define MASK_BLOCKLOS (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_BLOCKLOS)
// everything that blocks line of sight for AI plus NPCs
#define MASK_BLOCKLOS_AND_NPCS (MASK_BLOCKLOS|CONTENTS_MONSTER)
// everything that blocks line of sight for players
#define MASK_VISIBLE (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE)
// everything that blocks line of sight for players, but with monsters added.
#define MASK_VISIBLE_AND_NPCS (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE)
// bullets see these as solid
#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX)
// for finding floor height
#define MASK_FLOORTRACE (CONTENTS_SOLID|CONTENTS_MOVEABLE| CONTENTS_WINDOW|CONTENTS_DEBRIS)
// for csgo weapon clipping
#define MASK_WEAPONCLIPPING (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS)
// bullets see these as solid, except monsters (world+brush only)
#define MASK_SHOT_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_DEBRIS)
// non-raycasted weapons see this as solid (includes grates)
#define MASK_SHOT_HULL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE)
// hits solids (not grates) and passes through everything else
#define MASK_SHOT_PORTAL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER)
// everything normally solid, except monsters (world+brush only)
#define MASK_SOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE)
// everything normally solid for player movement, except monsters (world+brush only)
#define MASK_PLAYERSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE)
// everything normally solid for npc movement, except monsters (world+brush only)
#define MASK_NPCSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)
// just the world, used for route rebuilding
#define MASK_NPCWORLDSTATIC (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)
// just the world, used for route rebuilding
#define MASK_NPCWORLDSTATIC_FLUID (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP)
// These are things that can split areaportals
#define MASK_SPLITAREAPORTAL (CONTENTS_WATER|CONTENTS_SLIME)
// everything that blocks corpse movement
// UNDONE: Not used yet / may be deleted
#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_GRATE)
#endif // BSPFLAGS_H

352
public/bsptreedata.cpp Normal file
View File

@@ -0,0 +1,352 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Revision: $
// $NoKeywords: $
//
// The BSP tree leaf data system
//
//=============================================================================//
#include "basetypes.h"
#include "bsptreedata.h"
#include "utllinkedlist.h"
#include "utlvector.h"
#include "tier0/dbg.h"
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// The BSP tree leaf data system
//-----------------------------------------------------------------------------
class CBSPTreeData : public IBSPTreeData, public ISpatialLeafEnumerator
{
public:
// constructor, destructor
CBSPTreeData();
virtual ~CBSPTreeData();
// Methods of IBSPTreeData
void Init( ISpatialQuery* pBSPTree );
void Shutdown();
BSPTreeDataHandle_t Insert( int userId, Vector const& mins, Vector const& maxs );
void Remove( BSPTreeDataHandle_t handle );
void ElementMoved( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs );
// Enumerate elements in a particular leaf
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, 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, intp context );
// Is the element in any leaves at all?
bool IsElementInTree( BSPTreeDataHandle_t handle ) const;
private:
// Creates a new handle
BSPTreeDataHandle_t NewHandle( int userId );
// Adds a handle to the list of handles
void AddHandleToLeaf( int leaf, BSPTreeDataHandle_t handle );
// insert, remove handles from leaves
void InsertIntoTree( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs );
void RemoveFromTree( BSPTreeDataHandle_t handle );
// Returns the number of elements in a leaf
int CountElementsInLeaf( int leaf );
private:
// All the information associated with a particular handle
struct HandleInfo_t
{
int m_UserId; // Client-defined id
unsigned short m_LeafList; // What leafs is it in?
};
// The leaf contains an index into a list of elements
struct Leaf_t
{
unsigned short m_FirstElement;
};
// The handle knows about the leaves it lies in
struct HandleInLeaf_t
{
int m_Leaf; // what leaf is the handle in?
unsigned short m_LeafElementIndex; // what's the m_LeafElements index of the entry?
};
// Stores data associated with each leaf.
CUtlVector< Leaf_t > m_Leaf;
// Stores all unique handles
CUtlLinkedList< HandleInfo_t, unsigned short > m_Handles;
// Maintains the list of all handles in a particular leaf
CUtlLinkedList< BSPTreeDataHandle_t, unsigned short, true > m_LeafElements;
// Maintains the list of all leaves a particular handle spans
CUtlLinkedList< HandleInLeaf_t, unsigned short, true > m_HandleLeafList;
// Interface to BSP tree
ISpatialQuery* m_pBSPTree;
};
//-----------------------------------------------------------------------------
// Class factory
//-----------------------------------------------------------------------------
IBSPTreeData* CreateBSPTreeData()
{
return new CBSPTreeData;
}
void DestroyBSPTreeData( IBSPTreeData* pTreeData )
{
if (pTreeData)
delete pTreeData;
}
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
CBSPTreeData::CBSPTreeData()
{
}
CBSPTreeData::~CBSPTreeData()
{
}
//-----------------------------------------------------------------------------
// Level init, shutdown
//-----------------------------------------------------------------------------
void CBSPTreeData::Init( ISpatialQuery* pBSPTree )
{
Assert( pBSPTree );
m_pBSPTree = pBSPTree;
m_Handles.EnsureCapacity( 1024 );
m_LeafElements.EnsureCapacity( 1024 );
m_HandleLeafList.EnsureCapacity( 1024 );
// Add all the leaves we'll need
int leafCount = m_pBSPTree->LeafCount();
m_Leaf.EnsureCapacity( leafCount );
Leaf_t newLeaf;
newLeaf.m_FirstElement = m_LeafElements.InvalidIndex();
while ( --leafCount >= 0 )
{
m_Leaf.AddToTail( newLeaf );
}
}
void CBSPTreeData::Shutdown()
{
m_Handles.Purge();
m_LeafElements.Purge();
m_HandleLeafList.Purge();
m_Leaf.Purge();
}
//-----------------------------------------------------------------------------
// Creates a new handle
//-----------------------------------------------------------------------------
BSPTreeDataHandle_t CBSPTreeData::NewHandle( int userId )
{
BSPTreeDataHandle_t handle = m_Handles.AddToTail();
m_Handles[handle].m_UserId = userId;
m_Handles[handle].m_LeafList = m_HandleLeafList.InvalidIndex();
return handle;
}
//-----------------------------------------------------------------------------
// Add/remove handle
//-----------------------------------------------------------------------------
BSPTreeDataHandle_t CBSPTreeData::Insert( int userId, Vector const& mins, Vector const& maxs )
{
BSPTreeDataHandle_t handle = NewHandle( userId );
InsertIntoTree( handle, mins, maxs );
return handle;
}
void CBSPTreeData::Remove( BSPTreeDataHandle_t handle )
{
if (!m_Handles.IsValidIndex(handle))
return;
RemoveFromTree( handle );
m_Handles.Free( handle );
}
//-----------------------------------------------------------------------------
// Adds a handle to a leaf
//-----------------------------------------------------------------------------
void CBSPTreeData::AddHandleToLeaf( int leaf, BSPTreeDataHandle_t handle )
{
// Got to a leaf baby! Add the handle to the leaf's list of elements
unsigned short leafElement = m_LeafElements.Alloc( true );
if (m_Leaf[leaf].m_FirstElement != m_LeafElements.InvalidIndex() )
m_LeafElements.LinkBefore( m_Leaf[leaf].m_FirstElement, leafElement );
m_Leaf[leaf].m_FirstElement = leafElement;
m_LeafElements[leafElement] = handle;
// Insert the leaf into the handles's list of leaves
unsigned short handleElement = m_HandleLeafList.Alloc( true );
if (m_Handles[handle].m_LeafList != m_HandleLeafList.InvalidIndex() )
m_HandleLeafList.LinkBefore( m_Handles[handle].m_LeafList, handleElement );
m_Handles[handle].m_LeafList = handleElement;
m_HandleLeafList[handleElement].m_Leaf = leaf;
m_HandleLeafList[handleElement].m_LeafElementIndex = leafElement;
}
//-----------------------------------------------------------------------------
// Inserts an element into the tree
//-----------------------------------------------------------------------------
bool CBSPTreeData::EnumerateLeaf( int leaf, intp context )
{
BSPTreeDataHandle_t handle = (BSPTreeDataHandle_t)context;
AddHandleToLeaf( leaf, handle );
return true;
}
void CBSPTreeData::InsertIntoTree( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs )
{
m_pBSPTree->EnumerateLeavesInBox( mins, maxs, this, handle );
}
//-----------------------------------------------------------------------------
// Removes an element from the tree
//-----------------------------------------------------------------------------
void CBSPTreeData::RemoveFromTree( BSPTreeDataHandle_t handle )
{
// Iterate over the list of all leaves the handle is in
unsigned short i = m_Handles[handle].m_LeafList;
while (i != m_HandleLeafList.InvalidIndex())
{
int leaf = m_HandleLeafList[i].m_Leaf;
unsigned short leafElement = m_HandleLeafList[i].m_LeafElementIndex;
// Unhook the handle from the leaf handle list
if (leafElement == m_Leaf[leaf].m_FirstElement)
m_Leaf[leaf].m_FirstElement = m_LeafElements.Next(leafElement);
m_LeafElements.Free(leafElement);
unsigned short prevNode = i;
i = m_HandleLeafList.Next(i);
m_HandleLeafList.Free(prevNode);
}
m_Handles[handle].m_LeafList = m_HandleLeafList.InvalidIndex();
}
//-----------------------------------------------------------------------------
// Call this when the element moves
//-----------------------------------------------------------------------------
void CBSPTreeData::ElementMoved( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs )
{
if (handle != TREEDATA_INVALID_HANDLE)
{
RemoveFromTree( handle );
InsertIntoTree( handle, mins, maxs );
}
}
//-----------------------------------------------------------------------------
// Is the element in any leaves at all?
//-----------------------------------------------------------------------------
bool CBSPTreeData::IsElementInTree( BSPTreeDataHandle_t handle ) const
{
return m_Handles[handle].m_LeafList != m_HandleLeafList.InvalidIndex();
}
//-----------------------------------------------------------------------------
// Enumerate elements in a particular leaf
//-----------------------------------------------------------------------------
int CBSPTreeData::CountElementsInLeaf( int leaf )
{
int i;
int nCount = 0;
for( i = m_Leaf[leaf].m_FirstElement; i != m_LeafElements.InvalidIndex(); i = m_LeafElements.Next(i) )
{
++nCount;
}
return nCount;
}
//-----------------------------------------------------------------------------
// Enumerate elements in a particular leaf
//-----------------------------------------------------------------------------
bool CBSPTreeData::EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, intp context )
{
#ifdef DBGFLAG_ASSERT
// The enumeration method better damn well not change this list...
int nCount = CountElementsInLeaf(leaf);
#endif
unsigned short idx = m_Leaf[leaf].m_FirstElement;
while (idx != m_LeafElements.InvalidIndex())
{
BSPTreeDataHandle_t handle = m_LeafElements[idx];
if (!pEnum->EnumerateElement( m_Handles[handle].m_UserId, context ))
{
Assert( CountElementsInLeaf(leaf) == nCount );
return false;
}
idx = m_LeafElements.Next(idx);
}
Assert( CountElementsInLeaf(leaf) == nCount );
return true;
}
//-----------------------------------------------------------------------------
// For convenience, enumerates the leaves along a ray, box, etc.
//-----------------------------------------------------------------------------
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, intp context )
{
return m_pBSPTree->EnumerateLeavesInBox( mins, maxs, pEnum, 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, intp context )
{
return m_pBSPTree->EnumerateLeavesAlongRay( ray, pEnum, context );
}

145
public/bsptreedata.h Normal file
View File

@@ -0,0 +1,145 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Revision: $
// $NoKeywords: $
//
// The BSP tree leaf data system
//
//=============================================================================//
#include "tier0/platform.h"
#if !defined( BSPTREEDATA )
#define BSPTREEDATA
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class Vector;
struct Ray_t;
//-----------------------------------------------------------------------------
// Handle to an renderable in the client leaf system
//-----------------------------------------------------------------------------
typedef unsigned short BSPTreeDataHandle_t;
enum
{
TREEDATA_INVALID_HANDLE = (BSPTreeDataHandle_t)~0
};
//-----------------------------------------------------------------------------
// Interface needed by tree data to do its job
//
// Note that anything that has convex spatial regions with leaves identified
// by indices can implement the ISpatialQuery. All you have to do is to implement
// a class that can answer the 5 questions in the Query interface about the
// spatial subdivision. For example, a K-D tree or a BSP tree could implement
// this interface
//
//-----------------------------------------------------------------------------
abstract_class ISpatialLeafEnumerator
{
public:
// call back with a leaf and a context
// The context is completely user defined; it's passed into the enumeration
// function of ISpatialQuery.
// This gets called by the enumeration methods with each leaf
// that passes the test; return true to continue enumerating,
// false to stop
virtual bool EnumerateLeaf( int leaf, intp context ) = 0;
};
abstract_class ISpatialQuery
{
public:
// Returns the number of leaves
virtual int LeafCount() const = 0;
// Enumerates the leaves along a ray, box, etc.
virtual bool EnumerateLeavesAtPoint( const Vector& pt, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
virtual bool EnumerateLeavesInBox( const Vector& mins, const Vector& maxs, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
virtual bool EnumerateLeavesInSphere( const Vector& center, float radius, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
virtual bool EnumerateLeavesInSphereWithFlagSet( const Vector& center, float radius, ISpatialLeafEnumerator* pEnum, intp context, int nFlagsCheck ) = 0;
virtual int ListLeavesInBox( const Vector& mins, const Vector& maxs, unsigned short *pList, int listMax ) = 0;
// Used to determine which leaves passed in (specified by leafcount, pLeafs, and nLeafStride )
// are within radius flRadius of vecCenter and have the flag set.
// The result is placed in the pLeafsInSphere array, which specifies _indices_ into the original pLeafs array
// The number of leaves found within the sphere is the return value.
// The caller is expected to have allocated at least nLeafCount pLeafsInSphere to place the results into
virtual int ListLeavesInSphereWithFlagSet( int *pLeafsInSphere, const Vector& vecCenter, float flRadius, int nLeafCount, const uint16 *pLeafs, int nLeafStride = sizeof(uint16), int nFlagsCheck = 0xFFFFFFFF ) = 0;
};
//-----------------------------------------------------------------------------
// Data associated with leaves.
//
// This is a parasitic class that attaches data to the leaves specified by the
// ISpatialQuery sent in to the initialization function. It can't exist without
// a spatial partition of some sort to hold onto.
//-----------------------------------------------------------------------------
abstract_class IBSPTreeDataEnumerator
{
public:
// call back with a userId and a context
virtual bool FASTCALL EnumerateElement( int userId, intp context ) = 0;
};
abstract_class IBSPTreeData
{
public:
// Add a virtual destructor so that the derived class destructors will
// be called.
virtual ~IBSPTreeData() {}
// Initializes, shuts down
virtual void Init( ISpatialQuery* pBSPTree ) = 0;
virtual void Shutdown() = 0;
// Adds and removes data from the leaf lists
virtual BSPTreeDataHandle_t Insert( int userId, const Vector& mins, const Vector& maxs ) = 0;
virtual void Remove( BSPTreeDataHandle_t handle ) = 0;
// Call this when a element moves
virtual void ElementMoved( BSPTreeDataHandle_t handle, const Vector& mins, const Vector& maxs ) = 0;
// Enumerate elements in a particular leaf
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;
// 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( const Vector& pt, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
virtual bool EnumerateLeavesInBox( const Vector& mins, const Vector& maxs, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
virtual bool EnumerateLeavesInSphere( const Vector& center, float radius, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context ) = 0;
};
//-----------------------------------------------------------------------------
// Class factory
//-----------------------------------------------------------------------------
IBSPTreeData* CreateBSPTreeData();
void DestroyBSPTreeData( IBSPTreeData* pTreeData );
#endif // BSPTREEDATA

3156
public/builddisp.cpp Normal file

File diff suppressed because it is too large Load Diff

1559
public/builddisp.h Normal file

File diff suppressed because it is too large Load Diff

77
public/captioncompiler.h Normal file
View File

@@ -0,0 +1,77 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef CAPTIONCOMPILER_H
#define CAPTIONCOMPILER_H
#ifdef _WIN32
#pragma once
#endif
#include "datamap.h"
#include "checksum_crc.h"
#define MAX_BLOCK_BITS 13
#define MAX_BLOCK_SIZE (1<<MAX_BLOCK_BITS )
#define COMPILED_CAPTION_FILEID MAKEID( 'V', 'C', 'C', 'D' )
#define COMPILED_CAPTION_VERSION 1
#pragma pack(1)
struct CompiledCaptionHeader_t
{
DECLARE_BYTESWAP_DATADESC()
int magic;
int version;
int numblocks;
int blocksize;
int directorysize;
int dataoffset;
};
struct CaptionLookup_t
{
DECLARE_BYTESWAP_DATADESC()
unsigned int hash;
int blockNum;
unsigned short offset;
unsigned short length;
void SetHash( char const *string )
{
int len = Q_strlen( string );
char *tempstr = (char *)stackalloc( len + 1 );
Q_strncpy( tempstr, string, len + 1 );
Q_strlower( tempstr );
CRC32_t temp;
CRC32_Init( &temp );
CRC32_ProcessBuffer( &temp, tempstr, len );
CRC32_Final( &temp );
hash = ( unsigned int )temp;
}
};
#pragma pack()
class CCaptionLookupLess
{
public:
bool Less( const CaptionLookup_t& lhs, const CaptionLookup_t& rhs, void *pContext )
{
return lhs.hash < rhs.hash;
}
};
struct CaptionBlock_t
{
byte data[ MAX_BLOCK_SIZE ];
};
// For swapping compiled caption files
bool SwapClosecaptionFile( void *pData );
int UpdateOrCreateCaptionFile( const char *pSourceName, char *pTargetName, int targetLen, bool bForce = false );
#endif // CAPTIONCOMPILER_H

1194
public/cdll_int.h Normal file

File diff suppressed because it is too large Load Diff

985
public/chunkfile.cpp Normal file
View File

@@ -0,0 +1,985 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Implements an interface for reading and writing heirarchical
// text files of key value pairs. The format of the file is as follows:
//
// chunkname0
// {
// "key0" "value0"
// "key1" "value1"
// ...
// "keyN" "valueN"
// chunkname1
// {
// "key0" "value0"
// "key1" "value1"
// ...
// "keyN" "valueN"
// }
// }
// ...
// chunknameN
// {
// "key0" "value0"
// "key1" "value1"
// ...
// "keyN" "valueN"
// }
//
// The chunk names are not necessarily unique, nor are the key names, unless the
// parsing application requires them to be.
//
// $NoKeywords: $
//=============================================================================//
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <math.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "chunkfile.h"
#include "mathlib/vector.h"
#include "mathlib/vector4d.h"
#include "tier1/strtools.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Constructor.
//-----------------------------------------------------------------------------
CChunkHandlerMap::CChunkHandlerMap(void)
{
m_pHandlers = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor. Frees handler list.
//-----------------------------------------------------------------------------
CChunkHandlerMap::~CChunkHandlerMap(void)
{
ChunkHandlerInfoNode_t *pNode = m_pHandlers;
while (pNode != NULL)
{
ChunkHandlerInfoNode_t *pPrev = pNode;
pNode = pNode->pNext;
delete pPrev;
}
}
//-----------------------------------------------------------------------------
// Purpose: Adds a chunk handler to the handler list.
// Input : pszChunkName - Name of chunk to be handled.
// pfnHandler - Address of handler callback function.
// pData - Data to pass to the handler callback.
//-----------------------------------------------------------------------------
void CChunkHandlerMap::AddHandler(const char *pszChunkName, ChunkHandler_t pfnHandler, void *pData)
{
ChunkHandlerInfoNode_t *pNew = new ChunkHandlerInfoNode_t;
Q_strncpy(pNew->Handler.szChunkName, pszChunkName, sizeof( pNew->Handler.szChunkName ));
pNew->Handler.pfnHandler = pfnHandler;
pNew->Handler.pData = pData;
pNew->pNext = NULL;
if (m_pHandlers == NULL)
{
m_pHandlers = pNew;
}
else
{
ChunkHandlerInfoNode_t *pNode = m_pHandlers;
while (pNode->pNext != NULL)
{
pNode = pNode->pNext;
}
pNode->pNext = pNew;
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets the callback for error handling within this chunk's scope.
// Input : pfnHandler -
// pData -
//-----------------------------------------------------------------------------
void CChunkHandlerMap::SetErrorHandler(ChunkErrorHandler_t pfnHandler, void *pData)
{
m_pfnErrorHandler = pfnHandler;
m_pErrorData = pData;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : ppData -
// Output : ChunkErrorHandler_t
//-----------------------------------------------------------------------------
ChunkErrorHandler_t CChunkHandlerMap::GetErrorHandler(void **ppData)
{
*ppData = m_pErrorData;
return(m_pfnErrorHandler);
}
//-----------------------------------------------------------------------------
// Purpose: Gets the handler for a given chunk name, if one has been set.
// Input : pszChunkName - Name of chunk.
// ppfnHandler - Receives the address of the callback function.
// ppData - Receives the context data for the given chunk.
// Output : Returns true if a handler was found, false if not.
//-----------------------------------------------------------------------------
ChunkHandler_t CChunkHandlerMap::GetHandler(const char *pszChunkName, void **ppData)
{
ChunkHandlerInfoNode_t *pNode = m_pHandlers;
while (pNode != NULL)
{
if (!stricmp(pNode->Handler.szChunkName, pszChunkName))
{
*ppData = pNode->Handler.pData;
return(pNode->Handler.pfnHandler);
}
pNode = pNode->pNext;
}
return(0);
}
//-----------------------------------------------------------------------------
// Purpose: Constructor. Initializes data members.
//-----------------------------------------------------------------------------
CChunkFile::CChunkFile(void)
{
m_hFile = NULL;
m_nCurrentDepth = 0;
m_szIndent[0] = '\0';
m_nHandlerStackDepth = 0;
m_DefaultChunkHandler = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor. Closes the file if it is currently open.
//-----------------------------------------------------------------------------
CChunkFile::~CChunkFile(void)
{
if (m_hFile != NULL)
{
fclose(m_hFile);
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pszChunkName -
// Output : ChunkFileResult_t
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::BeginChunk(const char *pszChunkName)
{
//
// Write the chunk name and open curly.
//
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "%s\r\n%s{", pszChunkName, m_szIndent);
ChunkFileResult_t eResult = WriteLine(szBuf);
//
// Update the indentation depth.
//
if (eResult == ChunkFile_Ok)
{
m_nCurrentDepth++;
BuildIndentString(m_szIndent, m_nCurrentDepth);
}
return(eResult);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CChunkFile::BuildIndentString(char *pszDest, int nDepth)
{
if (nDepth >= 0)
{
for (int i = 0; i < nDepth; i++)
{
pszDest[i] = '\t';
}
pszDest[nDepth] = '\0';
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : ChunkFileResult_t
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::Close(void)
{
if (m_hFile != NULL)
{
fclose(m_hFile);
m_hFile = NULL;
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : ChunkFileResult_t
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::EndChunk(void)
{
if (m_nCurrentDepth > 0)
{
m_nCurrentDepth--;
BuildIndentString(m_szIndent, m_nCurrentDepth);
}
WriteLine("}");
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose: Returns a string explaining the last error that occurred.
//-----------------------------------------------------------------------------
const char *CChunkFile::GetErrorText(ChunkFileResult_t eResult)
{
static char szError[MAX_KEYVALUE_LEN];
switch (eResult)
{
case ChunkFile_UnexpectedEOF:
{
Q_strncpy(szError, "unexpected end of file", sizeof( szError ) );
break;
}
case ChunkFile_UnexpectedSymbol:
{
Q_snprintf(szError, sizeof( szError ), "unexpected symbol '%s'", m_szErrorToken);
break;
}
case ChunkFile_OpenFail:
{
Q_snprintf(szError, sizeof( szError ), "%s", strerror(errno)) ;
break;
}
case ChunkFile_StringTooLong:
{
Q_strncpy(szError, "unterminated string or string too long", sizeof( szError ) );
break;
}
default:
{
Q_snprintf(szError, sizeof( szError ), "error %d", eResult);
}
}
return(m_TokenReader.Error(szError));
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : eError -
//-----------------------------------------------------------------------------
void CChunkFile::HandleError(const char *szChunkName, ChunkFileResult_t eError)
{
// UNDONE: dispatch errors to the error handler.
// - keep track of current chunkname for reporting errors
// - use the last non-NULL handler that was pushed onto the stack?
// - need a return code to determine whether to abort parsing?
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : ChunkFileResult_t
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::HandleChunk(const char *szChunkName)
{
// See if the default handler wants it?
if( m_DefaultChunkHandler )
{
ChunkFileResult_t testResult = m_DefaultChunkHandler( this, m_pDefaultChunkHandlerData, szChunkName );
if( testResult == ChunkFile_Ok )
{
return ChunkFile_Ok;
}
}
//
// If there is an active handler map...
//
if (m_nHandlerStackDepth > 0)
{
CChunkHandlerMap *pHandler = m_HandlerStack[m_nHandlerStackDepth - 1];
//
// If a chunk handler was found in the handler map...
//
void *pData;
ChunkHandler_t pfnHandler = pHandler->GetHandler(szChunkName, &pData);
if (pfnHandler != NULL)
{
// Dispatch this chunk to the handler.
ChunkFileResult_t eResult = pfnHandler(this, pData);
if (eResult != ChunkFile_Ok)
{
return(eResult);
}
}
else
{
//
// No handler for this chunk. Skip to the matching close curly brace.
//
int nDepth = 1;
ChunkFileResult_t eResult;
do
{
ChunkType_t eChunkType;
char szKey[MAX_KEYVALUE_LEN];
char szValue[MAX_KEYVALUE_LEN];
while ((eResult = ReadNext(szKey, szValue, sizeof(szValue), eChunkType)) == ChunkFile_Ok)
{
if (eChunkType == ChunkType_Chunk)
{
nDepth++;
}
}
if (eResult == ChunkFile_EndOfChunk)
{
eResult = ChunkFile_Ok;
nDepth--;
}
else if (eResult == ChunkFile_EOF)
{
return(ChunkFile_UnexpectedEOF);
}
} while ((nDepth) && (eResult == ChunkFile_Ok));
}
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose: Opens the chunk file for reading or writing.
// Input : pszFileName - Path of file to open.
// eMode - ChunkFile_Read or ChunkFile_Write.
// Output : Returns ChunkFile_Ok on success, ChunkFile_Fail on failure.
// UNDONE: boolean return value?
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::Open(const char *pszFileName, ChunkFileOpenMode_t eMode)
{
if (eMode == ChunkFile_Read)
{
// UNDONE: TokenReader encapsulates file - unify reading and writing to use the same file I/O.
// UNDONE: Support in-memory parsing.
if (m_TokenReader.Open(pszFileName))
{
m_nCurrentDepth = 0;
}
else
{
return(ChunkFile_OpenFail);
}
}
else if (eMode == ChunkFile_Write)
{
m_hFile = fopen(pszFileName, "wb");
if (m_hFile == NULL)
{
return(ChunkFile_OpenFail);
}
m_nCurrentDepth = 0;
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose: Removes the topmost set of chunk handlers.
//-----------------------------------------------------------------------------
void CChunkFile::PopHandlers(void)
{
if (m_nHandlerStackDepth > 0)
{
m_nHandlerStackDepth--;
}
}
void CChunkFile::SetDefaultChunkHandler( DefaultChunkHandler_t pHandler, void *pData )
{
m_DefaultChunkHandler = pHandler;
m_pDefaultChunkHandlerData = pData;}
//-----------------------------------------------------------------------------
// Purpose: Adds a set of chunk handlers to the top of the handler stack.
// Input : pHandlerMap - Object containing the list of chunk handlers.
//-----------------------------------------------------------------------------
void CChunkFile::PushHandlers(CChunkHandlerMap *pHandlerMap)
{
if (m_nHandlerStackDepth < MAX_INDENT_DEPTH)
{
m_HandlerStack[m_nHandlerStackDepth] = pHandlerMap;
m_nHandlerStackDepth++;
}
}
//-----------------------------------------------------------------------------
// Purpose: Reads the next term from the chunk file. The type of term read is
// returned in the eChunkType parameter.
// Input : szName - Name of key or chunk.
// szValue - If eChunkType is ChunkType_Key, contains the value of the key.
// nValueSize - Size of the buffer pointed to by szValue.
// eChunkType - ChunkType_Key or ChunkType_Chunk.
// Output : Returns ChunkFile_Ok on success, an error code if a parsing error occurs.
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::ReadNext(char *szName, char *szValue, int nValueSize, ChunkType_t &eChunkType)
{
// HACK: pass in buffer sizes?
trtoken_t eTokenType = m_TokenReader.NextToken(szName, MAX_KEYVALUE_LEN);
if (eTokenType != TOKENEOF)
{
switch (eTokenType)
{
case IDENT:
case STRING:
{
char szNext[MAX_KEYVALUE_LEN];
trtoken_t eNextTokenType;
//
// Read the next token to determine what we have.
//
eNextTokenType = m_TokenReader.NextToken(szNext, sizeof(szNext));
switch (eNextTokenType)
{
case OPERATOR:
{
if (!stricmp(szNext, "{"))
{
// Beginning of new chunk.
m_nCurrentDepth++;
eChunkType = ChunkType_Chunk;
szValue[0] = '\0';
return(ChunkFile_Ok);
}
else
{
// Unexpected symbol.
Q_strncpy(m_szErrorToken, szNext, sizeof( m_szErrorToken ) );
return(ChunkFile_UnexpectedSymbol);
}
}
case STRING:
case IDENT:
{
// Key value pair.
Q_strncpy(szValue, szNext, nValueSize );
eChunkType = ChunkType_Key;
return(ChunkFile_Ok);
}
case TOKENEOF:
{
// Unexpected end of file.
return(ChunkFile_UnexpectedEOF);
}
case TOKENSTRINGTOOLONG:
{
// String too long or unterminated string.
return ChunkFile_StringTooLong;
}
}
}
case OPERATOR:
{
if (!stricmp(szName, "}"))
{
// End of current chunk.
m_nCurrentDepth--;
return(ChunkFile_EndOfChunk);
}
else
{
// Unexpected symbol.
Q_strncpy(m_szErrorToken, szName, sizeof( m_szErrorToken ) );
return(ChunkFile_UnexpectedSymbol);
}
}
case TOKENSTRINGTOOLONG:
{
return ChunkFile_StringTooLong;
}
}
}
if (m_nCurrentDepth != 0)
{
// End of file while within the scope of a chunk.
return(ChunkFile_UnexpectedEOF);
}
return(ChunkFile_EOF);
}
//-----------------------------------------------------------------------------
// Purpose: Reads the current chunk and dispatches keys and sub-chunks to the
// appropriate handler callbacks.
// Input : pfnKeyHandler - Callback for any key values in this chunk.
// pData - Data to pass to the key value callback function.
// Output : Normally returns ChunkFile_Ok or ChunkFile_EOF. Otherwise, returns
// a ChunkFile_xxx error code.
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::ReadChunk(KeyHandler_t pfnKeyHandler, void *pData)
{
//
// Read the keys and sub-chunks.
//
ChunkFileResult_t eResult;
do
{
char szName[MAX_KEYVALUE_LEN];
char szValue[MAX_KEYVALUE_LEN];
ChunkType_t eChunkType;
eResult = ReadNext(szName, szValue, sizeof(szValue), eChunkType);
if (eResult == ChunkFile_Ok)
{
if (eChunkType == ChunkType_Chunk)
{
//
// Dispatch sub-chunks to the appropriate handler.
//
eResult = HandleChunk(szName);
}
else if ((eChunkType == ChunkType_Key) && (pfnKeyHandler != NULL))
{
//
// Dispatch keys to the key value handler.
//
eResult = pfnKeyHandler(szName, szValue, pData);
}
}
} while (eResult == ChunkFile_Ok);
//
// Cover up ChunkFile_EndOfChunk results because the caller doesn't want to see them.
//
if (eResult == ChunkFile_EndOfChunk)
{
eResult = ChunkFile_Ok;
}
//
// Dispatch errors to the handler.
//
if ((eResult != ChunkFile_Ok) && (eResult != ChunkFile_EOF))
{
//HandleError("chunkname", eResult);
}
return(eResult);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszValue -
// pbBool -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValueBool(const char *pszValue, bool &bBool)
{
int nValue = atoi(pszValue);
if (nValue > 0)
{
bBool = true;
}
else
{
bBool = false;
}
return(true);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszValue -
// pfFloat -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValueFloat(const char *pszValue, float &flFloat)
{
flFloat = (float)atof(pszValue);
return(true);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszValue -
// pnInt -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValueInt(const char *pszValue, int &nInt)
{
nInt = atoi(pszValue);
return(true);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// r -
// g -
// b -
// Output :
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValueColor(const char *pszValue, unsigned char &chRed, unsigned char &chGreen, unsigned char &chBlue)
{
if (pszValue != NULL)
{
int r;
int g;
int b;
if (sscanf(pszValue, "%d %d %d", &r, &g, &b) == 3)
{
chRed = r;
chGreen = g;
chBlue = b;
return(true);
}
}
return(false);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszValue -
// pfPoint -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValuePoint(const char *pszValue, Vector &Point)
{
if (pszValue != NULL)
{
return(sscanf(pszValue, "(%f %f %f)", &Point.x, &Point.y, &Point.z) == 3);
}
return(false);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszValue -
// pfVector -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValueVector2(const char *pszValue, Vector2D &vec)
{
if (pszValue != NULL)
{
return ( sscanf( pszValue, "[%f %f]", &vec.x, &vec.y) == 2 );
}
return(false);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszValue -
// pfVector -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValueVector3(const char *pszValue, Vector &vec)
{
if (pszValue != NULL)
{
return(sscanf(pszValue, "[%f %f %f]", &vec.x, &vec.y, &vec.z) == 3);
}
return(false);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszValue -
// pfVector -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CChunkFile::ReadKeyValueVector4(const char *pszValue, Vector4D &vec)
{
if( pszValue != NULL )
{
return(sscanf(pszValue, "[%f %f %f %f]", &vec[0], &vec[1], &vec[2], &vec[3]) == 4);
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszLine -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValue(const char *pszKey, const char *pszValue)
{
if ((pszKey != NULL) && (pszValue != NULL))
{
char szTemp[MAX_KEYVALUE_LEN];
Q_snprintf(szTemp, sizeof( szTemp ), "\"%s\" \"%s\"", pszKey, pszValue);
return(WriteLine(szTemp));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// bValue -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValueBool(const char *pszKey, bool bValue)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%d\"", pszKey, (int)bValue);
return(WriteLine(szBuf));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// nValue -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValueInt(const char *pszKey, int nValue)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%d\"", pszKey, nValue);
return(WriteLine(szBuf));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// fValue -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValueFloat(const char *pszKey, float fValue)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%g\"", pszKey, (double)fValue);
return(WriteLine(szBuf));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// r -
// g -
// b -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValueColor(const char *pszKey, unsigned char r, unsigned char g, unsigned char b)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%d %d %d\"", pszKey, (int)r, (int)g, (int)b);
return(WriteLine(szBuf));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// fVector -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValuePoint(const char *pszKey, const Vector &Point)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"(%g %g %g)\"", pszKey, (double)Point[0], (double)Point[1], (double)Point[2]);
return(WriteLine(szBuf));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValueVector2(const char *pszKey, const Vector2D &vec)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf( szBuf, sizeof( szBuf ), "\"%s\" \"[%g %g]\"", pszKey, (double)vec.x, (double)vec.y );
return(WriteLine(szBuf));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValueVector3(const char *pszKey, const Vector &vec)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"[%g %g %g]\"", pszKey, (double)vec.x, (double)vec.y, (double)vec.z);
return(WriteLine(szBuf));
}
return(ChunkFile_Ok);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// fVector -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteKeyValueVector4(const char *pszKey, const Vector4D &vec)
{
if (pszKey != NULL)
{
char szBuf[MAX_KEYVALUE_LEN];
Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"[%g %g %g %g]\"", pszKey, (double)vec.x, (double)vec.y, (double)vec.z, (double)vec.w);
return( WriteLine( szBuf ) );
}
return( ChunkFile_Ok );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pszLine -
// Output :
//-----------------------------------------------------------------------------
ChunkFileResult_t CChunkFile::WriteLine(const char *pszLine)
{
if (pszLine != NULL)
{
//
// Write the indentation string.
//
if (m_nCurrentDepth > 0)
{
int nWritten = fwrite(m_szIndent, 1, m_nCurrentDepth, m_hFile);
if (nWritten != m_nCurrentDepth)
{
return(ChunkFile_Fail);
}
}
//
// Write the string.
//
int nLen = strlen(pszLine);
int nWritten = fwrite(pszLine, 1, nLen, m_hFile);
if (nWritten != nLen)
{
return(ChunkFile_Fail);
}
//
// Write the linefeed.
//
if (fwrite("\r\n", 1, 2, m_hFile) != 2)
{
return(ChunkFile_Fail);
}
}
return(ChunkFile_Ok);
}

197
public/chunkfile.h Normal file
View File

@@ -0,0 +1,197 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef CHUNKFILE_H
#define CHUNKFILE_H
#ifdef _WIN32
#pragma once
#endif
#include <stdio.h>
#include "tier2/tokenreader.h"
#define MAX_INDENT_DEPTH 80
#define MAX_KEYVALUE_LEN 1024
class CChunkFile;
class Vector2D;
class Vector;
class Vector4D;
//
// Modes for Open.
//
enum ChunkFileOpenMode_t
{
ChunkFile_Read = 0,
ChunkFile_Write,
};
//
// Return codes.
//
enum ChunkFileResult_t
{
ChunkFile_Ok = 0,
ChunkFile_Fail,
ChunkFile_OpenFail,
ChunkFile_EndOfChunk,
ChunkFile_EOF,
ChunkFile_UnexpectedEOF,
ChunkFile_UnexpectedSymbol,
ChunkFile_OutOfMemory,
ChunkFile_StringTooLong,
ChunkFile_NotHandled
};
enum ChunkType_t
{
ChunkType_Key = 0,
ChunkType_Chunk,
};
typedef ChunkFileResult_t (*DefaultChunkHandler_t)(CChunkFile *pFile, void *pData, char const *pChunkName);
typedef ChunkFileResult_t (*ChunkHandler_t)(CChunkFile *pFile, void *pData);
typedef ChunkFileResult_t (*KeyHandler_t)(const char *szKey, const char *szValue, void *pData);
typedef bool (*ChunkErrorHandler_t)(CChunkFile *pFile, const char *szChunkName, void *pData);
struct ChunkHandlerInfo_t
{
char szChunkName[80];
ChunkHandler_t pfnHandler;
void *pData;
};
struct ChunkHandlerInfoNode_t
{
ChunkHandlerInfo_t Handler;
struct ChunkHandlerInfoNode_t *pNext;
};
//
// Consider handling chunks with handler objects instead of callbacks.
//
//class CChunkHandler
//{
// virtual ChunkFileResult_t HandleChunk(const char *szName);
// virtual ChunkFileResult_t HandleKey(const char *szKey, const char *szValue);
// virtual bool HandleError(const char *szChunkName, ChunkFileResult_t eError);
//};
class CChunkHandlerMap
{
public:
CChunkHandlerMap(void);
~CChunkHandlerMap(void);
void AddHandler(const char *pszChunkName, ChunkHandler_t pfnHandler, void *pData);
ChunkHandler_t GetHandler(const char *pszChunkName, void **pData);
void SetErrorHandler(ChunkErrorHandler_t pfnHandler, void *pData);
ChunkErrorHandler_t GetErrorHandler(void **pData);
protected:
ChunkHandlerInfoNode_t *m_pHandlers;
ChunkErrorHandler_t m_pfnErrorHandler;
void *m_pErrorData;
};
class CChunkFile
{
public:
CChunkFile(void);
~CChunkFile(void);
ChunkFileResult_t Open(const char *pszFileName, ChunkFileOpenMode_t eMode);
ChunkFileResult_t Close(void);
const char *GetErrorText(ChunkFileResult_t eResult);
//
// Functions for writing chunk files.
//
ChunkFileResult_t BeginChunk(const char *pszChunkName);
ChunkFileResult_t EndChunk(void);
ChunkFileResult_t WriteKeyValue(const char *pszKey, const char *pszValue);
ChunkFileResult_t WriteKeyValueBool(const char *pszKey, bool bValue);
ChunkFileResult_t WriteKeyValueColor(const char *pszKey, unsigned char r, unsigned char g, unsigned char b);
ChunkFileResult_t WriteKeyValueFloat(const char *pszKey, float fValue);
ChunkFileResult_t WriteKeyValueInt(const char *pszKey, int nValue);
ChunkFileResult_t WriteKeyValuePoint(const char *pszKey, const Vector &Point);
ChunkFileResult_t WriteKeyValueVector2(const char *pszKey, const Vector2D &vec);
ChunkFileResult_t WriteKeyValueVector3(const char *pszKey, const Vector &vec);
ChunkFileResult_t WriteKeyValueVector4( const char *pszKey, const Vector4D &vec);
ChunkFileResult_t WriteLine(const char *pszLine);
//
// Functions for reading chunk files.
//
ChunkFileResult_t ReadChunk(KeyHandler_t pfnKeyHandler = NULL, void *pData = NULL);
ChunkFileResult_t ReadNext(char *szKey, char *szValue, int nValueSize, ChunkType_t &eChunkType);
ChunkFileResult_t HandleChunk(const char *szChunkName);
void HandleError(const char *szChunkName, ChunkFileResult_t eError);
// These functions should more really be named Parsexxx and possibly moved elsewhere.
static bool ReadKeyValueBool(const char *pszValue, bool &bBool);
static bool ReadKeyValueColor(const char *pszValue, unsigned char &chRed, unsigned char &chGreen, unsigned char &chBlue);
static bool ReadKeyValueInt(const char *pszValue, int &nInt);
static bool ReadKeyValueFloat(const char *pszValue, float &flFloat);
static bool ReadKeyValuePoint(const char *pszValue, Vector &Point);
static bool ReadKeyValueVector2(const char *pszValue, Vector2D &vec);
static bool ReadKeyValueVector3(const char *pszValue, Vector &vec);
static bool ReadKeyValueVector4( const char *pszValue, Vector4D &vec);
// The default chunk handler gets called before any other chunk handlers.
//
// If the handler returns ChunkFile_Ok, then it goes into the chunk.
// If the handler returns ChunkFile_NotHandled, then the chunk is
// passed to the regular handlers.
//
// If you pass NULL in here, then it disables the default chunk handler.
void SetDefaultChunkHandler( DefaultChunkHandler_t pHandler, void *pData );
void PushHandlers(CChunkHandlerMap *pHandlerMap);
void PopHandlers(void);
protected:
void BuildIndentString(char *pszDest, int nDepth);
TokenReader m_TokenReader;
FILE *m_hFile;
char m_szErrorToken[80];
char m_szIndent[MAX_INDENT_DEPTH];
int m_nCurrentDepth;
// See SetDefaultChunkHandler..
DefaultChunkHandler_t m_DefaultChunkHandler;
void *m_pDefaultChunkHandlerData;
CChunkHandlerMap *m_HandlerStack[MAX_INDENT_DEPTH];
int m_nHandlerStackDepth;
};
#endif // CHUNKFILE_H

16
public/client_class.cpp Normal file
View File

@@ -0,0 +1,16 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "client_class.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ClientClass *g_pClientClassHead=0;

182
public/client_class.h Normal file
View File

@@ -0,0 +1,182 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#if !defined( CLIENT_CLASS_H )
#define CLIENT_CLASS_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include "dt_recv.h"
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
class Vector;
class CMouthInfo;
//-----------------------------------------------------------------------------
// represents a handle used only by the client DLL
//-----------------------------------------------------------------------------
#include "iclientrenderable.h"
#include "iclientnetworkable.h"
class ClientClass;
// Linked list of all known client classes
extern ClientClass *g_pClientClassHead;
// The serial number that gets passed in is used for ehandles.
typedef IClientNetworkable* (*CreateClientClassFn)( int entnum, int serialNum );
typedef IClientNetworkable* (*CreateEventFn)();
//-----------------------------------------------------------------------------
// Purpose: Client side class definition
//-----------------------------------------------------------------------------
class ClientClass
{
public:
ClientClass( char *pNetworkName, CreateClientClassFn createFn, CreateEventFn createEventFn, RecvTable *pRecvTable )
{
m_pNetworkName = pNetworkName;
m_pCreateFn = createFn;
m_pCreateEventFn= createEventFn;
m_pRecvTable = pRecvTable;
m_pMapClassname = NULL;
// Link it in
m_pNext = g_pClientClassHead;
g_pClientClassHead = this;
}
const char* GetName()
{
return m_pNetworkName;
}
public:
CreateClientClassFn m_pCreateFn;
CreateEventFn m_pCreateEventFn; // Only called for event objects.
char *m_pNetworkName;
RecvTable *m_pRecvTable;
ClientClass *m_pNext;
int m_ClassID; // Managed by the engine.
const char *m_pMapClassname;
};
#define DECLARE_CLIENTCLASS() \
virtual int YouForgotToImplementOrDeclareClientClass();\
virtual ClientClass* GetClientClass();\
static RecvTable *m_pClassRecvTable; \
DECLARE_CLIENTCLASS_NOBASE()
// This can be used to give all datatables access to protected and private members of the class.
#define ALLOW_DATATABLES_PRIVATE_ACCESS() \
template <typename T> friend int ClientClassInit(T *);
#define DECLARE_CLIENTCLASS_NOBASE ALLOW_DATATABLES_PRIVATE_ACCESS
// This macro adds a ClientClass to the linked list in g_pClientClassHead (so
// the list can be given to the engine).
// Use this macro to expose your client class to the engine.
// networkName must match the network name of a class registered on the server.
#define IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName) \
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \
static IClientNetworkable* _##clientClassName##_CreateObject( int entnum, int serialNum ) \
{ \
clientClassName *pRet = new clientClassName; \
if ( !pRet ) \
return 0; \
pRet->Init( entnum, serialNum ); \
return pRet; \
} \
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \
_##clientClassName##_CreateObject, \
NULL,\
&dataTable::g_RecvTable);
// Implement a client class and provide a factory so you can allocate and delete it yourself
// (or make it a singleton).
#define IMPLEMENT_CLIENTCLASS_FACTORY(clientClassName, dataTable, serverClassName, factory) \
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \
factory, \
NULL,\
&dataTable::g_RecvTable);
// The IMPLEMENT_CLIENTCLASS_DT macros do IMPLEMENT_CLIENT_CLASS and also do BEGIN_RECV_TABLE.
#define IMPLEMENT_CLIENTCLASS_DT(clientClassName, dataTable, serverClassName)\
IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName)\
BEGIN_RECV_TABLE(clientClassName, dataTable)
#define IMPLEMENT_CLIENTCLASS_DT_NOBASE(clientClassName, dataTable, serverClassName)\
IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName)\
BEGIN_RECV_TABLE_NOBASE(clientClassName, dataTable)
// Using IMPLEMENT_CLIENTCLASS_EVENT means the engine thinks the entity is an event so the entity
// is responsible for freeing itself.
#define IMPLEMENT_CLIENTCLASS_EVENT(clientClassName, dataTable, serverClassName)\
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName)\
static clientClassName __g_##clientClassName; \
static IClientNetworkable* _##clientClassName##_CreateObject() {return &__g_##clientClassName;}\
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \
NULL,\
_##clientClassName##_CreateObject, \
&dataTable::g_RecvTable);
#define IMPLEMENT_CLIENTCLASS_EVENT_DT(clientClassName, dataTable, serverClassName)\
namespace dataTable {extern RecvTable g_RecvTable;}\
IMPLEMENT_CLIENTCLASS_EVENT(clientClassName, dataTable, serverClassName)\
BEGIN_RECV_TABLE(clientClassName, dataTable)
// Register a client event singleton but specify a pointer to give to the engine rather than
// have a global instance. This is useful if you're using Initializers and your object's constructor
// uses some other global object (so you must use Initializers so you're constructed afterwards).
#define IMPLEMENT_CLIENTCLASS_EVENT_POINTER(clientClassName, dataTable, serverClassName, ptr)\
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName)\
static IClientNetworkable* _##clientClassName##_CreateObject() {return ptr;}\
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \
NULL,\
_##clientClassName##_CreateObject, \
&dataTable::g_RecvTable);
#define IMPLEMENT_CLIENTCLASS_EVENT_NONSINGLETON(clientClassName, dataTable, serverClassName)\
static IClientNetworkable* _##clientClassName##_CreateObject() \
{ \
clientClassName *p = new clientClassName; \
if ( p ) \
p->Init( -1, 0 ); \
return p; \
} \
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \
NULL,\
_##clientClassName##_CreateObject, \
&dataTable::g_RecvTable);
// Used internally..
#define INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \
namespace dataTable {extern RecvTable g_RecvTable;}\
extern ClientClass __g_##clientClassName##ClientClass;\
RecvTable* clientClassName::m_pClassRecvTable = &dataTable::g_RecvTable;\
int clientClassName::YouForgotToImplementOrDeclareClientClass() {return 0;}\
ClientClass* clientClassName::GetClientClass() {return &__g_##clientClassName##ClientClass;}
#endif // CLIENT_CLASS_H

View File

@@ -0,0 +1,31 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef CLIENT_RENDER_HANDLE_H
#define CLIENT_RENDER_HANDLE_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Foward declarations
//-----------------------------------------------------------------------------
class IClientRenderable;
//-----------------------------------------------------------------------------
// Handle to an renderable in the client leaf system
//-----------------------------------------------------------------------------
typedef unsigned short ClientRenderHandle_t;
enum
{
INVALID_CLIENT_RENDER_HANDLE = (ClientRenderHandle_t)0xffff,
};
#endif // CLIENT_RENDER_HANDLE_H

View File

@@ -0,0 +1,33 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef CLIENT_TEXTMESSAGE_H
#define CLIENT_TEXTMESSAGE_H
#ifdef _WIN32
#pragma once
#endif
struct client_textmessage_t
{
int effect;
byte r1, g1, b1, a1; // 2 colors for effects
byte r2, g2, b2, a2;
float x;
float y;
float fadein;
float fadeout;
float holdtime;
float fxtime;
const char *pVGuiSchemeFontName; // If null, use default font for messages
const char *pName;
const char *pMessage;
bool bRoundedRectBackdropBox;
float flBoxSize; // as a function of font height
byte boxcolor[4];
char const *pClearMessage; // message to clear
};
#endif // CLIENT_TEXTMESSAGE_H

198
public/clientstats.h Normal file
View File

@@ -0,0 +1,198 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#if !defined( CLIENTSTATS_H )
#define CLIENTSTATS_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include <limits.h>
#include "tier0/dbg.h"
#define INTERFACEVERSION_CLIENTSTATS "ClientStats004"
//-----------------------------------------------------------------------------
// An interface used to help the client stats implementation tell time
//-----------------------------------------------------------------------------
struct IClientStatsTime
{
virtual float GetTime() = 0;
};
//-----------------------------------------------------------------------------
// Allows clients to draw their own stats text, will be passed by the
// engine into DisplayStats of the IClientStats interface.
//-----------------------------------------------------------------------------
struct IClientStatsTextDisplay
{
// Draws the stats
virtual void DrawStatsText( PRINTF_FORMAT_STRING const char *fmt, ... ) = 0;
virtual void SetDrawColor( unsigned char r, unsigned char g, unsigned char b ) = 0;
// Sets a color based on a value and its max acceptable limit
virtual void SetDrawColorFromStatValues( float limit, float value ) = 0;
};
//-----------------------------------------------------------------------------
// This will exist as a singleton within the client DLL and will be hooked into
// the engine to allow clients to render their own stats.
//-----------------------------------------------------------------------------
abstract_class IClientStats
{
public:
// This is called at startup to tell the stats about time
virtual void Init( IClientStatsTime* pTime ) = 0;
// These methods are called at the beginning and the end of each run
virtual void BeginRun() = 0;
virtual void EndRun() = 0;
// These methods are called at the beginning and the end of each frame
virtual void BeginFrame() = 0;
virtual void EndFrame() = 0;
// ---------------------------------------------------------------
// All this stuff is used to prop stats for gathering r_speeds data during timedemo.
// ---------------------------------------------------------------
virtual int GetNumTimesStats( void ) const = 0;
// returns timed stats
virtual double TimedStatInFrame( int statID ) const = 0;
virtual double TotalTimedStat( int statID ) const = 0;
};
//-----------------------------------------------------------------------------
// This is a templatized implementation which can be instantiated anywhere
// Note that you still have to install it and display it though.
//-----------------------------------------------------------------------------
template <int timedStatCount, int countedStatCount>
abstract_class CBaseClientStats : public IClientStats
{
public:
void Init( IClientStatsTime* pTime );
void BeginRun();
void EndRun();
void BeginFrame();
void EndFrame();
// Timed stat gathering
void BeginTimedStat( int stat );
void EndTimedStat( int stat );
// ---------------------------------------------------------------
// All this stuff is used to prop stats for gathering r_speeds data during timedemo.
// ---------------------------------------------------------------
// returns timed stats
double TimedStatInFrame( int statID ) const
{
Assert( statID >= 0 && statID < timedStatCount );
Assert( m_StatFrameTime[statID] >= 0.0 );
return m_StatFrameTime[statID];
}
double TotalTimedStat( int statID ) const
{
Assert( statID >= 0 && statID < timedStatCount );
return m_TotalStatTime[statID];
}
virtual const char *GetCountedStatName( int statID ) const = 0;
virtual const char *GetTimedStatName( int statID ) const = 0;
protected:
// Timed statistics
double m_StatFrameTime[timedStatCount];
double m_StatStartTime[timedStatCount];
double m_TotalStatTime[timedStatCount];
private:
IClientStatsTime* m_pTime;
};
//-----------------------------------------------------------------------------
// Initializes client stats
//-----------------------------------------------------------------------------
template <int timedStatCount, int countedStatCount>
void CBaseClientStats<timedStatCount, countedStatCount>::Init( IClientStatsTime* pTime )
{
Assert( pTime );
m_pTime = pTime;
}
//-----------------------------------------------------------------------------
// These methods are called at the beginning and the end of each run
//-----------------------------------------------------------------------------
template <int timedStatCount, int countedStatCount>
void CBaseClientStats<timedStatCount, countedStatCount>::BeginRun()
{
int i;
for (i = 0; i < timedStatCount; ++i)
m_TotalStatTime[i] = 0.0;
}
template <int timedStatCount, int countedStatCount>
void CBaseClientStats<timedStatCount, countedStatCount>::EndRun()
{
}
//-----------------------------------------------------------------------------
// These methods are called at the beginning and the end of each frame
//-----------------------------------------------------------------------------
template <int timedStatCount, int countedStatCount>
void CBaseClientStats<timedStatCount, countedStatCount>::BeginFrame()
{
int i;
for (i = 0; i < timedStatCount; ++i)
m_StatFrameTime[i] = 0.0;
}
template <int timedStatCount, int countedStatCount>
void CBaseClientStats<timedStatCount, countedStatCount>::EndFrame()
{
int i;
for (i = 0; i < timedStatCount; ++i)
m_TotalStatTime[i] += m_StatFrameTime[i];
}
//-----------------------------------------------------------------------------
// Inlined stat gathering methods
//-----------------------------------------------------------------------------
template <int timedStatCount, int countedStatCount>
void CBaseClientStats<timedStatCount, countedStatCount>::BeginTimedStat( int stat )
{
if (m_pTime)
m_StatStartTime[stat] = m_pTime->GetTime();
}
template <int timedStatCount, int countedStatCount>
void CBaseClientStats<timedStatCount, countedStatCount>::EndTimedStat( int stat )
{
if (m_pTime)
m_StatFrameTime[stat] += m_pTime->GetTime() - m_StatStartTime[stat];
}
#endif // CLIENTSTATS_H

62
public/closedcaptions.cpp Normal file
View File

@@ -0,0 +1,62 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "closedcaptions.h"
#include "filesystem.h"
#include "tier1/utlbuffer.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// Assumed to be set up by calling code
bool AsyncCaption_t::LoadFromFile( char const *pchFullPath )
{
FileHandle_t fh = g_pFullFileSystem->Open( pchFullPath, "rb" );
if ( FILESYSTEM_INVALID_HANDLE == fh )
return false;
MEM_ALLOC_CREDIT();
CUtlBuffer dirbuffer;
// Read the header
g_pFullFileSystem->Read( &m_Header, sizeof( m_Header ), fh );
if ( m_Header.magic != COMPILED_CAPTION_FILEID )
{
if( IsPS3() )
return false;
else
Error( "Invalid file id for %s\n", pchFullPath );
}
if ( m_Header.version != COMPILED_CAPTION_VERSION )
{
if( IsPS3() )
return false;
else
Error( "Invalid file version for %s\n", pchFullPath );
}
if ( m_Header.directorysize < 0 || m_Header.directorysize > 64 * 1024 )
{
if( IsPS3() )
return false;
else
Error( "Invalid directory size %d for %s\n", m_Header.directorysize, pchFullPath );
}
//if ( m_Header.blocksize != MAX_BLOCK_SIZE )
// Error( "Invalid block size %d, expecting %d for %s\n", m_Header.blocksize, MAX_BLOCK_SIZE, pchFullPath );
int directoryBytes = m_Header.directorysize * sizeof( CaptionLookup_t );
m_CaptionDirectory.EnsureCapacity( m_Header.directorysize );
dirbuffer.EnsureCapacity( directoryBytes );
g_pFullFileSystem->Read( dirbuffer.Base(), directoryBytes, fh );
g_pFullFileSystem->Close( fh );
m_CaptionDirectory.CopyArray( (const CaptionLookup_t *)dirbuffer.PeekGet(), m_Header.directorysize );
m_CaptionDirectory.RedoSort( true );
m_DataBaseFile = pchFullPath;
return true;
}

70
public/closedcaptions.h Normal file
View File

@@ -0,0 +1,70 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef CLOSEDCAPTIONS_H
#define CLOSEDCAPTIONS_H
#ifdef _WIN32
#pragma once
#endif
#include "captioncompiler.h"
#include "tier1/utlsymbol.h"
#include "tier1/utlsortvector.h"
FORWARD_DECLARE_HANDLE( memhandle_t );
typedef CUtlSortVector< CaptionLookup_t, CCaptionLookupLess > CaptionDictionary_t;
struct AsyncCaption_t
{
AsyncCaption_t() :
m_DataBaseFile( UTL_INVAL_SYMBOL ),
m_RequestedBlocks( 0, 0, BlockInfo_t::Less )
{
Q_memset( &m_Header, 0, sizeof( m_Header ) );
}
struct BlockInfo_t
{
int fileindex;
int blocknum;
memhandle_t handle;
static bool Less( const BlockInfo_t& lhs, const BlockInfo_t& rhs )
{
if ( lhs.fileindex != rhs.fileindex )
return lhs.fileindex < rhs.fileindex;
return lhs.blocknum < rhs.blocknum;
}
};
AsyncCaption_t& operator =( const AsyncCaption_t& rhs )
{
if ( this == &rhs )
return *this;
m_CaptionDirectory = rhs.m_CaptionDirectory;
m_Header = rhs.m_Header;
m_DataBaseFile = rhs.m_DataBaseFile;
for ( int i = rhs.m_RequestedBlocks.FirstInorder(); i != rhs.m_RequestedBlocks.InvalidIndex(); i = rhs.m_RequestedBlocks.NextInorder( i ) )
{
m_RequestedBlocks.Insert( rhs.m_RequestedBlocks[ i ] );
}
return *this;
}
bool LoadFromFile( char const *pchFullPath );
CUtlRBTree< BlockInfo_t, unsigned short > m_RequestedBlocks;
CaptionDictionary_t m_CaptionDirectory;
CompiledCaptionHeader_t m_Header;
CUtlSymbol m_DataBaseFile;
};
#endif // CLOSEDCAPTIONS_H

134
public/cmodel.h Normal file
View File

@@ -0,0 +1,134 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef CMODEL_H
#define CMODEL_H
#ifdef _WIN32
#pragma once
#endif
#include "trace.h"
#include "tier0/dbg.h"
#include "basehandle.h"
struct edict_t;
struct model_t;
/*
==============================================================
COLLISION DETECTION
==============================================================
*/
#include "bspflags.h"
//#include "mathlib/vector.h"
// gi.BoxEdicts() can return a list of either solid or trigger entities
// FIXME: eliminate AREA_ distinction?
#define AREA_SOLID 1
#define AREA_TRIGGERS 2
#include "vcollide.h"
struct cmodel_t
{
Vector mins, maxs;
Vector origin; // for sounds or lights
int headnode;
vcollide_t vcollisionData;
};
struct csurface_t
{
const char *name;
short surfaceProps;
unsigned short flags; // BUGBUG: These are declared per surface, not per material, but this database is per-material now
};
//-----------------------------------------------------------------------------
// A ray...
//-----------------------------------------------------------------------------
struct Ray_t
{
VectorAligned m_Start; // starting point, centered within the extents
VectorAligned m_Delta; // direction + length of the ray
VectorAligned m_StartOffset; // Add this to m_Start to get the actual ray start
VectorAligned m_Extents; // Describes an axis aligned box extruded along a ray
const matrix3x4_t *m_pWorldAxisTransform;
bool m_IsRay; // are the extents zero?
bool m_IsSwept; // is delta != 0?
Ray_t() : m_pWorldAxisTransform( NULL ) {}
void Init( Vector const& start, Vector const& end )
{
Assert( &end );
VectorSubtract( end, start, m_Delta );
m_IsSwept = (m_Delta.LengthSqr() != 0);
VectorClear( m_Extents );
m_pWorldAxisTransform = NULL;
m_IsRay = true;
// Offset m_Start to be in the center of the box...
VectorClear( m_StartOffset );
VectorCopy( start, m_Start );
}
void Init( Vector const& start, Vector const& end, Vector const& mins, Vector const& maxs )
{
Assert( &end );
VectorSubtract( end, start, m_Delta );
m_pWorldAxisTransform = NULL;
m_IsSwept = (m_Delta.LengthSqr() != 0);
VectorSubtract( maxs, mins, m_Extents );
m_Extents *= 0.5f;
m_IsRay = (m_Extents.LengthSqr() < 1e-6);
Assert(m_Extents.x >=0 && m_Extents.y >= 0 && m_Extents.z >= 0);
// Offset m_Start to be in the center of the box...
VectorAdd( mins, maxs, m_StartOffset );
m_StartOffset *= 0.5f;
VectorAdd( start, m_StartOffset, m_Start );
m_StartOffset *= -1.0f;
}
// compute inverse delta
Vector InvDelta() const
{
Vector vecInvDelta;
for ( int iAxis = 0; iAxis < 3; ++iAxis )
{
if ( m_Delta[iAxis] != 0.0f )
{
vecInvDelta[iAxis] = 1.0f / m_Delta[iAxis];
}
else
{
vecInvDelta[iAxis] = FLT_MAX;
}
}
return vecInvDelta;
}
private:
};
#endif // CMODEL_H
#include "gametrace.h"

3409
public/collisionutils.cpp Normal file

File diff suppressed because it is too large Load Diff

500
public/collisionutils.h Normal file
View File

@@ -0,0 +1,500 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Common collision utility methods
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#ifndef COLLISIONUTILS_H
#define COLLISIONUTILS_H
#include "tier0/platform.h"
#ifdef _WIN32
#pragma once
#endif
#include "mathlib/ssemath.h"
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
struct Ray_t;
class Vector;
class Vector2D;
class Vector4D;
struct cplane_t;
class QAngle;
class CBaseTrace;
struct matrix3x4_t;
//-----------------------------------------------------------------------------
//
// IntersectRayWithTriangle
//
// Intersects a ray with a triangle, returns distance t along ray.
// t will be less than zero if no intersection occurred
// oneSided will cull collisions which approach the triangle from the back
// side, assuming the vertices are specified in counter-clockwise order
// The vertices need not be specified in that order if oneSided is not used
//
//-----------------------------------------------------------------------------
float IntersectRayWithTriangle( const Ray_t& ray,
const Vector& v1, const Vector& v2, const Vector& v3,
bool oneSided );
//-----------------------------------------------------------------------------
//
// ComputeIntersectionBarycentricCoordinates
//
// Figures out the barycentric coordinates (u,v) where a ray hits a
// triangle. Note that this will ignore the ray extents, and it also ignores
// the ray length. Note that the edge from v1->v2 represents u (v2: u = 1),
// and the edge from v1->v3 represents v (v3: v = 1). It returns false
// if the ray is parallel to the triangle (or when t is specified if t is less
// than zero).
//
//-----------------------------------------------------------------------------
bool ComputeIntersectionBarycentricCoordinates( const Ray_t& ray,
const Vector& v1, const Vector& v2, const Vector& v3, float& u, float& v,
float *t = 0 );
//-----------------------------------------------------------------------------
//
// IntersectRayWithRay
//
// Returns whether or not there was an intersection. The "t" paramter is the
// distance along ray0 and the "s" parameter is the distance along ray1. If
// the two lines to not intersect the "t" and "s" represent the closest approach.
// "t" and "s" will not change if the rays are parallel.
//
//-----------------------------------------------------------------------------
bool IntersectRayWithRay( const Ray_t &ray0, const Ray_t &ray1, float &t, float &s );
//-----------------------------------------------------------------------------
//
// IntersectRayWithSphere
//
// Returns whether or not there was an intersection. Returns the two intersection points.
// NOTE: The point of closest approach can be found at the average t value.
//
//-----------------------------------------------------------------------------
bool IntersectRayWithSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta, const Vector &vecSphereCenter, float flRadius, float *pT1, float *pT2 );
//-----------------------------------------------------------------------------
//
// IntersectInfiniteRayWithSphere
//
// Returns whether or not there was an intersection of a sphere against an infinitely
// extending ray.
// Returns the two intersection points
//
//-----------------------------------------------------------------------------
bool IntersectInfiniteRayWithSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta,
const Vector &vecSphereCenter, float flRadius, float *pT1, float *pT2 );
// returns true if the sphere and cone intersect
// NOTE: cone sine/cosine are the half angle of the cone
bool IsSphereIntersectingCone( const Vector &sphereCenter, float sphereRadius, const Vector &coneOrigin, const Vector &coneNormal, float coneSine, float coneCosine );
//-----------------------------------------------------------------------------
//
// IntersectRayWithPlane
//
// Intersects a ray with a plane, returns distance t along ray.
// t will be less than zero the intersection occurs in the opposite direction of the ray.
//
//-----------------------------------------------------------------------------
float IntersectRayWithPlane( const Ray_t& ray, const cplane_t& plane );
float IntersectRayWithPlane( const Vector& org, const Vector& dir, const cplane_t& plane );
float IntersectRayWithPlane( const Vector& org, const Vector& dir, const Vector& normal, float dist );
// This version intersects a ray with an axis-aligned plane
float IntersectRayWithAAPlane( const Vector& vecStart, const Vector& vecEnd, int nAxis, float flSign, float flDist );
//-----------------------------------------------------------------------------
// IntersectRayWithBox
//
// Purpose: Computes the intersection of a ray with a box (AABB)
// Output : Returns true if there is an intersection + trace information
//-----------------------------------------------------------------------------
bool IntersectRayWithBox( const Vector &rayStart, const Vector &rayDelta, const Vector &boxMins, const Vector &boxMaxs, float epsilon, CBaseTrace *pTrace, float *pFractionLeftSolid = NULL );
bool IntersectRayWithBox( const Ray_t &ray, const Vector &boxMins, const Vector &boxMaxs, float epsilon, CBaseTrace *pTrace, float *pFractionLeftSolid = NULL );
//-----------------------------------------------------------------------------
// Intersects a ray against a box
//-----------------------------------------------------------------------------
struct BoxTraceInfo_t
{
float t1;
float t2;
int hitside;
bool startsolid;
};
bool IntersectRayWithBox( const Vector &vecRayStart, const Vector &vecRayDelta,
const Vector &boxMins, const Vector &boxMaxs, float flTolerance, BoxTraceInfo_t *pTrace );
//-----------------------------------------------------------------------------
// IntersectRayWithOBB
//
// Purpose: Computes the intersection of a ray with a oriented box (OBB)
// Output : Returns true if there is an intersection + trace information
//-----------------------------------------------------------------------------
bool IntersectRayWithOBB( const Vector &vecRayStart, const Vector &vecRayDelta,
const matrix3x4_t &matOBBToWorld, const Vector &vecOBBMins, const Vector &vecOBBMaxs,
float flTolerance, CBaseTrace *pTrace );
bool IntersectRayWithOBB( const Vector &vecRayOrigin, const Vector &vecRayDelta,
const Vector &vecBoxOrigin, const QAngle &angBoxRotation,
const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace );
bool IntersectRayWithOBB( const Ray_t &ray, const Vector &vecBoxOrigin, const QAngle &angBoxRotation,
const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace );
bool IntersectRayWithOBB( const Ray_t &ray, const matrix3x4_t &matOBBToWorld,
const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace );
bool IntersectRayWithOBB( const Vector &vecRayStart, const Vector &vecRayDelta,
const matrix3x4_t &matOBBToWorld, const Vector &vecOBBMins, const Vector &vecOBBMaxs,
float flTolerance, BoxTraceInfo_t *pTrace );
//-----------------------------------------------------------------------------
//
// IsSphereIntersectingSphere
//
// returns true if there's an intersection between sphere and sphere
//
//-----------------------------------------------------------------------------
bool IsSphereIntersectingSphere( const Vector& center1, float radius1,
const Vector& center2, float radius2 );
//-----------------------------------------------------------------------------
//
// IsBoxIntersectingSphere
//
// returns true if there's an intersection between box and sphere
//
//-----------------------------------------------------------------------------
bool IsBoxIntersectingSphere( const Vector& boxMin, const Vector& boxMax,
const Vector& center, float radius );
bool IsBoxIntersectingSphereExtents( const Vector& boxCenter, const Vector& boxHalfDiag,
const Vector& center, float radius );
//-----------------------------------------------------------------------------
// Returns true if a box intersects with a sphere
// NOTE: f4RadiusSq must have the radius sq in all components
//-----------------------------------------------------------------------------
FORCEINLINE bool IsBoxIntersectingSphere( const Vector& boxMin, const Vector& boxMax,
const fltx4& f4Center, const fltx4& f4RadiusSq )
{
// See Graphics Gems, box-sphere intersection
fltx4 f4Mins = LoadUnalignedSIMD( &boxMin.x );
fltx4 f4Maxs = LoadUnalignedSIMD( &boxMax.x );
fltx4 f4MinDelta = SubSIMD( f4Mins, f4Center );
fltx4 f4MaxDelta = SubSIMD( f4Center, f4Maxs );
f4MinDelta = MaxSIMD( f4MinDelta, Four_Zeros );
f4MaxDelta = MaxSIMD( f4MaxDelta, Four_Zeros );
fltx4 f4Delta = AddSIMD( f4MinDelta, f4MaxDelta );
fltx4 f4DistSq = Dot3SIMD( f4Delta, f4Delta );
return IsAllGreaterThan( f4RadiusSq, f4DistSq );
}
//-----------------------------------------------------------------------------
// returns true if there's an intersection between ray and sphere
//-----------------------------------------------------------------------------
bool IsRayIntersectingSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta,
const Vector &vecSphereCenter, float flRadius, float flTolerance = 0.0f );
//-----------------------------------------------------------------------------
//
// IsCircleIntersectingRectangle
//
// returns true if there's an intersection between rectangle and circle
//
//-----------------------------------------------------------------------------
bool IsCircleIntersectingRectangle( const Vector2D& boxMin, const Vector2D& boxMax,
const Vector2D& center, float radius );
//-----------------------------------------------------------------------------
//
// IsBoxIntersectingBox
//
// returns true if there's an intersection between two boxes
//
//-----------------------------------------------------------------------------
bool IsBoxIntersectingBox( const Vector& boxMin1, const Vector& boxMax1,
const Vector& boxMin2, const Vector& boxMax2 );
bool IsBoxIntersectingBoxExtents( const Vector& boxCenter1, const Vector& boxHalfDiagonal1,
const Vector& boxCenter2, const Vector& boxHalfDiagonal2 );
#ifdef _X360
// inline version:
#include "mathlib/ssemath.h"
inline bool IsBoxIntersectingBoxExtents( const fltx4 boxCenter1, const fltx4 boxHalfDiagonal1,
const fltx4 boxCenter2, const fltx4 boxHalfDiagonal2 );
#endif
//-----------------------------------------------------------------------------
//
// IsOBBIntersectingOBB
//
// returns true if there's an intersection between two OBBs
//
//-----------------------------------------------------------------------------
bool IsOBBIntersectingOBB( const Vector &vecOrigin1, const QAngle &vecAngles1, const Vector& boxMin1, const Vector& boxMax1,
const Vector &vecOrigin2, const QAngle &vecAngles2, const Vector& boxMin2, const Vector& boxMax2, float flTolerance = 0.0f );
//-----------------------------------------------------------------------------
//
// IsBoxIntersectingRay
//
// 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& delta, float flTolerance = 0.0f );
bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax,
const Ray_t& ray, float flTolerance );
bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax,
const Vector& origin, const Vector& delta,
const Vector& invDelta, float flTolerance = 0.0f );
// On the PC, we can't pass fltx4's in registers like this. On the x360, it is
// much better if we do.
#if defined( _X360 ) || defined( _PS3 )
bool FASTCALL IsBoxIntersectingRay( fltx4 boxMin, fltx4 boxMax,
fltx4 origin, fltx4 delta, fltx4 invDelta, // ray parameters
fltx4 vTolerance = LoadZeroSIMD() ///< eg from ReplicateX4(flTolerance)
);
#else
bool FASTCALL IsBoxIntersectingRay( const fltx4 &boxMin, const fltx4 &boxMax,
const fltx4 & origin, const fltx4 & delta, const fltx4 & invDelta, // ray parameters
const fltx4 & vTolerance = Four_Zeros ///< eg from ReplicateX4(flTolerance)
);
#endif
bool inline FASTCALL IsBoxIntersectingRay( const fltx4& boxMin, const fltx4& boxMax,
const fltx4& origin, const fltx4& delta, float flTolerance = 0.0f )
{
return IsBoxIntersectingRay( boxMin, boxMax, origin, delta, ReciprocalSIMD(delta), ReplicateX4(flTolerance) );
}
#if defined( _X360 ) || defined( _PS3 )
bool FASTCALL IsBoxIntersectingRay( fltx4 boxMin, fltx4 boxMax,
const Ray_t& ray, fltx4 fl4Tolerance = LoadZeroSIMD() );
#else
bool FASTCALL IsBoxIntersectingRay( const fltx4& boxMin, const fltx4& boxMax,
const Ray_t& ray, const fltx4 &fl4Tolerance = LoadZeroSIMD() );
#endif
FORCEINLINE bool IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax, const Ray_t& ray )
{
return IsBoxIntersectingRay( LoadUnaligned3SIMD(boxMin.Base()), LoadUnaligned3SIMD(boxMax.Base()), ray, LoadZeroSIMD() );
}
//-----------------------------------------------------------------------------
//
// IsPointInBox
//
// returns true if the point is in the box
//
//-----------------------------------------------------------------------------
bool IsPointInBox( const Vector& pt, const Vector& boxMin, const Vector& boxMax );
// SIMD version
FORCEINLINE bool IsPointInBox( const fltx4& pt, const fltx4& boxMin, const fltx4& boxMax )
{
bi32x4 greater = CmpGtSIMD( pt,boxMax );
bi32x4 less = CmpLtSIMD( pt, boxMin );
return (IsAllZeros(SetWToZeroSIMD(OrSIMD(greater,less))));
}
//-----------------------------------------------------------------------------
// Purpose: returns true if pt intersects the truncated cone
// origin - cone tip, axis unit cone axis, cosAngle - cosine of cone axis to surface angle
//-----------------------------------------------------------------------------
bool IsPointInCone( const Vector &pt, const Vector &origin, const Vector &axis, float cosAngle, float length );
//-----------------------------------------------------------------------------
// Intersects a plane with a triangle (using barycentric definition)
// The return value, in pIntersection, is an array of barycentric coordinates
// describing at most 2 intersection points.
// The return value is the number of intersection points
//-----------------------------------------------------------------------------
int IntersectTriangleWithPlaneBarycentric( const Vector& org, const Vector& edgeU, const Vector& edgeV,
const Vector4D& plane, Vector2D* pIntersection );
//-----------------------------------------------------------------------------
//
// PointInQuadBarycentric
//
// Given a point and a quad in a plane return the u and v (barycentric) positions
// of the point relative to the quad. The points (v1,v2,v3,v4) should be given
// in a counter-clockwise order with v1 acting as the primary corner (u=0, v=0).
// Thus, u0 = v2 - v1, and v0 = v4 - v1.
//
//-----------------------------------------------------------------------------
enum QuadBarycentricRetval_t
{
BARY_QUADRATIC_FALSE = 0,
BARY_QUADRATIC_TRUE = 1,
BARY_QUADRATIC_NEGATIVE_DISCRIMINANT = 2
};
QuadBarycentricRetval_t PointInQuadToBarycentric( const Vector &v1, const Vector &v2,
const Vector &v3, const Vector &v4, const Vector &point, Vector2D &uv );
void PointInQuadFromBarycentric( const Vector &v1, const Vector &v2, const Vector &v3, const Vector &v4,
const Vector2D &uv, Vector &point );
void TexCoordInQuadFromBarycentric( const Vector2D &v1, const Vector2D &v2, const Vector2D &v3, const Vector2D &v4,
const Vector2D &uv, Vector2D &texCoord );
//-----------------------------------------------------------------------------
// Compute point from barycentric specification
// Edge u goes from v0 to v1, edge v goes from v0 to v2
//-----------------------------------------------------------------------------
void ComputePointFromBarycentric( const Vector& v0, const Vector& v1, const Vector& v2,
float u, float v, Vector& pt );
void ComputePointFromBarycentric( const Vector2D& v0, const Vector2D& v1, const Vector2D& v2,
float u, float v, Vector2D& pt );
//-----------------------------------------------------------------------------
// Swept OBB test
//-----------------------------------------------------------------------------
bool IsRayIntersectingOBB( const Ray_t &ray, const Vector& org, const QAngle& angles,
const Vector& mins, const Vector& maxs );
//-----------------------------------------------------------------------------
// Compute a separating plane between two boxes (expensive!)
// Returns false if no separating plane exists
//-----------------------------------------------------------------------------
bool ComputeSeparatingPlane( const Vector& org1, const QAngle& angles1, const Vector& min1, const Vector& max1,
const Vector& org2, const QAngle& angles2, const Vector& min2, const Vector& max2,
float tolerance, cplane_t* pPlane );
//-----------------------------------------------------------------------------
// IsBoxIntersectingTriangle
//
// Test for an intersection (overlap) between an axial-aligned bounding
// box (AABB) and a triangle.
//
// Triangle points are in counter-clockwise order with the normal facing "out."
//
// Using the "Separating-Axis Theorem" to test for intersections between
// a triangle and an axial-aligned bounding box (AABB).
// 1. 3 Axis Plane Tests - x, y, z
// 2. 9 Edge Planes Tests - the 3 edges of the triangle crossed with all 3 axial
// planes (x, y, z)
// 3. 1 Face Plane Test - the plane the triangle resides in (cplane_t plane)
//-----------------------------------------------------------------------------
bool IsBoxIntersectingTriangle( const Vector &vecBoxCenter, const Vector &vecBoxExtents,
const Vector &v1, const Vector &v2, const Vector &v3,
const cplane_t &plane, float flTolerance );
Vector CalcClosestPointOnTriangle( const Vector &P, const Vector &v0, const Vector &v1, const Vector &v2 );
//-----------------------------------------------------------------------------
// Compute if the OBB intersects the quad plane, and whether the entire
// OBB/Quad intersection is contained within the quad itself
//
// False if no intersection exists, or if part of the intersection is
// outside the quad's extents
//-----------------------------------------------------------------------------
bool OBBHasFullyContainedIntersectionWithQuad( const Vector &vOBBExtent1_Scaled, const Vector &vOBBExtent2_Scaled, const Vector &vOBBExtent3_Scaled, const Vector &ptOBBCenter,
const Vector &vQuadNormal, float fQuadPlaneDist, const Vector &ptQuadCenter,
const Vector &vQuadExtent1_Normalized, float fQuadExtent1Length,
const Vector &vQuadExtent2_Normalized, float fQuadExtent2Length );
//-----------------------------------------------------------------------------
// Compute if the Ray intersects the quad plane, and whether the entire
// Ray/Quad intersection is contained within the quad itself
//
// False if no intersection exists, or if part of the intersection is
// outside the quad's extents
//-----------------------------------------------------------------------------
bool RayHasFullyContainedIntersectionWithQuad( const Ray_t &ray,
const Vector &vQuadNormal, float fQuadPlaneDist, const Vector &ptQuadCenter,
const Vector &vQuadExtent1_Normalized, float fQuadExtent1Length,
const Vector &vQuadExtent2_Normalized, float fQuadExtent2Length );
//-----------------------------------------------------------------------------
// Compute the intersection of a line and a circle
//-----------------------------------------------------------------------------
bool LineCircleIntersection(const Vector2D &center,
const float radius,
const Vector2D &vLinePt,
const Vector2D &vLineDir,
float *fIntersection1,
float *fIntersection2);
//-----------------------------------------------------------------------------
// Find the intersection of a ray with an axis-aligned cylinder
//-----------------------------------------------------------------------------
bool IntersectRayWithAACylinder( const Ray_t &ray,
const Vector &center,
float radius,
float height,
CBaseTrace *pTrace );
//-----------------------------------------------------------------------------
// INLINES
//-----------------------------------------------------------------------------
#ifdef _X360
inline bool IsBoxIntersectingBoxExtents( const fltx4 boxCenter1, const fltx4 boxHalfDiagonal1,
const fltx4 boxCenter2, const fltx4 boxHalfDiagonal2 )
{
fltx4 vecDelta, vecSize;
vecDelta = SubSIMD(boxCenter1, boxCenter2);
vecSize = AddSIMD(boxHalfDiagonal1, boxHalfDiagonal2);
uint condition;
XMVectorInBoundsR(&condition, vecDelta, vecSize);
// we want the top three words to be all 1's ; that means in bounds
return XMComparisonAllInBounds( condition );
}
#endif
#endif // COLLISIONUTILS_H

124
public/color.h Normal file
View File

@@ -0,0 +1,124 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef COLOR_H
#define COLOR_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/basetypes.h"
//-----------------------------------------------------------------------------
// Purpose: Basic handler for an rgb set of colors
// This class is fully inline
//-----------------------------------------------------------------------------
class Color
{
public:
// constructors
Color()
{
*((int *)this) = 0;
}
Color(int _r,int _g,int _b)
{
SetColor(_r, _g, _b, 0);
}
Color(int _r,int _g,int _b,int _a)
{
SetColor(_r, _g, _b, _a);
}
// set the color
// r - red component (0-255)
// g - green component (0-255)
// b - blue component (0-255)
// a - alpha component, controls transparency (0 - transparent, 255 - opaque);
void SetColor(int _r, int _g, int _b, int _a = 0)
{
_color[0] = (unsigned char)_r;
_color[1] = (unsigned char)_g;
_color[2] = (unsigned char)_b;
_color[3] = (unsigned char)_a;
}
void GetColor(int &_r, int &_g, int &_b, int &_a) const
{
_r = _color[0];
_g = _color[1];
_b = _color[2];
_a = _color[3];
}
void SetRawColor( int color32 )
{
*((int *)this) = color32;
}
int GetRawColor() const
{
return *((int *)this);
}
inline int r() const { return _color[0]; }
inline int g() const { return _color[1]; }
inline int b() const { return _color[2]; }
inline int a() const { return _color[3]; }
unsigned char &operator[](int index)
{
return _color[index];
}
const unsigned char &operator[](int index) const
{
return _color[index];
}
bool operator == (const Color &rhs) const
{
return ( *((int *)this) == *((int *)&rhs) );
}
bool operator != (const Color &rhs) const
{
return !(operator==(rhs));
}
Color &operator=( const Color &rhs )
{
SetRawColor( rhs.GetRawColor() );
return *this;
}
Color &operator=( const color32 &rhs )
{
_color[0] = rhs.r;
_color[1] = rhs.g;
_color[2] = rhs.b;
_color[3] = rhs.a;
return *this;
}
color32 ToColor32() const
{
color32 newColor;
newColor.r = _color[0];
newColor.g = _color[1];
newColor.b = _color[2];
newColor.a = _color[3];
return newColor;
}
private:
unsigned char _color[4];
};
#endif // COLOR_H

31
public/con_nprint.h Normal file
View File

@@ -0,0 +1,31 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Debug overlay / notfication printing
//
//=============================================================================//
#ifndef CON_NPRINT_H
#define CON_NPRINT_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose: Debug overlay / notfication printing
// NOTE: Structure cannot be changed by mods
//-----------------------------------------------------------------------------
typedef struct con_nprint_s
{
int index; // Row #
float time_to_live; // # of seconds before it disappears. -1 means to display for 1 frame then go away.
float color[ 3 ]; // RGB colors ( 0.0 -> 1.0 scale )
bool fixed_width_font;
} con_nprint_t;
// Print string on line idx
void Con_NPrintf( int idx, PRINTF_FORMAT_STRING const char *fmt, ... );
// Customized printout
void Con_NXPrintf( const con_nprint_t *info, PRINTF_FORMAT_STRING const char *fmt, ... );
#endif // CON_NPRINT_H

469
public/const.h Normal file
View File

@@ -0,0 +1,469 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef CONST_H
#define CONST_H
#ifdef _WIN32
#pragma once
#endif
// the command line param that tells the engine to use steam
#define STEAM_PARM "-steam"
// the command line param to tell dedicated server to restart
// if they are out of date
#define AUTO_RESTART "-autoupdate"
// the message a server sends when a clients steam login is expired
#define INVALID_STEAM_TICKET "Invalid STEAM UserID Ticket\n"
#define INVALID_STEAM_LOGON "No Steam logon\n"
#define INVALID_STEAM_VACBANSTATE "VAC banned from secure server\n"
#define INVALID_STEAM_LOGGED_IN_ELSEWHERE "This Steam account is being used in another location\n"
#define DEFAULT_TICK_INTERVAL_X360 (1.0 / 29.970030) // This matches x360 refresh, but is not critical
#define DEFAULT_TICK_INTERVAL_PS3 (1.0 / 30.0)
#define DEFAULT_TICK_INTERVAL_PC (1.0 / 64.0)
// This is the default, see shareddefs.h for mod-specific value, which can override this
#if defined( _X360 )
#define DEFAULT_TICK_INTERVAL DEFAULT_TICK_INTERVAL_X360
#elif defined( _PS3 )
#define DEFAULT_TICK_INTERVAL DEFAULT_TICK_INTERVAL_PS3
#else
#define DEFAULT_TICK_INTERVAL DEFAULT_TICK_INTERVAL_PC
#endif
#define MINIMUM_TICK_INTERVAL (4.0f / 512.0f) // 128 fps
#define MAXIMUM_TICK_INTERVAL (25.0f / 512.0f) // 20.48 fps
// This is the max # of players the engine can handle
// Note, must be power of 2
#define ABSOLUTE_PLAYER_LIMIT 255
#define ABSOLUTE_PLAYER_LIMIT_DW ( (ABSOLUTE_PLAYER_LIMIT/32) + 1 )
#if ABSOLUTE_PLAYER_LIMIT > 32
#define CPlayerBitVec CBitVec<ABSOLUTE_PLAYER_LIMIT>
#else
#define CPlayerBitVec CDWordBitVec
#endif
// a player name may have 31 chars + 0 on the PC.
// the 360 only allows 15 char + 0, but stick with the larger PC size for cross-platform communication
#define MAX_PLAYER_NAME_LENGTH 128
#ifdef _X360
#define MAX_PLAYERS_PER_CLIENT XUSER_MAX_COUNT // Xbox 360 supports 4 players per console
#else
#define MAX_PLAYERS_PER_CLIENT 1 // One player per PC
#endif
#define MAX_MAP_NAME 64
#define MAX_NETWORKID_LENGTH 64 // num chars for a network (i.e steam) ID
// BUGBUG: Reconcile with or derive this from the engine's internal definition!
// FIXME: Somebody added an extra bit because they needed to make it signed, not sure why?
// Anyways must have this value in sync(+1) with qlimits.h and effect_dispatch_data.cpp
#define SP_MODEL_INDEX_BITS 13
// How many bits to use to encode an edict.
#define MAX_EDICT_BITS 11 // # of bits needed to represent max edicts
// Max # of edicts in a level
#define MAX_EDICTS (1<<MAX_EDICT_BITS)
// How many bits to use to encode an server class index
#define MAX_SERVER_CLASS_BITS 9
// Max # of networkable server classes
#define MAX_SERVER_CLASSES (1<<MAX_SERVER_CLASS_BITS)
#define SIGNED_GUID_LEN 32 // Hashed CD Key (32 hex alphabetic chars + 0 terminator )
// Used for networking ehandles.
#define NUM_ENT_ENTRY_BITS (MAX_EDICT_BITS + 2)
#define NUM_ENT_ENTRIES (1 << NUM_ENT_ENTRY_BITS)
#define INVALID_EHANDLE_INDEX 0xFFFFFFFF
#define NUM_SERIAL_NUM_BITS 16 // (32 - NUM_ENT_ENTRY_BITS)
#define NUM_SERIAL_NUM_SHIFT_BITS (32 - NUM_SERIAL_NUM_BITS)
#define ENT_ENTRY_MASK (( 1 << NUM_SERIAL_NUM_BITS) - 1)
// Networked ehandles use less bits to encode the serial number.
#define NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS 10
#define NUM_NETWORKED_EHANDLE_BITS (MAX_EDICT_BITS + NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS)
#define INVALID_NETWORKED_EHANDLE_VALUE ((1 << NUM_NETWORKED_EHANDLE_BITS) - 1)
// This is the maximum amount of data a PackedEntity can have. Having a limit allows us
// to use static arrays sometimes instead of allocating memory all over the place.
#define MAX_PACKEDENTITY_DATA (16384)
// This is the maximum number of properties that can be delta'd. Must be evenly divisible by 8.
#define MAX_PACKEDENTITY_PROPS (4096)
// a client can have up to 4 customization files (logo, sounds, models, txt).
#define MAX_CUSTOM_FILES 4 // max 4 files
#define MAX_CUSTOM_FILE_SIZE 524288 // Half a megabyte
//
// Constants shared by the engine and dlls
// This header file included by engine files and DLL files.
// Most came from server.h
// CBaseEntity::m_fFlags
// PLAYER SPECIFIC FLAGS FIRST BECAUSE WE USE ONLY A FEW BITS OF NETWORK PRECISION
#define FL_ONGROUND (1<<0) // At rest / on the ground
#define FL_DUCKING (1<<1) // Player flag -- Player is fully crouched
#define FL_ANIMDUCKING (1<<2) // Player flag -- Player is in the process of crouching or uncrouching but could be in transition
// examples: Fully ducked: FL_DUCKING & FL_ANIMDUCKING
// Previously fully ducked, unducking in progress: FL_DUCKING & !FL_ANIMDUCKING
// Fully unducked: !FL_DUCKING & !FL_ANIMDUCKING
// Previously fully unducked, ducking in progress: !FL_DUCKING & FL_ANIMDUCKING
#define FL_WATERJUMP (1<<3) // player jumping out of water
#define FL_ONTRAIN (1<<4) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
#define FL_INRAIN (1<<5) // Indicates the entity is standing in rain
#define FL_FROZEN (1<<6) // Player is frozen for 3rd person camera
#define FL_ATCONTROLS (1<<7) // Player can't move, but keeps key inputs for controlling another entity
#define FL_CLIENT (1<<8) // Is a player
#define FL_FAKECLIENT (1<<9) // Fake client, simulated server side; don't send network messages to them
// NON-PLAYER SPECIFIC (i.e., not used by GameMovement or the client .dll ) -- Can still be applied to players, though
#define FL_INWATER (1<<10) // In water
// NOTE if you move things up, make sure to change this value
#define PLAYER_FLAG_BITS 11
#define FL_FLY (1<<11) // Changes the SV_Movestep() behavior to not need to be on ground
#define FL_SWIM (1<<12) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
#define FL_CONVEYOR (1<<13)
#define FL_NPC (1<<14)
#define FL_GODMODE (1<<15)
#define FL_NOTARGET (1<<16)
#define FL_AIMTARGET (1<<17) // set if the crosshair needs to aim onto the entity
#define FL_PARTIALGROUND (1<<18) // not all corners are valid
#define FL_STATICPROP (1<<19) // Eetsa static prop!
#ifdef PORTAL2
#define FL_AFFECTED_BY_PAINT (1<<20)
#else
#define FL_GRAPHED (1<<20) // worldgraph has this ent listed as something that blocks a connection
#endif
#define FL_GRENADE (1<<21)
#define FL_STEPMOVEMENT (1<<22) // Changes the SV_Movestep() behavior to not do any processing
#define FL_DONTTOUCH (1<<23) // Doesn't generate touch functions, generates Untouch() for anything it was touching when this flag was set
#define FL_BASEVELOCITY (1<<24) // Base velocity has been applied this frame (used to convert base velocity into momentum)
#define FL_WORLDBRUSH (1<<25) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
#define FL_OBJECT (1<<26) // Terrible name. This is an object that NPCs should see. Missiles, for example.
#define FL_KILLME (1<<27) // This entity is marked for death -- will be freed by game DLL
#define FL_ONFIRE (1<<28) // You know...
#define FL_DISSOLVING (1<<29) // We're dissolving!
#define FL_TRANSRAGDOLL (1<<30) // In the process of turning into a client side ragdoll.
#define FL_UNBLOCKABLE_BY_PLAYER (1<<31) // pusher that can't be blocked by the player
// FIXME[HPE]: this won't actually work - we're out of bits. :(
#ifdef PORTAL2
#define FL_UNPAINTABLE (1<<32) // Unpaintable entities!
#else
#define FL_FREEZING (1<<32) // We're becoming frozen!
#endif
// edict->movetype values
enum MoveType_t
{
MOVETYPE_NONE = 0, // never moves
MOVETYPE_ISOMETRIC, // For players -- in TF2 commander view, etc.
MOVETYPE_WALK, // Player only - moving on the ground
MOVETYPE_STEP, // gravity, special edge handling -- monsters use this
MOVETYPE_FLY, // No gravity, but still collides with stuff
MOVETYPE_FLYGRAVITY, // flies through the air + is affected by gravity
MOVETYPE_VPHYSICS, // uses VPHYSICS for simulation
MOVETYPE_PUSH, // no clip to world, push and crush
MOVETYPE_NOCLIP, // No gravity, no collisions, still do velocity/avelocity
MOVETYPE_LADDER, // Used by players only when going onto a ladder
MOVETYPE_OBSERVER, // Observer movement, depends on player's observer mode
MOVETYPE_CUSTOM, // Allows the entity to describe its own physics
// should always be defined as the last item in the list
MOVETYPE_LAST = MOVETYPE_CUSTOM,
MOVETYPE_MAX_BITS = 4
};
// edict->movecollide values
enum MoveCollide_t
{
MOVECOLLIDE_DEFAULT = 0,
// These ones only work for MOVETYPE_FLY + MOVETYPE_FLYGRAVITY
MOVECOLLIDE_FLY_BOUNCE, // bounces, reflects, based on elasticity of surface and object - applies friction (adjust velocity)
MOVECOLLIDE_FLY_CUSTOM, // Touch() will modify the velocity however it likes
MOVECOLLIDE_FLY_SLIDE, // slides along surfaces (no bounce) - applies friciton (adjusts velocity)
MOVECOLLIDE_COUNT, // Number of different movecollides
// When adding new movecollide types, make sure this is correct
MOVECOLLIDE_MAX_BITS = 3
};
// edict->solid values
// NOTE: Some movetypes will cause collisions independent of SOLID_NOT/SOLID_TRIGGER when the entity moves
// SOLID only effects OTHER entities colliding with this one when they move - UGH!
// Solid type basically describes how the bounding volume of the object is represented
// NOTE: SOLID_BBOX MUST BE 2, and SOLID_VPHYSICS MUST BE 6
// NOTE: These numerical values are used in the FGD by the prop code (see prop_dynamic)
enum SolidType_t
{
SOLID_NONE = 0, // no solid model
SOLID_BSP = 1, // a BSP tree
SOLID_BBOX = 2, // an AABB
SOLID_OBB = 3, // an OBB (not implemented yet)
SOLID_OBB_YAW = 4, // an OBB, constrained so that it can only yaw
SOLID_CUSTOM = 5, // Always call into the entity for tests
SOLID_VPHYSICS = 6, // solid vphysics object, get vcollide from the model and collide with that
SOLID_LAST,
};
enum SolidFlags_t
{
FSOLID_CUSTOMRAYTEST = 0x0001, // Ignore solid type + always call into the entity for ray tests
FSOLID_CUSTOMBOXTEST = 0x0002, // Ignore solid type + always call into the entity for swept box tests
FSOLID_NOT_SOLID = 0x0004, // Are we currently not solid?
FSOLID_TRIGGER = 0x0008, // This is something may be collideable but fires touch functions
// even when it's not collideable (when the FSOLID_NOT_SOLID flag is set)
FSOLID_NOT_STANDABLE = 0x0010, // You can't stand on this
FSOLID_VOLUME_CONTENTS = 0x0020, // Contains volumetric contents (like water)
FSOLID_FORCE_WORLD_ALIGNED = 0x0040, // Forces the collision rep to be world-aligned even if it's SOLID_BSP or SOLID_VPHYSICS
FSOLID_USE_TRIGGER_BOUNDS = 0x0080, // Uses a special trigger bounds separate from the normal OBB
FSOLID_ROOT_PARENT_ALIGNED = 0x0100, // Collisions are defined in root parent's local coordinate space
FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200, // This trigger will touch debris objects
FSOLID_TRIGGER_TOUCH_PLAYER = 0x0400, // This trigger will touch only players
FSOLID_NOT_MOVEABLE = 0x0800, // Assume this object will not move
FSOLID_MAX_BITS = 12
};
//-----------------------------------------------------------------------------
// A couple of inline helper methods
//-----------------------------------------------------------------------------
inline bool IsSolid( SolidType_t solidType, int nSolidFlags )
{
return (solidType != SOLID_NONE) && ((nSolidFlags & FSOLID_NOT_SOLID) == 0);
}
// m_lifeState values
#define LIFE_ALIVE 0 // alive
#define LIFE_DYING 1 // playing death animation or still falling off of a ledge waiting to hit ground
#define LIFE_DEAD 2 // dead. lying still.
#define LIFE_RESPAWNABLE 3
#define LIFE_DISCARDBODY 4
// entity effects
enum
{
EF_BONEMERGE = 0x001, // Performs bone merge on client side
EF_BRIGHTLIGHT = 0x002, // DLIGHT centered at entity origin
EF_DIMLIGHT = 0x004, // player flashlight
EF_NOINTERP = 0x008, // don't interpolate the next frame
EF_NOSHADOW = 0x010, // Don't cast no shadow
EF_NODRAW = 0x020, // don't draw entity
EF_NORECEIVESHADOW = 0x040, // Don't receive no shadow
EF_BONEMERGE_FASTCULL = 0x080, // For use with EF_BONEMERGE. If this is set, then it places this ent's origin at its
// parent and uses the parent's bbox + the max extents of the aiment.
// Otherwise, it sets up the parent's bones every frame to figure out where to place
// the aiment, which is inefficient because it'll setup the parent's bones even if
// the parent is not in the PVS.
EF_ITEM_BLINK = 0x100, // blink an item so that the user notices it.
EF_PARENT_ANIMATES = 0x200, // always assume that the parent entity is animating
EF_MARKED_FOR_FAST_REFLECTION = 0x400, // marks an entity for reflection rendering when using $reflectonlymarkedentities material variable
EF_NOSHADOWDEPTH = 0x800, // Indicates this entity does not render into any shadow depthmap
EF_SHADOWDEPTH_NOCACHE = 0x1000, // Indicates this entity cannot be cached in shadow depthmap and should render every frame
EF_NOFLASHLIGHT = 0x2000,
EF_NOCSM = 0x4000, // Indicates this entity does not render into the cascade shadow depthmap
EF_MAX_BITS = 15
};
#define EF_PARITY_BITS 3
#define EF_PARITY_MASK ((1<<EF_PARITY_BITS)-1)
// How many bits does the muzzle flash parity thing get?
#define EF_MUZZLEFLASH_BITS 2
// plats
#define PLAT_LOW_TRIGGER 1
// Trains
#define SF_TRAIN_WAIT_RETRIGGER 1
#define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains
// view angle update types for CPlayerState::fixangle
#define FIXANGLE_NONE 0
#define FIXANGLE_ABSOLUTE 1
#define FIXANGLE_RELATIVE 2
// Break Model Defines
#define BREAK_GLASS 0x01
#define BREAK_METAL 0x02
#define BREAK_FLESH 0x04
#define BREAK_WOOD 0x08
#define BREAK_SMOKE 0x10
#define BREAK_TRANS 0x20
#define BREAK_CONCRETE 0x40
// If this is set, then we share a lighting origin with the last non-slave breakable sent down to the client
#define BREAK_SLAVE 0x80
// Colliding temp entity sounds
#define BOUNCE_GLASS BREAK_GLASS
#define BOUNCE_METAL BREAK_METAL
#define BOUNCE_FLESH BREAK_FLESH
#define BOUNCE_WOOD BREAK_WOOD
#define BOUNCE_SHRAP 0x10
#define BOUNCE_SHELL 0x20
#define BOUNCE_CONCRETE BREAK_CONCRETE
#define BOUNCE_SHOTSHELL 0x80
// Temp entity bounce sound types
#define TE_BOUNCE_NULL 0
#define TE_BOUNCE_SHELL 1
#define TE_BOUNCE_SHOTSHELL 2
// Rendering constants
// if this is changed, update common/MaterialSystem/Sprite.cpp
enum RenderMode_t
{
kRenderNormal = 0, // src
kRenderTransColor, // c*a+dest*(1-a)
kRenderTransTexture, // src*a+dest*(1-a)
kRenderGlow, // src*a+dest -- No Z buffer checks -- Fixed size in screen space
kRenderTransAlpha, // src*srca+dest*(1-srca)
kRenderTransAdd, // src*a+dest
kRenderEnvironmental, // not drawn, used for environmental effects
kRenderTransAddFrameBlend, // use a fractional frame value to blend between animation frames
kRenderTransAlphaAdd, // src + dest*(1-a)
kRenderWorldGlow, // Same as kRenderGlow but not fixed size in screen space
kRenderNone, // Don't render.
kRenderModeCount, // must be last
};
enum RenderFx_t
{
kRenderFxNone = 0,
kRenderFxPulseSlow,
kRenderFxPulseFast,
kRenderFxPulseSlowWide,
kRenderFxPulseFastWide,
kRenderFxFadeSlow,
kRenderFxFadeFast,
kRenderFxSolidSlow,
kRenderFxSolidFast,
kRenderFxStrobeSlow,
kRenderFxStrobeFast,
kRenderFxStrobeFaster,
kRenderFxFlickerSlow,
kRenderFxFlickerFast,
kRenderFxNoDissipation,
kRenderFxFadeOut,
kRenderFxFadeIn,
kRenderFxPulseFastWider,
kRenderFxGlowShell, // Glowing Shell
kRenderFxMax
};
enum Collision_Group_t
{
COLLISION_GROUP_NONE = 0,
COLLISION_GROUP_DEBRIS, // Collides with nothing but world and static stuff
COLLISION_GROUP_DEBRIS_TRIGGER, // Same as debris, but hits triggers
COLLISION_GROUP_INTERACTIVE_DEBRIS, // Collides with everything except other interactive debris or debris
COLLISION_GROUP_INTERACTIVE, // Collides with everything except interactive debris or debris
COLLISION_GROUP_PLAYER,
COLLISION_GROUP_BREAKABLE_GLASS,
COLLISION_GROUP_VEHICLE,
COLLISION_GROUP_PLAYER_MOVEMENT, // For HL2, same as Collision_Group_Player, for
// TF2, this filters out other players and CBaseObjects
COLLISION_GROUP_NPC, // Generic NPC group
COLLISION_GROUP_IN_VEHICLE, // for any entity inside a vehicle
COLLISION_GROUP_WEAPON, // for any weapons that need collision detection
COLLISION_GROUP_VEHICLE_CLIP, // vehicle clip brush to restrict vehicle movement
COLLISION_GROUP_PROJECTILE, // Projectiles!
COLLISION_GROUP_DOOR_BLOCKER, // Blocks entities not permitted to get near moving doors
COLLISION_GROUP_PASSABLE_DOOR, // Doors that the player shouldn't collide with
COLLISION_GROUP_DISSOLVING, // Things that are dissolving are in this group
COLLISION_GROUP_PUSHAWAY, // Nonsolid on client and server, pushaway in player code
COLLISION_GROUP_NPC_ACTOR, // Used so NPCs in scripts ignore the player.
COLLISION_GROUP_NPC_SCRIPTED, // USed for NPCs in scripts that should not collide with each other
COLLISION_GROUP_PZ_CLIP,
#ifdef PORTAL2
COLLISION_GROUP_CAMERA_SOLID, // Solid only to the camera's test trace
COLLISION_GROUP_PLACEMENT_SOLID, // Solid only to the placement tool's test trace
COLLISION_GROUP_PLAYER_HELD, // Held objects that shouldn't collide with players
COLLISION_GROUP_WEIGHTED_CUBE, // Cubes need a collision group that acts roughly like COLLISION_GROUP_NONE but doesn't collide with debris or interactive
#endif // PORTAL2
COLLISION_GROUP_DEBRIS_BLOCK_PROJECTILE, // Only collides with bullets
LAST_SHARED_COLLISION_GROUP
};
#include "basetypes.h"
#define SOUND_NORMAL_CLIP_DIST 1000.0f
// max number of cached build/draw views to support parallel building of World/Renderlists on SPU
#define MAX_CONCURRENT_BUILDVIEWS 10
//-----------------------------------------------------------------------------
// Base light indices to avoid index collision
//-----------------------------------------------------------------------------
enum
{
LIGHT_INDEX_TE_DYNAMIC = 0x10000000,
LIGHT_INDEX_PLAYER_BRIGHT = 0x20000000,
LIGHT_INDEX_MUZZLEFLASH = 0x40000000,
LIGHT_INDEX_LOW_PRIORITY = 0x64000000,
};
// How many networked area portals do we allow?
#define MAX_AREA_STATE_BYTES 32
#define MAX_AREA_PORTAL_STATE_BYTES 24
// user message max payload size (note, this value is used by the engine, so MODs cannot change it)
#define MAX_USER_MSG_BITS 12
#define MAX_USER_MSG_DATA ( ( 1 << ( MAX_USER_MSG_BITS - 3 ) ) - 1 )
#define MAX_ENTITY_MSG_DATA 255
#define SOURCE_MT
#ifdef SOURCE_MT
class CThreadMutex;
typedef CThreadMutex CSourceMutex;
#else
class CThreadNullMutex;
typedef CThreadNullMutex CSourceMutex;
#endif
#if defined( CLIENT_DLL )
#define IsServerDll() false
#define IsClientDll() true
#elif defined( GAME_DLL )
#define IsServerDll() true
#define IsClientDll() false
#else
#define IsServerDll() false
#define IsClientDll() false
#endif
#endif
#define IsValveDedicated() false

99
public/coordsize.h Normal file
View File

@@ -0,0 +1,99 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef COORDSIZE_H
#define COORDSIZE_H
#pragma once
#include "worldsize.h"
// OVERALL Coordinate Size Limits used in COMMON.C MSG_*BitCoord() Routines (and someday the HUD)
#define COORD_INTEGER_BITS 14
#define COORD_FRACTIONAL_BITS 5
#define COORD_DENOMINATOR (1<<(COORD_FRACTIONAL_BITS))
#define COORD_RESOLUTION (1.0/(COORD_DENOMINATOR))
// Special threshold for networking multiplayer origins
#define COORD_INTEGER_BITS_MP 11
#define COORD_FRACTIONAL_BITS_MP_LOWPRECISION 3
#define COORD_DENOMINATOR_LOWPRECISION (1<<(COORD_FRACTIONAL_BITS_MP_LOWPRECISION))
#define COORD_RESOLUTION_LOWPRECISION (1.0/(COORD_DENOMINATOR_LOWPRECISION))
#define NORMAL_FRACTIONAL_BITS 11
#define NORMAL_DENOMINATOR ( (1<<(NORMAL_FRACTIONAL_BITS)) - 1 )
#define NORMAL_RESOLUTION (1.0/(NORMAL_DENOMINATOR))
// this is limited by the network fractional bits used for coords
// because net coords will be only be accurate to 5 bits fractional
// Standard collision test epsilon
// 1/32nd inch collision epsilon
#define DIST_EPSILON (0.03125)
// Verify that coordsize.h and worldsize.h are consistently defined
#if (MAX_COORD_INTEGER != (1<<COORD_INTEGER_BITS) )
#error MAX_COORD_INTEGER does not match COORD_INTEGER_BITS
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////
// The following are Bit Packing Diagrams for client/server Coordinate BitField Messages
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// "Coordinates" = +/-16384.9375 (21 Bits Max)
//
// | IntegerFlagBit:1 | FractionFlagBit:1 | SignBit:1 | IntegerField:14 | FractionPart:4 | Total
// --------------------------------------------------------------------------------------------------
// 0 0 - - - 2
// 0 1 x - xxxx 7
// 1 0 x xxxxxxxxxxxxx - 17
// 1 1 x xxxxxxxxxxxxx xxxx 21
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// "Vec3Coordinate" = Up to 3 Coordinates (66 Bits Max)
//
// | NonZeroX:1 | NonZeroY:1 | NonZeroZ:1 | 0..3 "Coordinates" | BitField Total
// -------------------------------------------------------------------------------
// 0 0 0 - 3
// 0 0 1 7..21 Bits 10..24
// 0 1 0 7..21 Bits 10..24
// 1 0 0 7..21 Bits 10..24
// 0 1 1 14..42 Bits 17..45
// 1 1 0 14..42 Bits 17..45
// 1 0 1 14..42 Bits 17..45
// 1 1 1 21..63 Bits 24..66
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
// The following are Bit Packing Diagrams for client/server Normal BitField Messages
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// "Normals" = +/-1.0 (12 Bits Total)
//
// The only gotcha here is that normalization occurs so that
// 011111111111 = +1.0 and 1111111111111 = -1.0
//
// | SignBit:1 | FractionPart:11 | Total
// --------------------------------------------------------------------------------------------------
// 1 xxxxxxxxxxx 12
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// "Vec3Normal" = Up to 3 Coordinates (27 Bits Max)
//
// | NonZeroX:1 | NonZeroY:1 | 0..2 "Coordinates" | Z Sign Bit | BitField Total
// -------------------------------------------------------------------------------
// 0 0 - x 3
// 0 1 12 Bits x 14
// 1 0 12 Bits x 14
// 1 1 24 Bits x 27
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // COORDSIZE_H

44
public/crtmemdebug.cpp Normal file
View File

@@ -0,0 +1,44 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB)
#include "crtmemdebug.h"
#ifdef USECRTMEMDEBUG
#include <crtdbg.h>
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
void CheckHeap( void )
{
#ifdef USECRTMEMDEBUG
_CrtCheckMemory();
#endif
}
// undone: this needs to be somehow made to construct before everything else.
// see http://msdn.microsoft.com/library/periodic/period97/dembugs.htm for info
void InitCRTMemDebug( void )
{
#ifdef USECRTMEMDEBUG
_CrtSetDbgFlag(
// _CRTDBG_ALLOC_MEM_DF |
_CRTDBG_CHECK_ALWAYS_DF |
_CRTDBG_CHECK_CRT_DF |
_CRTDBG_DELAY_FREE_MEM_DF );
#endif
}
#endif // !_STATIC_LINKED || _SHARED_LIB

33
public/crtmemdebug.h Normal file
View File

@@ -0,0 +1,33 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef CRTMEMDEBUG_H
#define CRTMEMDEBUG_H
#pragma once
#ifdef USECRTMEMDEBUG
#include <crtdbg.h>
#define MEMCHECK CheckHeap()
void CheckHeap( void );
#else
#define MEMCHECK
#endif
void InitCRTMemDebug( void );
#endif // CRTMEMDEBUG_H

View File

@@ -0,0 +1,582 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//===========================================================================//
#ifndef IDATACACHE_H
#define IDATACACHE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "appframework/iappsystem.h"
#include "tier3/tier3.h"
class IDataCache;
//-----------------------------------------------------------------------------
//
// Shared Data Cache API
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Support types and enums
//-----------------------------------------------------------------------------
//---------------------------------------------------------
// Unique (per section) identifier for a cache item defined by client
//---------------------------------------------------------
typedef uintp DataCacheClientID_t;
//---------------------------------------------------------
// Cache-defined handle for a cache item
//---------------------------------------------------------
FORWARD_DECLARE_HANDLE( memhandle_t );
typedef memhandle_t DataCacheHandle_t;
#define DC_INVALID_HANDLE ((DataCacheHandle_t)0)
//---------------------------------------------------------
// Cache Limits
//---------------------------------------------------------
struct DataCacheLimits_t
{
DataCacheLimits_t( unsigned _nMaxBytes = (unsigned)-1, unsigned _nMaxItems = (unsigned)-1, unsigned _nMinBytes = 0, unsigned _nMinItems = 0 )
: nMaxBytes(_nMaxBytes),
nMaxItems(_nMaxItems),
nMinBytes(_nMinBytes),
nMinItems(_nMinItems)
{
}
// Maximum levels permitted
unsigned nMaxBytes;
unsigned nMaxItems;
// Minimum levels permitted
unsigned nMinBytes;
unsigned nMinItems;
};
//---------------------------------------------------------
// Cache status
//---------------------------------------------------------
struct DataCacheStatus_t
{
// Current state of the cache
unsigned nBytes;
unsigned nItems;
unsigned nBytesLocked;
unsigned nItemsLocked;
// Diagnostics
unsigned nFindRequests;
unsigned nFindHits;
};
//---------------------------------------------------------
// Cache options
//---------------------------------------------------------
enum DataCacheOptions_t
{
DC_TRACE_ACTIVITY = (1 << 0),
DC_FORCE_RELOCATE = (1 << 1),
DC_ALWAYS_MISS = (1 << 2),
DC_VALIDATE = (1 << 3),
DC_NO_USER_FORCE_FLUSH = (1 << 4)
};
//---------------------------------------------------------
// Cache report types
//---------------------------------------------------------
enum DataCacheReportType_t
{
DC_SUMMARY_REPORT,
DC_DETAIL_REPORT,
DC_DETAIL_REPORT_LRU,
DC_DETAIL_REPORT_VXCONSOLE,
};
//---------------------------------------------------------
// Notifications to section clients on cache events
//---------------------------------------------------------
enum DataCacheNotificationType_t
{
// Used internally to prohibit notifications
DC_NONE,
// Item is falling off the LRU and should be deleted, return false to block
DC_AGE_DISCARD,
// Item is being explicitly flushed and should be deleted, return false to block
DC_FLUSH_DISCARD,
// Item is being explicitly removed and should be deleted. Failure is not an option
DC_REMOVED,
// Cache is requesting item be relocated for debugging purposes
DC_RELOCATE,
// Item info should be output to console, return false to accept default handling
DC_PRINT_INF0,
};
//-------------------------------------
struct DataCacheNotification_t
{
DataCacheNotificationType_t type;
const char * pszSectionName;
DataCacheClientID_t clientId;
const void * pItemData;
unsigned nItemSize;
};
//---------------------------------------------------------
const int DC_MAX_CLIENT_NAME = 15;
const int DC_MAX_ITEM_NAME = 511;
//---------------------------------------------------------
// Result codes
//---------------------------------------------------------
enum DataCacheRemoveResult_t
{
DC_OK,
DC_NOT_FOUND,
DC_LOCKED,
};
//---------------------------------------------------------
// Add flags
//---------------------------------------------------------
enum DataCacheAddFlags_t
{
DCAF_LOCK = ( 1 << 0 ),
DCAF_DEFAULT = 0,
};
//-----------------------------------------------------------------------------
// IDataCacheSection
//
// Purpose: Implements a sub-section of the global cache. Subsections are
// areas of the cache with thier own memory constraints and common
// management.
//-----------------------------------------------------------------------------
abstract_class IDataCacheSection
{
public:
virtual ~IDataCacheSection() { };
//--------------------------------------------------------
virtual IDataCache *GetSharedCache() = 0;
virtual const char *GetName() = 0;
//--------------------------------------------------------
// Purpose: Controls cache size & options
//--------------------------------------------------------
virtual void SetLimits( const DataCacheLimits_t &limits ) = 0;
virtual void SetOptions( unsigned options ) = 0;
//--------------------------------------------------------
// Purpose: Get the current state of the section
//--------------------------------------------------------
virtual void GetStatus( DataCacheStatus_t *pStatus, DataCacheLimits_t *pLimits = NULL ) = 0;
//--------------------------------------------------------
// Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache.
//--------------------------------------------------------
virtual void EnsureCapacity( unsigned nBytes, unsigned nItems = 1 ) = 0;
//--------------------------------------------------------
// Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache.
//--------------------------------------------------------
virtual bool Add( DataCacheClientID_t clientId, const void *pItemData, unsigned size, DataCacheHandle_t *pHandle ) = 0;
//--------------------------------------------------------
// Purpose: Finds an item in the cache, returns NULL if item is not in cache. Not a cheap operation if section not configured for fast find.
//--------------------------------------------------------
virtual DataCacheHandle_t Find( DataCacheClientID_t clientId ) = 0;
//--------------------------------------------------------
// Purpose: Get an item out of the cache and remove it. No callbacks are executed unless explicity specified.
//--------------------------------------------------------
virtual DataCacheRemoveResult_t Remove( DataCacheHandle_t handle, const void **ppItemData, unsigned *pItemSize = NULL, bool bNotify = false ) = 0;
DataCacheRemoveResult_t Remove( DataCacheHandle_t handle, bool bNotify = false ) { return Remove( handle, NULL, NULL, bNotify ); }
//--------------------------------------------------------
// Purpose: Returns if the data is currently in memory, but does *not* change its location in the LRU
//--------------------------------------------------------
virtual bool IsPresent( DataCacheHandle_t handle ) = 0;
//--------------------------------------------------------
// Purpose: Lock an item in the cache, returns NULL if item is not in the cache.
//--------------------------------------------------------
virtual void *Lock( DataCacheHandle_t handle ) = 0;
//--------------------------------------------------------
// Purpose: Unlock a previous lock.
//--------------------------------------------------------
virtual int Unlock( DataCacheHandle_t handle ) = 0;
//--------------------------------------------------------
// Purpose: Get an item without locking it, returns NULL if item is not in the cache. Use with care!
//--------------------------------------------------------
virtual void *Get( DataCacheHandle_t handle, bool bFrameLock = false ) = 0;
virtual void *GetNoTouch( DataCacheHandle_t handle, bool bFrameLock = false ) = 0;
//--------------------------------------------------------
// Purpose: "Frame locking" (not game frame). A crude way to manage locks over relatively
// short periods. Does not affect normal locks/unlocks
//--------------------------------------------------------
virtual int BeginFrameLocking() = 0;
virtual bool IsFrameLocking() = 0;
virtual void *FrameLock( DataCacheHandle_t handle ) = 0;
virtual int EndFrameLocking() = 0;
virtual int *GetFrameUnlockCounterPtr() = 0;
//--------------------------------------------------------
// Purpose: Lock management, not for the feint of heart
//--------------------------------------------------------
virtual int GetLockCount( DataCacheHandle_t handle ) = 0;
virtual int BreakLock( DataCacheHandle_t handle ) = 0;
//--------------------------------------------------------
// Purpose: Explicitly mark an item as "recently used"
//--------------------------------------------------------
virtual bool Touch( DataCacheHandle_t handle ) = 0;
//--------------------------------------------------------
// Purpose: Explicitly mark an item as "least recently used".
//--------------------------------------------------------
virtual bool Age( DataCacheHandle_t handle ) = 0;
//--------------------------------------------------------
// Purpose: Empty the cache. Returns bytes released, will remove locked items if force specified
//--------------------------------------------------------
virtual unsigned Flush( bool bUnlockedOnly = true, bool bNotify = true ) = 0;
//--------------------------------------------------------
// Purpose: Dump the oldest items to free the specified amount of memory. Returns amount actually freed
//--------------------------------------------------------
virtual unsigned Purge( unsigned nBytes ) = 0;
//--------------------------------------------------------
// Purpose: Output the state of the section
//--------------------------------------------------------
virtual void OutputReport( DataCacheReportType_t reportType = DC_SUMMARY_REPORT ) = 0;
//--------------------------------------------------------
// Purpose: Updates the size used by a specific item (locks the item, kicks
// other items out to make room as necessary, unlocks the item).
//--------------------------------------------------------
virtual void UpdateSize( DataCacheHandle_t handle, unsigned int nNewSize ) = 0;
//--------------------------------------------------------
// Purpose: Access to the mutex. More explicit control during get-then-lock sequences
// to ensure object stays valid during "then"
//--------------------------------------------------------
virtual void LockMutex() = 0;
virtual void UnlockMutex() = 0;
//--------------------------------------------------------
// Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache.
//--------------------------------------------------------
virtual bool AddEx( DataCacheClientID_t clientId, const void *pItemData, unsigned size, unsigned flags, DataCacheHandle_t *pHandle ) = 0;
virtual unsigned int GetOptions() = 0;
// Batch oriented get/lock
virtual void GetAndLockMultiple( void **ppData, int nCount, DataCacheHandle_t *pHandles ) = 0;
};
//-----------------------------------------------------------------------------
// IDataCacheClient
//
// Purpose: Connection between the cache and the owner of a cache section
//
//-----------------------------------------------------------------------------
abstract_class IDataCacheClient
{
public:
virtual ~IDataCacheClient() { };
//--------------------------------------------------------
//
//--------------------------------------------------------
virtual bool HandleCacheNotification( const DataCacheNotification_t &notification ) = 0;
//--------------------------------------------------------
//
//--------------------------------------------------------
virtual bool GetItemName( DataCacheClientID_t clientId, const void *pItem, char *pDest, unsigned nMaxLen ) = 0;
};
//-------------------------------------
class CDefaultDataCacheClient : public IDataCacheClient
{
public:
virtual ~CDefaultDataCacheClient() { };
virtual bool HandleCacheNotification( const DataCacheNotification_t &notification )
{
switch ( notification.type )
{
case DC_AGE_DISCARD:
case DC_FLUSH_DISCARD:
case DC_REMOVED:
default:
Assert ( 0 );
return false;
case DC_NONE:
case DC_RELOCATE:
case DC_PRINT_INF0:
return false;
}
return false;
}
virtual bool GetItemName( DataCacheClientID_t clientId, const void *pItem, char *pDest, unsigned nMaxLen )
{
return false;
}
};
//-----------------------------------------------------------------------------
// IDataCache
//
// Purpose: The global shared cache. Manages sections and overall budgets.
//
//-----------------------------------------------------------------------------
abstract_class IDataCache : public IAppSystem
{
public:
//--------------------------------------------------------
// Purpose: Controls cache size.
//--------------------------------------------------------
virtual void SetSize( int nMaxBytes ) = 0;
virtual void SetOptions( unsigned options ) = 0;
virtual void SetSectionLimits( const char *pszSectionName, const DataCacheLimits_t &limits ) = 0;
//--------------------------------------------------------
// Purpose: Get the current state of the cache
//--------------------------------------------------------
virtual void GetStatus( DataCacheStatus_t *pStatus, DataCacheLimits_t *pLimits = NULL ) = 0;
//--------------------------------------------------------
// Purpose: Add a section to the cache
//--------------------------------------------------------
virtual IDataCacheSection *AddSection( IDataCacheClient *pClient, const char *pszSectionName, const DataCacheLimits_t &limits = DataCacheLimits_t(), bool bSupportFastFind = false ) = 0;
//--------------------------------------------------------
// Purpose: Remove a section from the cache
//--------------------------------------------------------
virtual void RemoveSection( const char *pszClientName, bool bCallFlush = true ) = 0;
void RemoveSection( IDataCacheSection *pSection, bool bCallFlush = true ) { if ( pSection) RemoveSection( pSection->GetName() ); }
//--------------------------------------------------------
// Purpose: Find a section of the cache
//--------------------------------------------------------
virtual IDataCacheSection *FindSection( const char *pszClientName ) = 0;
//--------------------------------------------------------
// Purpose: Dump the oldest items to free the specified amount of memory. Returns amount actually freed
//--------------------------------------------------------
virtual unsigned Purge( unsigned nBytes ) = 0;
//--------------------------------------------------------
// Purpose: Empty the cache. Returns bytes released, will remove locked items if force specified
//--------------------------------------------------------
virtual unsigned Flush( bool bUnlockedOnly = true, bool bNotify = true ) = 0;
//--------------------------------------------------------
// Purpose: Output the state of the cache
//--------------------------------------------------------
virtual void OutputReport( DataCacheReportType_t reportType = DC_SUMMARY_REPORT, const char *pszSection = NULL ) = 0;
virtual int GetSectionCount() = 0;
virtual const char *GetSectionName( int iIndex ) = 0;
};
//-----------------------------------------------------------------------------
// Helper class to support usage pattern similar to CDataManager
//-----------------------------------------------------------------------------
template< class STORAGE_TYPE, class CREATE_PARAMS, class LOCK_TYPE = STORAGE_TYPE * >
class CManagedDataCacheClient : public CDefaultDataCacheClient
{
public:
typedef CManagedDataCacheClient<STORAGE_TYPE, CREATE_PARAMS, LOCK_TYPE> CCacheClientBaseClass;
CManagedDataCacheClient()
: m_pCache( NULL )
{
}
void Init( IDataCache *pSharedCache, const char *pszSectionName, const DataCacheLimits_t &limits = DataCacheLimits_t(), bool bSupportFastFind = false )
{
if ( !m_pCache )
{
m_pCache = pSharedCache->AddSection( this, pszSectionName, limits, bSupportFastFind );
}
}
void Shutdown()
{
if ( m_pCache )
{
m_pCache->GetSharedCache()->RemoveSection( m_pCache );
m_pCache = NULL;
}
}
LOCK_TYPE CacheGet( DataCacheHandle_t handle, bool bFrameLock = true )
{
return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->Get( handle, bFrameLock ))->GetData());
}
void CacheGetAndLockMultiple( LOCK_TYPE *pData, int nCount, DataCacheHandle_t *pHandles )
{
m_pCache->GetAndLockMultiple( (void**)pData, nCount, pHandles );
for ( int i = 0; i < nCount; ++i )
{
STORAGE_TYPE *pTypedData = pData[i];
if ( pTypedData )
{
pData[i] = (LOCK_TYPE)( pTypedData->GetData() );
}
}
}
LOCK_TYPE CacheGetNoTouch( DataCacheHandle_t handle )
{
return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->GetNoTouch( handle ))->GetData());
}
LOCK_TYPE CacheLock( DataCacheHandle_t handle )
{
return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->Lock( handle ))->GetData());
}
int CacheUnlock( DataCacheHandle_t handle )
{
return m_pCache->Unlock( handle );
}
void CacheTouch( DataCacheHandle_t handle )
{
m_pCache->Touch( handle );
}
void CacheRemove( DataCacheHandle_t handle, bool bNotify = true )
{
m_pCache->Remove( handle, bNotify );
}
void CacheFlush()
{
m_pCache->Flush();
}
DataCacheHandle_t CacheCreate( const CREATE_PARAMS &createParams, unsigned flags = DCAF_DEFAULT )
{
m_pCache->EnsureCapacity(STORAGE_TYPE::EstimatedSize(createParams));
STORAGE_TYPE *pStore = STORAGE_TYPE::CreateResource( createParams );
if ( !pStore )
{
return DC_INVALID_HANDLE;
}
DataCacheHandle_t handle;
m_pCache->AddEx( (DataCacheClientID_t)pStore, pStore, pStore->Size(), flags, &handle);
return handle;
}
void CacheLockMutex()
{
m_pCache->LockMutex();
}
void CacheUnlockMutex()
{
m_pCache->UnlockMutex();
}
bool HandleCacheNotification( const DataCacheNotification_t &notification )
{
switch ( notification.type )
{
case DC_AGE_DISCARD:
case DC_FLUSH_DISCARD:
case DC_REMOVED:
{
STORAGE_TYPE *p = (STORAGE_TYPE *)notification.clientId;
p->DestroyResource();
return true;
}
break;
case DC_NONE:
case DC_RELOCATE:
case DC_PRINT_INF0:
break;
}
return CDefaultDataCacheClient::HandleCacheNotification( notification );
}
protected:
~CManagedDataCacheClient()
{
Shutdown();
}
IDataCacheSection *GetCacheSection()
{
return m_pCache;
}
private:
IDataCacheSection *m_pCache;
};
//-----------------------------------------------------------------------------
#endif // IDataCache

View File

@@ -0,0 +1,467 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// model loading and caching
//
//=============================================================================
#ifndef IMDLCACHE_H
#define IMDLCACHE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "appframework/iappsystem.h"
#include "filesystem.h"
#include "string_t.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct studiohdr_t;
struct studiohwdata_t;
struct vcollide_t;
struct virtualmodel_t;
struct vertexFileHeader_t;
class KeyValues;
class IDataCacheSection;
class IVTFTexture;
namespace OptimizedModel
{
struct FileHeader_t;
}
//-----------------------------------------------------------------------------
// Reference to a loaded studiomdl
//-----------------------------------------------------------------------------
typedef unsigned short MDLHandle_t;
inline MDLHandle_t VoidPtrToMDLHandle( void *ptr )
{
return ( MDLHandle_t ) ( int ) ( intp ) ptr;
}
inline void* MDLHandleToVirtual( MDLHandle_t hndl )
{
return (void*)(uintp)hndl;
}
enum
{
MDLHANDLE_INVALID = (MDLHandle_t)~0
};
//-----------------------------------------------------------------------------
// Cache data types
//-----------------------------------------------------------------------------
enum MDLCacheDataType_t
{
MDLCACHE_NONE = -1,
// Callbacks to get called when data is loaded or unloaded for these:
MDLCACHE_STUDIOHDR = 0,
MDLCACHE_STUDIOHWDATA,
MDLCACHE_VCOLLIDE,
// Callbacks NOT called when data is loaded or unloaded for these:
MDLCACHE_ANIMBLOCK,
MDLCACHE_VIRTUALMODEL,
MDLCACHE_VERTEXES,
MDLCACHE_DECODEDANIMBLOCK
};
abstract_class IMDLCacheNotify
{
public:
virtual ~IMDLCacheNotify() { };
// Called right after the data is loaded
virtual void OnDataLoaded( MDLCacheDataType_t type, MDLHandle_t handle ) = 0;
// Called right before combiner process data into cache
virtual void OnCombinerPreCache( MDLHandle_t OldHandle, MDLHandle_t NewHandle ) = 0;
// Called right before the data is unloaded
virtual void OnDataUnloaded( MDLCacheDataType_t type, MDLHandle_t handle ) = 0;
virtual bool ShouldSupressLoadWarning( MDLHandle_t handle ) = 0;
};
//-----------------------------------------------------------------------------
// Flags for flushing
//-----------------------------------------------------------------------------
enum MDLCacheFlush_t
{
MDLCACHE_FLUSH_STUDIOHDR = 0x01,
MDLCACHE_FLUSH_STUDIOHWDATA = 0x02,
MDLCACHE_FLUSH_VCOLLIDE = 0x04,
MDLCACHE_FLUSH_ANIMBLOCK = 0x08,
MDLCACHE_FLUSH_VIRTUALMODEL = 0x10,
MDLCACHE_FLUSH_AUTOPLAY = 0x20,
MDLCACHE_FLUSH_VERTEXES = 0x40,
MDLCACHE_FLUSH_COMBINED_DATA = 0x80,
MDLCACHE_FLUSH_IGNORELOCK = 0x80000000,
MDLCACHE_FLUSH_ALL = 0xFFFFFFFF
};
//-----------------------------------------------------------------------------
// Combiner
//-----------------------------------------------------------------------------
#define COMBINER_MAX_MODELS 15
#define COMBINER_MAX_LODS 8
#define COMBINER_MAX_TEXTURES_PER_MATERIAL 5
#define COMBINER_MAX_ATLAS_GROUPS 5
#define COMBINER_MAX_MATERIALS_PER_INPUT_MODEL 4
enum ECombinedResult
{
COMBINE_RESULT_FLAG_OK = 0,
COMBINE_RESULT_FLAG_TOO_MANY_STRINGS,
COMBINE_RESULT_FLAG_OUT_OF_MEMORY,
COMBINE_RESULT_FLAG_TOO_MANY_BONES,
COMBINE_RESULT_FLAG_UNSUPPORTED_FEATURE, // Major feature of the formats that isn't supported. You'll need to debug the specific cause of this.
COMBINE_RESULT_FLAG_UNHANDLED_ISSUE, // Minor section of the formats that wasn't expected. You'll need to debug the specific cause of this.
COMBINE_RESULT_FLAG_MISSING_ASSET_FILE,
COMBINE_RESULT_FLAG_UNSUPPORTED_SHADER,
COMBINE_RESULT_FLAG_FAILED_GOOD_PRACTICE, // Not necessarily an error, but sanity checks to make sure we are doing good practices
COMBINE_RESULT_FLAG_KEY_VALUE_FAILURE,
};
enum EDetailedError
{
COMBINED_DETAIL_ERROR_NOT_SPECIFIED = 0,
COMBINED_DETAIL_ERROR_TEXTURE_PACKER_NO_SPACE,
COMBINED_DETAIL_ERROR_MODEL_PACKER_TOO_MANY_MATERIALS,
COMBINED_DETAIL_ERROR_TEXTURE_COORDINATES_WRAP,
COMBINED_DETAIL_ERROR_MODEL_LOWER_LOD_HIGHER_TRI_COUNT,
};
typedef struct SCombinedResults
{
// individual model info
int m_nNumVerts[ COMBINER_MAX_MODELS ][ COMBINER_MAX_LODS ];
int m_nNumIndexes[ COMBINER_MAX_MODELS ][ COMBINER_MAX_LODS ];
int m_nBatches[ COMBINER_MAX_MODELS ][ COMBINER_MAX_LODS ];
int m_nNumLODs[ COMBINER_MAX_MODELS ];
// cumulative combined info
int m_nCombinedNumVerts[ COMBINER_MAX_LODS ];
int m_nCombinedNumIndexes[ COMBINER_MAX_LODS ];
int m_nCombinedBatches[ COMBINER_MAX_LODS ];
int m_nCombinedNumLODs;
int m_nNumTexturePackIterations;
unsigned int m_nCombinedResults;
char m_szErrorMessage[ 256 ];
char m_szErrorDetails[ 4096 ];
unsigned int m_nDetailedError;
float m_flModelLoadDuration;
float m_flModelCombineDuration;
float m_flTextureLoadDuration;
float m_flTextureCombineDuration;
float m_flEngineProcessingDuration;
} TCombinedResults;
enum ECombinedAsset
{
COMBINED_ASSET_MATERIAL = 0,
COMBINED_ASSET_TEXTURE,
COMBINED_ASSET_MAX
};
enum ECombinerFlags
{
COMBINER_FLAG_THREADING = 0x00000001,
COMBINER_FLAG_NO_DATA_PROCESSING = 0x00000002,
};
struct STextureSubstitute_t
{
STextureSubstitute_t()
: m_iszMaterialParam( NULL_STRING )
, m_pVTFTexture( NULL )
{
}
string_t m_iszMaterialParam;
IVTFTexture *m_pVTFTexture;
};
struct SCombinerModelInput_t
{
SCombinerModelInput_t()
: m_iszModelName( NULL_STRING )
, m_nSkinFamily( 0 )
, m_nBodyGroupSubModelSelection ( -1 )
{
}
SCombinerModelInput_t( string_t iszModelName, int nSkinFamily = 0, int nBodyGroupSubModelSelection = -1 )
: m_iszModelName( iszModelName )
, m_nSkinFamily( nSkinFamily )
, m_nBodyGroupSubModelSelection( nBodyGroupSubModelSelection )
{
}
string_t m_iszModelName;
int m_nSkinFamily;
int m_nBodyGroupSubModelSelection; // -1 means no selection, include all body part sub models
STextureSubstitute_t m_textureSubstitutes[ COMBINER_MAX_MATERIALS_PER_INPUT_MODEL ][ COMBINER_MAX_TEXTURES_PER_MATERIAL ]; // entries can have NULL contents, it means don't substitute (use the one the mdl says)
};
// Callback for the combining process
// pUserData: the pointer you optionally specified in the FinishedCombinedModel() call
// OldHandle: either the temporary model model returned by CreateCombinedModel() or MDLHANDLE_INVALID if reusing an existing handle
// NewHandle: the combined model handle, which may be your reused model handle specified in CreateCombinedModel()
// CombinedResults: various statistical and timing information about the model and combining process
typedef void (*CombinedModelLoadedCallback)( void *pUserData, MDLHandle_t OldHandle, MDLHandle_t NewHandle, TCombinedResults &CombinedResults );
//-----------------------------------------------------------------------------
// The main MDL cacher
//-----------------------------------------------------------------------------
abstract_class IMDLCache : public IAppSystem
{
public:
// Used to install callbacks for when data is loaded + unloaded
// Returns the prior notify
virtual void SetCacheNotify( IMDLCacheNotify *pNotify ) = 0;
// NOTE: This assumes the "GAME" path if you don't use
// the UNC method of specifying files. This will also increment
// the reference count of the MDL
virtual MDLHandle_t FindMDL( const char *pMDLRelativePath ) = 0;
// Reference counting
virtual int AddRef( MDLHandle_t handle ) = 0;
virtual int Release( MDLHandle_t handle ) = 0;
virtual int GetRef( MDLHandle_t handle ) = 0;
// Gets at the various data associated with a MDL
virtual studiohdr_t *GetStudioHdr( MDLHandle_t handle ) = 0;
virtual studiohwdata_t *GetHardwareData( MDLHandle_t handle ) = 0;
virtual vcollide_t *GetVCollide( MDLHandle_t handle ) = 0;
virtual unsigned char *GetAnimBlock( MDLHandle_t handle, int nBlock, bool preloadIfMissing ) = 0;
virtual bool HasAnimBlockBeenPreloaded( MDLHandle_t handle, int nBlock ) = 0;
virtual virtualmodel_t *GetVirtualModel( MDLHandle_t handle ) = 0;
virtual int GetAutoplayList( MDLHandle_t handle, unsigned short **pOut ) = 0;
virtual vertexFileHeader_t *GetVertexData( MDLHandle_t handle ) = 0;
// Brings all data associated with an MDL into memory
virtual void TouchAllData( MDLHandle_t handle ) = 0;
// Gets/sets user data associated with the MDL
virtual void SetUserData( MDLHandle_t handle, void* pData ) = 0;
virtual void *GetUserData( MDLHandle_t handle ) = 0;
// Is this MDL using the error model?
virtual bool IsErrorModel( MDLHandle_t handle ) = 0;
virtual bool IsOverBudget( MDLHandle_t handle ) = 0;
// Flushes the cache, force a full discard
virtual void Flush( MDLCacheFlush_t nFlushFlags = MDLCACHE_FLUSH_ALL ) = 0;
// Flushes a particular model out of memory
virtual void Flush( MDLHandle_t handle, int nFlushFlags = MDLCACHE_FLUSH_ALL ) = 0;
// Returns the name of the model (its relative path)
virtual const char *GetModelName( MDLHandle_t handle ) = 0;
virtual IDataCacheSection *GetCacheSection( MDLCacheDataType_t type ) =0;
// faster access when you already have the studiohdr
virtual virtualmodel_t *GetVirtualModelFast( const studiohdr_t *pStudioHdr, MDLHandle_t handle ) = 0;
// all cache entries that subsequently allocated or successfully checked
// are considered "locked" and will not be freed when additional memory is needed
virtual void BeginLock() = 0;
// reset all protected blocks to normal
virtual void EndLock() = 0;
// returns a pointer to a counter that is incremented every time the cache has been out of the locked state (EVIL)
virtual int *GetFrameUnlockCounterPtrOLD() = 0;
// Finish all pending async operations
virtual void FinishPendingLoads() = 0;
virtual vcollide_t *GetVCollideEx( MDLHandle_t handle, bool synchronousLoad = true ) = 0;
virtual bool GetVCollideSize( MDLHandle_t handle, int *pVCollideSize ) = 0;
virtual bool GetAsyncLoad( MDLCacheDataType_t type ) = 0;
virtual bool SetAsyncLoad( MDLCacheDataType_t type, bool bAsync ) = 0;
virtual void BeginMapLoad() = 0;
virtual void EndMapLoad() = 0;
virtual void MarkAsLoaded( MDLHandle_t handle ) = 0;
virtual void InitPreloadData( bool rebuild ) = 0;
virtual void ShutdownPreloadData() = 0;
virtual bool IsDataLoaded( MDLHandle_t handle, MDLCacheDataType_t type ) = 0;
virtual int *GetFrameUnlockCounterPtr( MDLCacheDataType_t type ) = 0;
virtual studiohdr_t *LockStudioHdr( MDLHandle_t handle ) = 0;
virtual void UnlockStudioHdr( MDLHandle_t handle ) = 0;
virtual bool PreloadModel( MDLHandle_t handle ) = 0;
// Hammer uses this. If a model has an error loading in GetStudioHdr, then it is flagged
// as an error model and any further attempts to load it will just get the error model.
// That is, until you call this function. Then it will load the correct model.
virtual void ResetErrorModelStatus( MDLHandle_t handle ) = 0;
virtual void MarkFrame() = 0;
// Locking for things that we can lock over longer intervals than
// resources locked by BeginLock/EndLock
virtual void BeginCoarseLock() = 0;
virtual void EndCoarseLock() = 0;
virtual void ReloadVCollide( MDLHandle_t handle ) = 0;
virtual bool ReleaseAnimBlockAllocator() = 0;
virtual bool RestoreHardwareData( MDLHandle_t handle, FSAsyncControl_t *pAsyncVTXControl, FSAsyncControl_t *pAsyncVVDControl ) = 0;
virtual void DisableVCollideLoad() = 0;
virtual void EnableVCollideLoad() = 0;
virtual void DisableFileNotFoundWarnings() = 0;
virtual void EnableFileNotFoundWarnings() = 0;
virtual bool ProcessPendingHardwareRestore() = 0;
virtual void UnloadQueuedHardwareData( ) = 0;
virtual void DumpDictionaryState( ) = 0;
// ========================
// combined models
// This will create a combined model by the name specified in pszModelName and return back a temporary model handle.
// May return MDLHANDLE_INVALID if the name is a duplicate of an existing model
virtual MDLHandle_t CreateCombinedModel( const char *pszModelName ) = 0;
// This will create a combined model in replace of an existing model handle. The handle should be valid to use during the entire process.
// Returns true if the handle is acceptable to use for the combining process.
virtual bool CreateCombinedModel( MDLHandle_t handle ) = 0;
// Sets the models for the combining process
virtual bool SetCombineModels( MDLHandle_t handle, const CUtlVector< SCombinerModelInput_t > &vecModelsToCombine ) = 0;
// Indicates that you are done with the setup of the combining process. You must specify a callback function and optionally
// a user pointer that will be supplied to you in the callback
virtual bool FinishCombinedModel( MDLHandle_t handle, CombinedModelLoadedCallback pFunc, void *pUserData = NULL ) = 0;
// Lets you query a model handle to see if it is a placeholder returned by CreateCombinedModel()
virtual bool IsCombinedPlaceholder( MDLHandle_t handle ) = 0;
// Lets you query a model handle to see if it is a combined model
virtual bool IsCombinedModel( MDLHandle_t handle ) = 0;
// Returns the number of models contained in the combined model. Includes primary and all secondary models
virtual int GetNumCombinedSubModels( MDLHandle_t handle ) = 0;
// Gets the file name for a sub model
virtual void GetCombinedSubModelFilename( MDLHandle_t handle, int nSubModelIndex, char *pszResult, int nResultSize ) = 0;
// Returns the KV of the material set for the model. You are responsible for calling deleteThis() on the result.
virtual KeyValues *GetCombinedMaterialKV( MDLHandle_t handle, int nAtlasGroup = 0 ) = 0;
// Internal engine use function to help drive the combining process.
virtual void UpdateCombiner( ) = 0; // should be called from main thread after rendering has completed
// Internal engine function to help get access to specific combined assets
virtual void *GetCombinedInternalAsset( ECombinedAsset AssetType, const char *pszAssetID = NULL, int *nSize = NULL ) = 0;
// Set Combiner Flags
virtual void SetCombinerFlags( unsigned nFlags ) = 0;
// Clear Combiner Flags
virtual void ClearCombinerFlags( unsigned nFlags ) = 0;
// Dump out resident combiner info
virtual void DebugCombinerInfo( ) = 0;
};
DECLARE_TIER3_INTERFACE( IMDLCache, g_pMDLCache );
//-----------------------------------------------------------------------------
// Critical section helper code
//-----------------------------------------------------------------------------
class CMDLCacheCriticalSection
{
public:
CMDLCacheCriticalSection( IMDLCache *pCache ) : m_pCache( pCache )
{
m_pCache->BeginLock();
}
~CMDLCacheCriticalSection()
{
m_pCache->EndLock();
}
private:
IMDLCache *m_pCache;
};
class CMDLCacheCoarseCriticalSection
{
public:
CMDLCacheCoarseCriticalSection( IMDLCache *pCache ) : m_pCache( pCache )
{
m_pCache->BeginCoarseLock();
}
~CMDLCacheCoarseCriticalSection()
{
m_pCache->EndCoarseLock();
}
private:
IMDLCache *m_pCache;
};
#define MDCACHE_FINE_GRAINED 1
#if defined(MDCACHE_FINE_GRAINED)
#define MDLCACHE_CRITICAL_SECTION_( pCache ) CMDLCacheCriticalSection cacheCriticalSection(pCache)
#define MDLCACHE_COARSE_LOCK_( pCache ) CMDLCacheCoarseCriticalSection cacheCoarseCriticalSection(pCache)
#elif defined(MDLCACHE_LEVEL_LOCKED)
#define MDLCACHE_CRITICAL_SECTION_( pCache ) ((void)(0))
#define MDLCACHE_COARSE_LOCK_( pCache ) ((void)(0))
#else
#define MDLCACHE_CRITICAL_SECTION_( pCache ) ((void)(0))
#define MDLCACHE_COARSE_LOCK_( pCache ) CMDLCacheCriticalSection cacheCriticalSection(pCache); CMDLCacheCoarseCriticalSection cacheCoarseCriticalSection(pCache)
#endif
#define MDLCACHE_CRITICAL_SECTION() MDLCACHE_CRITICAL_SECTION_(mdlcache)
#define MDLCACHE_COARSE_LOCK() MDLCACHE_COARSE_LOCK_(mdlcache)
#endif // IMDLCACHE_H

View File

@@ -0,0 +1,51 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//===========================================================================//
#ifndef IPRECACHESYSTEM_H
#define IPRECACHESYSTEM_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier2/tier2.h"
#include "tier2/resourceprecacher.h"
#include "appframework/iappsystem.h"
//-----------------------------------------------------------------------------
// Resource access control API
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// IResourceAccessControl
// Purpose: Maintains lists of resources to use them as filters to prevent access
// to ensure proper precache behavior in game code
//-----------------------------------------------------------------------------
abstract_class IPrecacheSystem : public IAppSystem
{
public:
// Precaches/uncaches all resources used by a particular system
virtual void Cache( IPrecacheHandler *pPrecacheHandler, PrecacheSystem_t nSystem,
const char *pName, bool bPrecache, ResourceList_t hResourceList, bool bBuildResourceList ) = 0;
virtual void UncacheAll( IPrecacheHandler *pPrecacheHandler ) = 0 ;
virtual void Register( IResourcePrecacher *pResourcePrecacherFirst, PrecacheSystem_t nSystem ) = 0;
// Limits resource access to only resources used by this particular system
// Use GLOBAL system, and NULL name to disable limited resource access
virtual void LimitResourceAccess( PrecacheSystem_t nSystem, const char *pName ) = 0;
virtual void EndLimitedResourceAccess() = 0;
};
DECLARE_TIER2_INTERFACE( IPrecacheSystem, g_pPrecacheSystem );
#endif // IPRECACHESYSTEM_H

View File

@@ -0,0 +1,50 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//===========================================================================//
#ifndef IRESOURCEACCESSCONTROL_H
#define IRESOURCEACCESSCONTROL_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier2/resourceprecacher.h"
#include "appframework/iappsystem.h"
//-----------------------------------------------------------------------------
// Resource access control API
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// IResourceAccessControl
// Purpose: Maintains lists of resources to use them as filters to prevent access
// to ensure proper precache behavior in game code
//-----------------------------------------------------------------------------
abstract_class IResourceAccessControl : public IAppSystem
{
public:
// Creates, destroys a resource list
virtual ResourceList_t CreateResourceList( const char *pDebugName ) = 0;
virtual void DestroyAllResourceLists( ) = 0;
// Adds a resource to a resource list
virtual void AddResource( ResourceList_t hResourceList, ResourceTypeOld_t nType, const char *pResourceName ) = 0;
// Prevents access to anything except the specified resource list
// Pass RESOURCE_LIST_INVALID to allow access to all resources
virtual void LimitAccess( ResourceList_t hResourceList ) = 0;
// Is access to this resource allowed?
virtual bool IsAccessAllowed( ResourceTypeOld_t nType, const char *pResource ) = 0;
};
#endif // IRESOURCEACCESSCONTROL_H

View File

@@ -0,0 +1,425 @@
//========= Copyright c 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef DATA_LINKER_INTERFACE_H
#define DATA_LINKER_INTERFACE_H
#include "tier0/platform.h"
#include "tier0/basetypes.h"
#include "tier0/dbg.h"
template <uint nAlignment = 1, uint nCookie = 0>
struct DataLinkerClassProperties
{
enum {kDataAlignment = nAlignment};
enum {kDataCookie = nCookie};// 0 means no cookie
};
template <typename T>
struct DataLinkerClassPropertiesSelector: public DataLinkerClassProperties<sizeof(T)&1?1:sizeof(T)&3?2:4> // heuristic: 1-, 2- and 4-byte aligned type size calls for 1-, 2- and 4-byte alignment by default
{
};
//#define DATALINKER_ALIGNMENT(ALIGNMENT) enum {kDataAlignment = ALIGNMENT}
#define DATALINKER_CLASS_ALIGNMENT(CLASS, ALIGNMENT) template <> struct DataLinkerClassPropertiesSelector<CLASS> {enum {kDataAlignment = ALIGNMENT};}
DATALINKER_CLASS_ALIGNMENT(float,4);
DATALINKER_CLASS_ALIGNMENT(int32,4);
DATALINKER_CLASS_ALIGNMENT(int16,2);
DATALINKER_CLASS_ALIGNMENT(int8,1);
DATALINKER_CLASS_ALIGNMENT(uint32,4);
DATALINKER_CLASS_ALIGNMENT(uint16,2);
DATALINKER_CLASS_ALIGNMENT(uint8,1);
// undefine DATALINKER_CHECK_COOKIES if you don't want runtime cookie checks
#define DATALINKER_CHECK_COOKIES
namespace DataLinker
{
inline byte *ResolveOffset(int32 *pOffset)
{
int offset = *pOffset;
return offset ? ((byte*)pOffset) + offset : NULL;
}
inline byte *ResolveOffsetFast(const int32 *pOffset)
{
int offset = *pOffset;
Assert(offset != 0);
return ((byte*)pOffset) + offset;
}
// AT RUN-TIME ONLY the offset converts automatically into pointers to the appropritate type
// at tool-time, you should use LinkSource_t and LinkTarget_t
template <typename T, int32 nCookie = 0>
struct Offset_t
{
enum {kDataAlignment = 4};
int32 offset;
bool operator == (int zero)const {Assert(zero == 0); return offset == zero;}
bool IsNull()const {return offset == 0;}
int32 NotNull()const {return offset;}
const T* GetPtr()const
{
// validate
byte *ptr = ResolveOffsetFast(&offset);
#ifdef DATALINKER_CHECK_COOKIES
if(nCookie)
{
if(nCookie != ((int*)ptr)[-1])
{
Error("Invalid data cookie %d != %d\n", ((int*)ptr)[-1], nCookie);
}
}
#endif
return (const T*)ptr;
}
//const T* GetPtrFast()const {return (const T*)ResolveOffsetFast(&offset);}
operator const T* ()const{return GetPtr();}
const T* operator ->() const{return GetPtr();}
};
template <typename T,int32 nCookie = 0>
struct OffsetAndSize_t: public Offset_t<T,nCookie>
{
int32 size;
const T& operator []( int index ) const
{
Assert(index < size);
return this->GetPtr()[index];
}
};
template <typename T,int32 nCookie = 0>
struct OffsetSizeAndStride_t : public OffsetAndSize_t<T,nCookie>
{
int32 stride;
const T& operator []( int index ) const
{
Assert(index < this->size);
return *(const T*)(ResolveOffsetFast(&this->offset) + stride * index);
}
};
enum {kSpecialTargetUndefined = -1};
enum {kSpecialTargetNull = 0};
enum {kSpecialTargetDefault = 1};// resolved pointer/offset right in the LinkSource
// this is resolved or unresolved reference within the data block
// it's unique for the life cycle of the Stream and must either be resolved or
// never referenced by the end
struct LinkTarget_t
{
int m_id;
friend class Stream;
LinkTarget_t(){m_id = kSpecialTargetUndefined;} // -1 is anonymous/undefined reference
};
struct LinkTargetNull_t: public LinkTarget_t
{
LinkTargetNull_t(){m_id = kSpecialTargetNull;} // 0 is special default case meaning null pointer/offset
};
/*
template <typename T>
struct Target_t
{
T* m_ptr;
operator T* () {return m_ptr;}
T* operator -> () {return m_ptr;}
};
*/
struct LinkSource_t
{
protected:
int m_offset;
friend class Stream;
LinkSource_t(){}
};
enum OffsetTypeEnum
{
kOtRelative32bit,
kOtRelative16bit,
kOtAbsolute32bit
};
//////////////////////////////////////////////////////////////////////////
// this class may be useful at runtime to use fast serialize interface (without data linking)
//
abstract_class IBasicStream
{
public:
virtual void* WriteBytes(uint numBytes) = 0;
virtual void Align(uint nAlignment, int nOffset = 0) = 0;
inline void AlignPointer(){Align(4);}
virtual long Tell() = 0;
// the Begin/End semantics differ in different implementations
// in some, it can be ignored, some others can use it for statistics and some others may set fixed page boundaries based on the names and/or flags
virtual void Begin(const char *nName, uint flags = 0) = 0;
virtual void End() = 0;
virtual void PrintStats() = 0;
virtual void ClearStats() = 0;
template <typename T>
T* Write(uint count = 1);
template <typename T, int32 nCookie>
T* WriteWithCookie(uint count = 1);
template <typename T, int32 nCookie>
T* WriteWithCookieStrided(uint count, uint stride);
template <typename T>
void WriteSimple(const T x)
{
*Write<T>() = x;
}
virtual void EnsureAvailable(uint addCapacity) = 0;
inline void WriteFloat(float x)
{
WriteSimple(x);
}
inline void WriteU32(uint32 x)
{
WriteSimple(x);
}
inline void WriteU16(uint16 x)
{
WriteSimple(x);
}
inline void WriteByte(byte x)
{
WriteSimple(x);
}
};
//////////////////////////////////////////////////////////////////////////
// this is light-weight version of IStream with Links
// It can link on-the-fly, has minimal overhead but cannot late-bind symbols
// you basically have to manage all your late-bindings by managing
// pointers to offsets, which is fine in 99% of use cases.
// WARNING: there are no error-checking facilities here. If you forget to set
// a link, you'll have a NULL offset and no warnings or errors
//
abstract_class IStream: public IBasicStream
{
public:
template <typename T,int32 nCookie> T* WriteAndLink(Offset_t<T,nCookie>*pOffset, uint count = 1);
template <typename T,int32 nCookie> T* WriteAndLink(OffsetAndSize_t<T,nCookie>*pOffset, uint count = 1); // intentionally not implemented - use explicit WriteAndLinkArray()
template <typename T,int32 nCookie> T* WriteAndLinkArray(OffsetAndSize_t<T,nCookie>*pOffsetAndSize, uint count = 1);
template <typename T,int32 nCookie> T* WriteAndLinkStrided(OffsetSizeAndStride_t<T,nCookie>*pOffset, uint nStride, uint count = 1);
template <typename T,int32 nCookie> void Link(Offset_t<T,nCookie>*pOffset, const T* pTarget);
virtual void Link(int32 *pOffset, const void *pTarget) = 0;
virtual void Link(int16 *pOffset, const void *pTarget) = 0;
virtual bool Compile(void *pBuffer) = 0;
virtual uint GetTotalSize()const = 0;
};
//////////////////////////////////////////////////////////////////////////
// This is IStream with late-binding capabilities. You can link multiple sources to
// the same target, then change your mind and reset the target somewhere and it'll
// automatically track all sources and reset them to the latest target at compilation.
// You can create unresolved targets to resolve them later.
// You can extend this to multiple object files linked at later stage (szDescription
// must be unique identifiers)
//
abstract_class ILinkStream: public IStream
{
public:
virtual LinkSource_t WriteOffset(const char *szDescription) = 0;
virtual LinkSource_t WriteOffset(LinkTarget_t linkTarget, const char *szDescription) = 0;
virtual LinkSource_t WriteNullOffset(const char *szDescription) = 0;
virtual void Link(LinkSource_t, LinkTarget_t, const char *szDescription) = 0;
virtual LinkSource_t LinkToHere(int32 *pOffset, const char *szDescription) = 0;
virtual LinkSource_t Link(int32 *pOffset, LinkTarget_t linkTarget, const char *szDescription) = 0;
virtual LinkTarget_t NewTarget() = 0; // create new, unresolved target
virtual LinkTarget_t NewTarget(void *pWhere) = 0;
virtual LinkTarget_t NewTargetHere() = 0; // creates a target right here
virtual void SetTargetHere(LinkTarget_t) = 0; // sets the given target to point to right here
virtual void SetTargetNull(LinkTarget_t) = 0; // set this target to point to NULL
virtual LinkSource_t NewOffset(int *pOffset, const char *szDescription) = 0;
virtual bool IsDeclared(LinkTarget_t linkTarget)const = 0;
virtual bool IsSet(LinkTarget_t linkTarget)const = 0;
virtual bool IsDefined(LinkSource_t linkSource)const = 0;
virtual bool IsLinked(LinkSource_t linkSource)const = 0;
};
template <typename T>
inline T* IBasicStream::Write(uint count)
{
// TODO: insert reflection code here
uint nAlignment = DataLinkerClassPropertiesSelector<T>::kDataAlignment;
Align(nAlignment);
return (T*)WriteBytes(count * sizeof(T));
}
template <typename T, int32 nCookie>
inline T* IBasicStream::WriteWithCookie(uint count)
{
// TODO: insert reflection code here
uint nAlignment = DataLinkerClassPropertiesSelector<T>::kDataAlignment;
if(nCookie)
{
if(nAlignment > sizeof(int32))
{
Align(nAlignment, -4);
}
else
{
Align(sizeof(int32));// we want the cookie itself aligned properly
}
WriteSimple<int32>(nCookie);
Assert((Tell()&(nAlignment-1)) == 0); // must be correctly aligned by now
}
else
{
if(nAlignment > 1)
{
Align(nAlignment);
}
}
return (T*)WriteBytes(count * sizeof(T));
}
template <typename T, int32 nCookie>
inline T* IBasicStream::WriteWithCookieStrided(uint count, uint stride)
{
// TODO: insert reflection code here
uint nAlignment = DataLinkerClassPropertiesSelector<T>::kDataAlignment;
if(nCookie)
{
if(nAlignment > sizeof(int32))
{
Align(nAlignment, -4);
}
else
{
Align(sizeof(int32));// we want the cookie itself aligned properly
}
WriteSimple<int32>(nCookie);
Assert((Tell()&(nAlignment-1)) == 0); // must be correctly aligned by now
}
else
{
if(nAlignment > 1)
{
Align(nAlignment);
}
}
if(count)
return (T*)WriteBytes((count-1) * stride + sizeof(T));
else
return (T*)WriteBytes(0);
}
template <typename T,int32 nCookie>
inline void IStream::Link(Offset_t<T,nCookie>*pOffset, const T* pTarget)
{
Link(&pOffset->offset, pTarget);
}
template <typename T, int32 nCookie>
inline T* IStream::WriteAndLink(Offset_t<T,nCookie>*pOffset, uint count)
{
T* p = WriteWithCookie<T,nCookie>(count);
Link(&pOffset->offset, p);
return p;
}
template <typename T, int32 nCookie>
inline T* IStream::WriteAndLinkArray(OffsetAndSize_t<T,nCookie>*pOffsetAndSize, uint count)
{
pOffsetAndSize->size = count;
if(count)
{
T* p = WriteWithCookie<T,nCookie>(count);
Link(&pOffsetAndSize->offset, p);
return p;
}
else
{
pOffsetAndSize->offset = 0;
return NULL;
}
}
template <typename T, int32 nCookie>
inline T* IStream::WriteAndLinkStrided(OffsetSizeAndStride_t<T,nCookie>*pOffset, uint stride, uint count)
{
pOffset->size = count;
pOffset->stride = stride;
if(count)
{
T* p = WriteWithCookieStrided<T,nCookie>(count, stride);
Link(&pOffset->offset, p);
return p;
}
else
{
pOffset->offset = 0;
return NULL;
}
}
}
struct DataLinkerBasicStreamRange_t
{
DataLinker::IBasicStream *m_pStream;
DataLinkerBasicStreamRange_t(DataLinker::IBasicStream *pStream, const char *name): m_pStream(pStream){pStream->Begin(name);}
~DataLinkerBasicStreamRange_t(){m_pStream->End();}
};
#define DATALINKER_RANGE(STREAM,NAME) DataLinkerBasicStreamRange_t dataLinker_basicStreamRange##__LINE((STREAM),(NAME))
#endif

521
public/datamap.h Normal file
View File

@@ -0,0 +1,521 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef DATAMAP_H
#define DATAMAP_H
#ifdef _WIN32
#pragma once
#endif
#ifndef VECTOR_H
#include "mathlib/vector.h"
#endif
#include "tier1/utlvector.h"
#include "tier0/memdbgon.h"
// SINGLE_INHERITANCE restricts the size of CBaseEntity pointers-to-member-functions to 4 bytes
class SINGLE_INHERITANCE CBaseEntity;
struct inputdata_t;
#define INVALID_TIME (FLT_MAX * -1.0) // Special value not rebased on save/load
typedef enum _fieldtypes
{
FIELD_VOID = 0, // No type or value
FIELD_FLOAT, // Any floating point value
FIELD_STRING, // A string ID (return from ALLOC_STRING)
FIELD_VECTOR, // Any vector, QAngle, or AngularImpulse
FIELD_QUATERNION, // A quaternion
FIELD_INTEGER, // Any integer or enum
FIELD_BOOLEAN, // boolean, implemented as an int, I may use this as a hint for compression
FIELD_SHORT, // 2 byte integer
FIELD_CHARACTER, // a byte
FIELD_COLOR32, // 8-bit per channel r,g,b,a (32bit color)
FIELD_EMBEDDED, // an embedded object with a datadesc, recursively traverse and embedded class/structure based on an additional typedescription
FIELD_CUSTOM, // special type that contains function pointers to it's read/write/parse functions
FIELD_CLASSPTR, // CBaseEntity *
FIELD_EHANDLE, // Entity handle
FIELD_EDICT, // edict_t *
FIELD_POSITION_VECTOR, // A world coordinate (these are fixed up across level transitions automagically)
FIELD_TIME, // a floating point time (these are fixed up automatically too!)
FIELD_TICK, // an integer tick count( fixed up similarly to time)
FIELD_MODELNAME, // Engine string that is a model name (needs precache)
FIELD_SOUNDNAME, // Engine string that is a sound name (needs precache)
FIELD_INPUT, // a list of inputed data fields (all derived from CMultiInputVar)
FIELD_FUNCTION, // A class function pointer (Think, Use, etc)
FIELD_VMATRIX, // a vmatrix (output coords are NOT worldspace)
// NOTE: Use float arrays for local transformations that don't need to be fixed up.
FIELD_VMATRIX_WORLDSPACE,// A VMatrix that maps some local space to world space (translation is fixed up on level transitions)
FIELD_MATRIX3X4_WORLDSPACE, // matrix3x4_t that maps some local space to world space (translation is fixed up on level transitions)
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_VECTOR4D, // 4 floats
FIELD_TYPECOUNT, // MUST BE LAST
} fieldtype_t;
//-----------------------------------------------------------------------------
// Field sizes...
//-----------------------------------------------------------------------------
template <int FIELD_TYPE>
class CDatamapFieldSizeDeducer
{
public:
enum
{
SIZE = 0
};
static int FieldSize( )
{
return 0;
}
};
#define DECLARE_FIELD_SIZE( _fieldType, _fieldSize ) \
template< > class CDatamapFieldSizeDeducer<_fieldType> { public: enum { SIZE = _fieldSize }; static int FieldSize() { return _fieldSize; } };
#define FIELD_SIZE( _fieldType ) CDatamapFieldSizeDeducer<_fieldType>::SIZE
#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_VECTOR4D, 4 * sizeof( float ) )
DECLARE_FIELD_SIZE( FIELD_QUATERNION, 4 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_INTEGER, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_INTEGER64, sizeof(int64))
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_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))
#if defined(_WIN32)
DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(void *))
#elif defined(POSIX)
// pointer to members under gnuc are 8bytes if you have a virtual func
DECLARE_FIELD_SIZE( FIELD_FUNCTION, 2 * sizeof(void *))
#else
#error
#endif
DECLARE_FIELD_SIZE( FIELD_VMATRIX, 16 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_VMATRIX_WORLDSPACE, 16 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_MATRIX3X4_WORLDSPACE, 12 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_INTERVAL, 2 * sizeof( float) ) // NOTE: Must match interval.h definition
DECLARE_FIELD_SIZE( FIELD_MODELINDEX, sizeof(int) )
DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) )
#define ARRAYSIZE2D(p) (sizeof(p)/sizeof(p[0][0]))
#define SIZE_OF_ARRAY(p) _ARRAYSIZE(p)
#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, offsetof(classNameTypedef, name), 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}
#define DEFINE_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_FIELD_NOT_SAVED(name,fieldtype) _FIELD(name, fieldtype, 1, 0, NULL, 0 )
#define DEFINE_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 )
#define DEFINE_KEYFIELD_NOT_SAVED(name,fieldtype, mapname)_FIELD(name, fieldtype, 1, FTYPEDESC_KEY, mapname, 0 )
#define DEFINE_AUTO_ARRAY(name,fieldtype) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_AUTO_ARRAY_KEYFIELD(name,fieldtype,mapname) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, mapname, 0 )
#define DEFINE_ARRAY(name,fieldtype, count) _FIELD(name, fieldtype, count, FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_ARRAY_NOT_SAVED(name,fieldtype, count) _FIELD(name, fieldtype, count, 0, NULL, 0 )
#define DEFINE_ENTITY_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, #name, 0 )
#define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE | FTYPEDESC_GLOBAL, #name, 0 )
#define DEFINE_GLOBAL_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_GLOBAL_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 )
#define DEFINE_CUSTOM_FIELD(name,datafuncs) { FIELD_CUSTOM, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE, NULL, datafuncs, NULL }
#define DEFINE_CUSTOM_KEYFIELD(name,datafuncs,mapname) { FIELD_CUSTOM, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, datafuncs, NULL }
#define DEFINE_AUTO_ARRAY2D(name,fieldtype) _FIELD(name, fieldtype, ARRAYSIZE2D(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 )
// Used by byteswap datadescs
#define DEFINE_BITFIELD(name,fieldtype,bitcount) DEFINE_ARRAY(name,fieldtype,((bitcount+FIELD_BITS(fieldtype)-1)&~(FIELD_BITS(fieldtype)-1)) / FIELD_BITS(fieldtype) )
#define DEFINE_INDEX(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_INDEX, NULL, 0 )
#define DEFINE_EMBEDDED( name ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name.m_DataMap), sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDED_OVERRIDE( name, overridetype ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &((overridetype *)0)->m_DataMap, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDEDBYREF( name ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( *(((classNameTypedef *)0)->name) ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDED_ARRAY( name, count ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), count, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDED_AUTO_ARRAY( name ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), SIZE_OF_ARRAY( ((classNameTypedef *)0)->name ), FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f }
#ifndef NO_ENTITY_PREDICTION
// FTYPEDESC_KEY tells the prediction copy system to report the full nameof the field when reporting errors
#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, NULL, NULL, NULL, &fieldtype::m_PredMap }
#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_PTR | FTYPEDESC_KEY, NULL, NULL, NULL, &fieldtype::m_PredMap }
#else
#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) DEFINE_FIELD_NULL
#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) DEFINE_FIELD_NULL
#endif
// Extensions to datamap.h macros for predicted entities only
#define DEFINE_PRED_FIELD(name,fieldtype, flags) _FIELD(name, fieldtype, 1, flags, NULL, 0.0f )
#define DEFINE_PRED_ARRAY(name,fieldtype, count,flags) _FIELD(name, fieldtype, count, flags, NULL, 0.0f )
#define DEFINE_FIELD_NAME(localname,netname,fieldtype) _FIELD(localname, fieldtype, 1, 0, #netname, 0.0f )
// Predictable macros, which include a tolerance for floating point values...
#define DEFINE_PRED_FIELD_TOL(name,fieldtype, flags,tolerance) _FIELD(name, fieldtype, 1, flags, NULL, tolerance )
#define DEFINE_PRED_ARRAY_TOL(name,fieldtype, count,flags,tolerance) _FIELD(name, fieldtype, count, flags, NULL, tolerance)
#define DEFINE_FIELD_NAME_TOL(localname,netname,fieldtolerance) _FIELD(localname, fieldtype, 1, 0, #netname, tolerance )
//#define DEFINE_DATA( name, fieldextname, flags ) _FIELD(name, fieldtype, 1, flags, extname )
// INPUTS
#define DEFINE_INPUT( name, fieldtype, inputname ) { fieldtype, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_INPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, inputname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ) }
#define DEFINE_INPUTFUNC( fieldtype, inputname, inputfunc ) { fieldtype, #inputfunc, 0, 1, FTYPEDESC_INPUT, inputname, NULL, static_cast <inputfunc_t> (&classNameTypedef::inputfunc) }
// OUTPUTS
// the variable 'name' MUST BE derived from CBaseOutput
// we know the output type from the variable itself, so it doesn't need to be specified here
class ISaveRestoreOps;
extern ISaveRestoreOps *eventFuncs;
#define DEFINE_OUTPUT( name, outputname ) { FIELD_CUSTOM, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_OUTPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, outputname, eventFuncs }
// replaces EXPORT table for portability and non-DLL based systems (xbox)
#define DEFINE_FUNCTION_RAW( function, func_type ) { FIELD_VOID, nameHolder.GenerateName(#function), 0, 1, FTYPEDESC_FUNCTIONTABLE, NULL, NULL, (inputfunc_t)((func_type)(&classNameTypedef::function)) }
#define DEFINE_FUNCTION( function ) DEFINE_FUNCTION_RAW( function, inputfunc_t )
#define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore
#define FTYPEDESC_SAVE 0x0002 // This field is saved to disk
#define FTYPEDESC_KEY 0x0004 // This field can be requested and written to by string name at load time
#define FTYPEDESC_INPUT 0x0008 // This field can be written to by string name at run time, and a function called
#define FTYPEDESC_OUTPUT 0x0010 // This field propogates it's value to all targets whenever it changes
#define FTYPEDESC_FUNCTIONTABLE 0x0020 // This is a table entry for a member function pointer
#define FTYPEDESC_PTR 0x0040 // This field is a pointer, not an embedded object
#define FTYPEDESC_OVERRIDE 0x0080 // The field is an override for one in a base class (only used by prediction system for now)
// Flags used by other systems (e.g., prediction system)
#define FTYPEDESC_INSENDTABLE 0x0100 // This field is present in a network SendTable
#define FTYPEDESC_PRIVATE 0x0200 // The field is local to the client or server only (not referenced by prediction code and not replicated by networking)
#define FTYPEDESC_NOERRORCHECK 0x0400 // The field is part of the prediction typedescription, but doesn't get compared when checking for errors
#define FTYPEDESC_MODELINDEX 0x0800 // The field is a model index (used for debugging output)
#define FTYPEDESC_INDEX 0x1000 // The field is an index into file data, used for byteswapping.
// These flags apply to C_BasePlayer derived objects only
#define FTYPEDESC_VIEW_OTHER_PLAYER 0x2000 // By default you can only view fields on the local player (yourself),
// but if this is set, then we allow you to see fields on other players
#define FTYPEDESC_VIEW_OWN_TEAM 0x4000 // Only show this data if the player is on the same team as the local player
#define FTYPEDESC_VIEW_NEVER 0x8000 // Never show this field to anyone, even the local player (unusual)
#define TD_MSECTOLERANCE 0.001f // This is a FIELD_FLOAT and should only be checked to be within 0.001 of the networked info
struct typedescription_t;
class ISaveRestoreOps;
//
// Function prototype for all input handlers.
//
typedef void (CBaseEntity::*inputfunc_t)(inputdata_t &data);
struct datamap_t;
struct typedescription_t;
enum
{
PC_NON_NETWORKED_ONLY = 0,
PC_NETWORKED_ONLY,
PC_COPYTYPE_COUNT,
PC_EVERYTHING = PC_COPYTYPE_COUNT,
};
enum
{
TD_OFFSET_NORMAL = 0,
TD_OFFSET_PACKED = 1,
// Must be last
TD_OFFSET_COUNT,
};
struct typedescription_t
{
fieldtype_t fieldType;
const char *fieldName;
int fieldOffset; // Local offset value
unsigned short fieldSize;
short flags;
// the name of the variable in the map/fgd data, or the name of the action
const char *externalName;
// pointer to the function set for save/restoring of custom data types
ISaveRestoreOps *pSaveRestoreOps;
// for associating function with string names
inputfunc_t inputFunc;
// For embedding additional datatables inside this one
datamap_t *td;
// Stores the actual member variable size in bytes
int fieldSizeInBytes;
// FTYPEDESC_OVERRIDE point to first baseclass instance if chains_validated has occurred
struct typedescription_t *override_field;
// Used to track exclusion of baseclass fields
int override_count;
// Tolerance for field errors for float fields
float fieldTolerance;
// For raw fields (including children of embedded stuff) this is the flattened offset
int flatOffset[ TD_OFFSET_COUNT ];
unsigned short flatGroup;
};
// See predictioncopy.h for implementation and notes
struct optimized_datamap_t;
//-----------------------------------------------------------------------------
// Purpose: stores the list of objects in the hierarchy
// used to iterate through an object's data descriptions
//-----------------------------------------------------------------------------
struct datamap_t
{
typedescription_t *dataDesc;
int dataNumFields;
char const *dataClassName;
datamap_t *baseMap;
int m_nPackedSize;
optimized_datamap_t *m_pOptimizedDataMap;
#if defined( _DEBUG )
bool bValidityChecked;
#endif // _DEBUG
};
//-----------------------------------------------------------------------------
//
// Macros used to implement datadescs
//
#define DECLARE_FRIEND_DATADESC_ACCESS() \
template <typename T> friend void DataMapAccess(T *, datamap_t **p); \
template <typename T> friend datamap_t *DataMapInit(T *);
#define DECLARE_SIMPLE_DATADESC() \
static datamap_t m_DataMap; \
static datamap_t *GetBaseMap(); \
template <typename T> friend void DataMapAccess(T *, datamap_t **p); \
template <typename T> friend datamap_t *DataMapInit(T *);
#if defined(POSIX) && !defined(_PS3)
#define DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() \
static datamap_t m_DataMap; \
static datamap_t *GetBaseMap(); \
template <typename T> friend void ::DataMapAccess(T *, datamap_t **p);
#else
#define DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() \
static datamap_t m_DataMap; \
static datamap_t *GetBaseMap(); \
template <typename T> friend void ::DataMapAccess(T *, datamap_t **p); \
template <typename T> friend datamap_t *::DataMapInit(T *);
#endif
#define DECLARE_DATADESC() \
DECLARE_SIMPLE_DATADESC() \
virtual datamap_t *GetDataDescMap( void );
#define BEGIN_DATADESC( className ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \
datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_DATADESC_NO_BASE( className ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \
datamap_t *className::GetBaseMap() { return NULL; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_SIMPLE_DATADESC( className ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetBaseMap() { return NULL; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_SIMPLE_DATADESC_( className, BaseClass ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_DATADESC_GUTS( className ) \
template <typename T> datamap_t *DataMapInit(T *); \
template <> datamap_t *DataMapInit<className>( className * ); \
namespace className##_DataDescInit \
{ \
datamap_t *g_DataMapHolder = DataMapInit<className>( (className *)NULL ); /* This can/will be used for some clean up duties later */ \
} \
\
template <> datamap_t *DataMapInit<className>( className * ) \
{ \
typedef className classNameTypedef; \
static CDatadescGeneratedNameHolder nameHolder(#className); \
className::m_DataMap.baseMap = className::GetBaseMap(); \
static typedescription_t dataDesc[] = \
{ \
{ FIELD_VOID,0,0,0,0,0,0,0,0}, /* so you can define "empty" tables */
#define BEGIN_DATADESC_GUTS_NAMESPACE( className, nameSpace ) \
template <typename T> datamap_t *nameSpace::DataMapInit(T *); \
template <> datamap_t *nameSpace::DataMapInit<className>( className * ); \
namespace className##_DataDescInit \
{ \
datamap_t *g_DataMapHolder = nameSpace::DataMapInit( (className *)NULL ); /* This can/will be used for some clean up duties later */ \
} \
\
template <> datamap_t *nameSpace::DataMapInit<className>( className * ) \
{ \
typedef className classNameTypedef; \
static CDatadescGeneratedNameHolder nameHolder(#className); \
className::m_DataMap.baseMap = className::GetBaseMap(); \
static typedescription_t dataDesc[] = \
{ \
{ FIELD_VOID,0,0,0,0,0,0,0,0}, /* so you can define "empty" tables */
#define END_DATADESC() \
}; \
\
if ( sizeof( dataDesc ) > sizeof( dataDesc[0] ) ) \
{ \
classNameTypedef::m_DataMap.dataNumFields = SIZE_OF_ARRAY( dataDesc ) - 1; \
classNameTypedef::m_DataMap.dataDesc = &dataDesc[1]; \
} \
else \
{ \
classNameTypedef::m_DataMap.dataNumFields = 1; \
classNameTypedef::m_DataMap.dataDesc = dataDesc; \
} \
return &classNameTypedef::m_DataMap; \
}
// used for when there is no data description
#define IMPLEMENT_NULL_SIMPLE_DATADESC( derivedClass ) \
BEGIN_SIMPLE_DATADESC( derivedClass ) \
END_DATADESC()
#define IMPLEMENT_NULL_SIMPLE_DATADESC_( derivedClass, baseClass ) \
BEGIN_SIMPLE_DATADESC_( derivedClass, baseClass ) \
END_DATADESC()
#define IMPLEMENT_NULL_DATADESC( derivedClass ) \
BEGIN_DATADESC( derivedClass ) \
END_DATADESC()
// helps get the offset of a bitfield
#define BEGIN_BITFIELD( name ) \
union \
{ \
char name; \
struct \
{
#define END_BITFIELD() \
}; \
};
//-----------------------------------------------------------------------------
// Forward compatability with potential seperate byteswap datadescs
#define DECLARE_BYTESWAP_DATADESC() DECLARE_SIMPLE_DATADESC()
#define BEGIN_BYTESWAP_DATADESC(name) BEGIN_SIMPLE_DATADESC(name)
#define BEGIN_BYTESWAP_DATADESC_(name,base) BEGIN_SIMPLE_DATADESC_(name,base)
#define END_BYTESWAP_DATADESC() END_DATADESC()
//-----------------------------------------------------------------------------
template <typename T>
inline void DataMapAccess(T *ignored, datamap_t **p)
{
*p = &T::m_DataMap;
}
//-----------------------------------------------------------------------------
class CDatadescGeneratedNameHolder
{
public:
explicit CDatadescGeneratedNameHolder( const char *pszBase )
: m_pszBase(pszBase)
{
m_nLenBase = strlen( m_pszBase );
}
~CDatadescGeneratedNameHolder()
{
for ( int i = 0; i < m_Names.Count(); i++ )
{
delete m_Names[i];
}
}
const char *GenerateName( const char *pszIdentifier )
{
char *pBuf = new char[m_nLenBase + strlen(pszIdentifier) + 1];
strcpy( pBuf, m_pszBase );
strcat( pBuf, pszIdentifier );
m_Names.AddToTail( pBuf );
return pBuf;
}
private:
const char *m_pszBase;
size_t m_nLenBase;
CUtlVector<char *> m_Names;
};
//-----------------------------------------------------------------------------
// Compiler can require the global-namespace template friend to be declared
// before DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() can be used
template <typename T> datamap_t *DataMapInit(T *);
#include "tier0/memdbgoff.h"
#endif // DATAMAP_H

View File

@@ -0,0 +1,32 @@
//====== Copyright <20> 1996-2004, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef ATTRIBUTEFLAGS_H
#define ATTRIBUTEFLAGS_H
#ifdef _WIN32
#pragma once
#endif
enum
{
// NOTE: The first 5 flags bits are reserved for attribute type
FATTRIB_TYPEMASK = 0x1F,
FATTRIB_READONLY = (1<<5), // Don't allow editing value in editors
FATTRIB_DONTSAVE = (1<<6), // Don't persist to .dmx file
FATTRIB_DIRTY = (1<<7), // Indicates the attribute has been changed since the resolve phase
FATTRIB_HAS_CALLBACK = (1<<8), // Indicates that this will notify its owner and/or other elements when it changes
FATTRIB_EXTERNAL = (1<<9), // Indicates this attribute's data is externally owned (in a CDmElement somewhere)
FATTRIB_TOPOLOGICAL = (1<<10), // Indicates this attribute effects the scene's topology (ie it's an attribute name or element)
FATTRIB_MUSTCOPY = (1<<11), // parent element must make a new copy during CopyInto, even for shallow copy
FATTRIB_NEVERCOPY = (1<<12), // parent element shouldn't make a new copy during CopyInto, even for deep copy
FATTRIB_USERDEFINED = (1<<13), // This flag WAS used to sort attributes. Now it's used to guess whether vmtdoc and vmfentity attributes are shaderparams or entitykeys. TODO - remove this
FATTRIB_OPERATOR_DIRTY = (1<<14), // Used and cleared only by operator phase of datamodel
FATTRIB_HIDDEN = (1<<15), // shouldn't be shown in ui
};
#endif // ATTRIBUTEFLAGS_H

View File

@@ -0,0 +1,440 @@
//====== Copyright <20> 1996-2004, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef DMATTRIBUTE_H
#define DMATTRIBUTE_H
#ifdef _WIN32
#pragma once
#endif
#include "datamodel/attributeflags.h"
#include "datamodel/idatamodel.h"
#include "datamodel/dmattributetypes.h"
#include "datamodel/dmvar.h"
#include "tier1/utlhash.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CDmElement;
class CUtlBuffer;
//-----------------------------------------------------------------------------
// Used for in-place modification
//-----------------------------------------------------------------------------
typedef void *DmAttributeModifyHandle_t;
//-----------------------------------------------------------------------------
// Purpose: A general purpose pAttribute. Eventually will be extensible to arbitrary user types
//-----------------------------------------------------------------------------
class CDmAttribute
{
public:
// Returns the type
DmAttributeType_t GetType() const;
const char *GetTypeString() const;
template< class T > bool IsA() const;
// ChangeType fails (and returns false) for external attributes (ones who's data is owned by their element)
bool ChangeType_UNSAFE( DmAttributeType_t type );
bool IsStandard() const;
// Returns the name. NOTE: The utlsymbol
// can be turned into a string by using g_pDataModel->String();
const char *GetName() const;
CUtlSymbolLarge GetNameSymbol() const;
void SetName( const char *newName );
// Gets the attribute value
// NOTE: GetValueUntyped is used with GetType() for use w/ SetValue( type, void* )
template< class T > const T& GetValue() const;
template< class T > const T& GetValue( const T& defaultValue ) const;
const char *GetValueString() const;
template< class E > E *GetValueElement() const;
const void *GetValueUntyped() const;
// Sets the attribute value
template< class T > void SetValue( const T &value );
template< class E > void SetValue( E* pValue );
void SetValue( const void *pValue, size_t nSize );
// Copies w/ type conversion (if possible) from another attribute
void SetValue( const CDmAttribute *pAttribute );
void SetValue( CDmAttribute *pAttribute );
void SetValue( DmAttributeType_t valueType, const void *pValue );
// Sets the attribute to its default value based on its type
void SetToDefaultValue();
// Convert to and from string
void SetValueFromString( const char *pValue );
const char *GetValueAsString( char *pBuffer, size_t nBufLen ) const;
// Used for in-place modification of the data; preferable to set value
// for large data like arrays or binary blocks
template< class T > T& BeginModifyValueInPlace( DmAttributeModifyHandle_t *pHandle );
template< class T > void EndModifyValueInPlace( DmAttributeModifyHandle_t handle );
// Used for element and element array attributes; it specifies which type of
// elements are valid to be referred to by this attribute
void SetElementTypeSymbol( CUtlSymbolLarge typeSymbol );
CUtlSymbolLarge GetElementTypeSymbol() const;
// Returns the next attribute
CDmAttribute *NextAttribute();
const CDmAttribute *NextAttribute() const;
// Returns the owner
CDmElement *GetOwner();
// Methods related to flags
void AddFlag( int flags );
void RemoveFlag( int flags );
void ClearFlags();
int GetFlags() const;
bool IsFlagSet( int flags ) const;
// Serialization
bool Serialize( CUtlBuffer &buf ) const;
bool Unserialize( CUtlBuffer &buf );
bool IsIdenticalToSerializedValue( CUtlBuffer &buf ) const;
// Serialization of a single element.
// First version of UnserializeElement adds to tail if it worked
// Second version overwrites, but does not add, the element at the specified index
bool SerializeElement( int nElement, CUtlBuffer &buf ) const;
bool UnserializeElement( CUtlBuffer &buf );
bool UnserializeElement( int nElement, CUtlBuffer &buf );
// Does this attribute serialize on multiple lines?
bool SerializesOnMultipleLines() const;
// Get the attribute/create an attribute handle
DmAttributeHandle_t GetHandle( bool bCreate = true );
// estimate memory overhead
int EstimateMemoryUsage( TraversalDepth_t depth ) const;
private:
// Class factory
static CDmAttribute *CreateAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
static CDmAttribute *CreateExternalAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pExternalMemory );
static void DestroyAttribute( CDmAttribute *pAttribute );
// Constructor, destructor
CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pMemory );
~CDmAttribute();
// Used when constructing CDmAttributes
void Init( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
// Used when shutting down, indicates DmAttributeHandle_t referring to this are invalid
void InvalidateHandle();
// Called when the attribute changes
void OnChanged( bool bArrayCountChanged = false, bool bIsTopological = false );
// Is modification allowed in this phase?
bool ModificationAllowed() const;
// Mark the attribute as being dirty
bool MarkDirty();
// Is the data inline in a containing element class?
bool IsDataInline() const;
// Allocates, frees internal data storage
void CreateAttributeData();
void DeleteAttributeData();
// Gets at the internal data storage
void* GetAttributeData();
const void* GetAttributeData() const;
template < class T > typename CDmAttributeInfo< T >::StorageType_t* GetData();
template < class T > const typename CDmAttributeInfo< T >::StorageType_t* GetData() const;
template < class T > typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData();
template < class T > const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData() const;
// Used by CDmElement to manage the list of attributes it owns
CDmAttribute **GetNextAttributeRef();
// Implementational function used for memory consumption estimation computation
int EstimateMemoryUsageInternal( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories ) const;
// Called by elements after unserialization of their attributes is complete
void OnUnserializationFinished();
template< class T > bool IsTypeConvertable() const;
template< class T > bool ShouldModify( const T& src );
template< class T > void CopyData( const T& src );
template< class T > void CopyDataOut( T& dest ) const;
private:
CDmAttribute *m_pNext;
void *m_pData;
CDmElement *m_pOwner;
DmAttributeHandle_t m_Handle;
uint16 m_nFlags;
CUtlSymbolLarge m_Name;
friend class CDmElement;
friend class CDmAttributeAccessor;
template< class T > friend class CDmrElementArray;
template< class E > friend class CDmrElementArrayConst;
template< class T > friend class CDmaArrayAccessor;
template< class T, class B > friend class CDmrDecorator;
template< class T, class B > friend class CDmrDecoratorConst;
template< class T > friend class CDmArrayAttributeOp;
};
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline DmAttributeType_t CDmAttribute::GetType() const
{
return (DmAttributeType_t)( m_nFlags & FATTRIB_TYPEMASK );
}
template< class T > inline bool CDmAttribute::IsA() const
{
return GetType() == CDmAttributeInfo< T >::AttributeType();
}
inline const char *CDmAttribute::GetName() const
{
return m_Name.String();
}
inline CUtlSymbolLarge CDmAttribute::GetNameSymbol() const
{
return m_Name;
}
//-----------------------------------------------------------------------------
// Iteration
//-----------------------------------------------------------------------------
inline CDmAttribute *CDmAttribute::NextAttribute()
{
return m_pNext;
}
inline const CDmAttribute *CDmAttribute::NextAttribute() const
{
return m_pNext;
}
//-----------------------------------------------------------------------------
// Returns the owner
//-----------------------------------------------------------------------------
inline CDmElement *CDmAttribute::GetOwner()
{
return m_pOwner;
}
//-----------------------------------------------------------------------------
// Value getting methods
//-----------------------------------------------------------------------------
template< class T >
inline const T& CDmAttribute::GetValue( const T& defaultValue ) const
{
if ( (int)GetType() == (int)CDmAttributeInfo< T >::ATTRIBUTE_TYPE )
return *reinterpret_cast< const T* >( m_pData );
if ( IsTypeConvertable< T >() )
{
static T tempVal;
CopyDataOut( tempVal );
return tempVal;
}
Assert( 0 );
return defaultValue;
}
template< class T >
inline const T& CDmAttribute::GetValue() const
{
static CDmaVar< T > defaultVal;
return GetValue( defaultVal.Get() );
}
inline const char *CDmAttribute::GetValueString() const
{
Assert( GetType() == AT_STRING );
if ( GetType() != AT_STRING )
return NULL;
CUtlSymbolLarge symbol = GetValue< CUtlSymbolLarge >();
return symbol.String();
}
// used with GetType() for use w/ SetValue( type, void* )
inline const void* CDmAttribute::GetValueUntyped() const
{
return m_pData;
}
#ifndef POSIX
template< class E >
inline E* CDmAttribute::GetValueElement() const
{
Assert( GetType() == AT_ELEMENT );
if ( GetType() == AT_ELEMENT )
return GetElement<E>( this->GetValue<DmElementHandle_t>( ) );
return NULL;
}
#endif
//-----------------------------------------------------------------------------
// Value setting methods
//-----------------------------------------------------------------------------
template< class E >
inline void CDmAttribute::SetValue( E* pValue )
{
Assert( GetType() == AT_ELEMENT );
if ( GetType() == AT_ELEMENT )
{
SetValue( pValue ? pValue->GetHandle() : DMELEMENT_HANDLE_INVALID );
}
}
template<>
inline void CDmAttribute::SetValue( const char *pValue )
{
CUtlSymbolLarge symbol = g_pDataModel->GetSymbol( pValue );
return SetValue( symbol );
}
template<>
inline void CDmAttribute::SetValue( char *pValue )
{
return SetValue( (const char *)pValue );
}
inline void CDmAttribute::SetValue( const void *pValue, size_t nSize )
{
CUtlBinaryBlock buf( pValue, nSize );
return SetValue( buf );
}
//-----------------------------------------------------------------------------
// Methods related to flags
//-----------------------------------------------------------------------------
inline void CDmAttribute::AddFlag( int nFlags )
{
m_nFlags |= ( nFlags & ~FATTRIB_TYPEMASK );
}
inline void CDmAttribute::RemoveFlag( int nFlags )
{
m_nFlags &= ~nFlags | FATTRIB_TYPEMASK;
}
inline void CDmAttribute::ClearFlags()
{
RemoveFlag( 0xffffffff );
}
inline int CDmAttribute::GetFlags() const
{
return m_nFlags & ~FATTRIB_TYPEMASK;
}
inline bool CDmAttribute::IsFlagSet( int nFlags ) const
{
return ( nFlags & GetFlags() ) != 0;
}
inline bool CDmAttribute::IsDataInline() const
{
return !IsFlagSet( FATTRIB_EXTERNAL );
}
//-----------------------------------------------------------------------------
// Gets at the internal data storage
//-----------------------------------------------------------------------------
inline void* CDmAttribute::GetAttributeData()
{
return m_pData;
}
inline const void* CDmAttribute::GetAttributeData() const
{
return m_pData;
}
template < class T >
inline typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData()
{
return ( typename CDmAttributeInfo< T >::StorageType_t* )m_pData;
}
template < class T >
inline typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData()
{
return ( typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData;
}
template < class T >
inline const typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData() const
{
return ( const typename CDmAttributeInfo< T >::StorageType_t* )m_pData;
}
template < class T >
inline const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData() const
{
return ( const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData;
}
//-----------------------------------------------------------------------------
// Used by CDmElement to manage the list of attributes it owns
//-----------------------------------------------------------------------------
inline CDmAttribute **CDmAttribute::GetNextAttributeRef()
{
return &m_pNext;
}
//-----------------------------------------------------------------------------
// helper function for determining which attributes/elements to traverse during copy/find/save/etc.
//-----------------------------------------------------------------------------
inline bool ShouldTraverse( const CDmAttribute *pAttr, TraversalDepth_t depth )
{
switch ( depth )
{
case TD_NONE:
return false;
case TD_SHALLOW:
if ( !pAttr->IsFlagSet( FATTRIB_MUSTCOPY ) )
return false;
// fall-through intentional
case TD_DEEP:
if ( pAttr->IsFlagSet( FATTRIB_NEVERCOPY ) )
return false;
// fall-through intentional
case TD_ALL:
return true;
}
Assert( 0 );
return false;
}
#endif // DMATTRIBUTE_H

View File

@@ -0,0 +1,352 @@
//====== Copyright (c) 1996-2004, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef DMATTRIBUTETYPES_H
#define DMATTRIBUTETYPES_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/utlvector.h"
#include "tier1/utlstring.h"
#include "tier1/uniqueid.h"
#include "color.h"
#include "mathlib/vector2d.h"
#include "mathlib/vector.h"
#include "mathlib/vector4d.h"
#include "mathlib/vmatrix.h"
#include "datamodel/dmelementhandle.h"
#include "tier1/utlsymbollarge.h"
#include "tier1/timeutils.h"
//-----------------------------------------------------------------------------
// Object Id
//-----------------------------------------------------------------------------
typedef UniqueId_t DmObjectId_t;
//-----------------------------------------------------------------------------
// Necessary for template specialization for AT_UNKNOWN
//-----------------------------------------------------------------------------
struct DmUnknownAttribute_t
{
bool operator==( const DmUnknownAttribute_t& src ) const { return true; }
};
//-----------------------------------------------------------------------------
// Element array
//-----------------------------------------------------------------------------
struct DmElementAttribute_t
{
DmElementAttribute_t() : m_ElementType( UTL_INVAL_SYMBOL_LARGE ) {}
operator DmElementHandle_t&() { return m_Handle; }
operator const DmElementHandle_t&() const { return m_Handle; }
DmElementHandle_t m_Handle;
CUtlSymbolLarge m_ElementType;
};
struct DmElementArray_t : public CUtlVector< DmElementHandle_t >
{
DmElementArray_t() : m_ElementType( UTL_INVAL_SYMBOL_LARGE ) {}
CUtlSymbolLarge m_ElementType;
};
//-----------------------------------------------------------------------------
// Attribute chunk type enum
//-----------------------------------------------------------------------------
enum DmAttributeType_t
{
AT_UNKNOWN = 0,
AT_FIRST_VALUE_TYPE,
AT_ELEMENT = AT_FIRST_VALUE_TYPE,
AT_INT,
AT_FLOAT,
AT_BOOL,
AT_STRING,
AT_VOID,
AT_TIME,
AT_COLOR, //rgba
AT_VECTOR2,
AT_VECTOR3,
AT_VECTOR4,
AT_QANGLE,
AT_QUATERNION,
AT_VMATRIX,
AT_FIRST_ARRAY_TYPE,
AT_ELEMENT_ARRAY = AT_FIRST_ARRAY_TYPE,
AT_INT_ARRAY,
AT_FLOAT_ARRAY,
AT_BOOL_ARRAY,
AT_STRING_ARRAY,
AT_VOID_ARRAY,
AT_TIME_ARRAY,
AT_COLOR_ARRAY,
AT_VECTOR2_ARRAY,
AT_VECTOR3_ARRAY,
AT_VECTOR4_ARRAY,
AT_QANGLE_ARRAY,
AT_QUATERNION_ARRAY,
AT_VMATRIX_ARRAY,
AT_TYPE_COUNT,
AT_TYPE_INVALID,
};
const char *GetTypeString( DmAttributeType_t type );
inline bool IsValueType( DmAttributeType_t type )
{
return type >= AT_FIRST_VALUE_TYPE && type < AT_FIRST_ARRAY_TYPE;
}
inline bool IsArrayType( DmAttributeType_t type )
{
return type >= AT_FIRST_ARRAY_TYPE && type < AT_TYPE_COUNT;
}
inline bool IsTopological( DmAttributeType_t type )
{
return type == AT_ELEMENT || type == AT_ELEMENT_ARRAY;
}
inline DmAttributeType_t ValueTypeToArrayType( DmAttributeType_t type )
{
Assert( IsValueType( type ) );
return ( DmAttributeType_t )( ( type - AT_FIRST_VALUE_TYPE ) + AT_FIRST_ARRAY_TYPE );
}
inline DmAttributeType_t ArrayTypeToValueType( DmAttributeType_t type )
{
Assert( IsArrayType( type ) );
return ( DmAttributeType_t )( ( type - AT_FIRST_ARRAY_TYPE ) + AT_FIRST_VALUE_TYPE );
}
inline int NumComponents( DmAttributeType_t type )
{
switch ( type )
{
case AT_BOOL:
case AT_INT:
case AT_FLOAT:
case AT_TIME:
return 1;
case AT_VECTOR2:
return 2;
case AT_VECTOR3:
case AT_QANGLE:
return 3;
case AT_COLOR: //rgba
case AT_VECTOR4:
case AT_QUATERNION:
return 4;
case AT_VMATRIX:
return 16;
case AT_ELEMENT:
case AT_STRING:
case AT_VOID:
default:
return 0;
}
}
template< typename T >
inline float GetComponent( const T &value, int i )
{
Assert( 0 );
return 0.0f;
}
template <> inline float GetComponent( const bool &value, int i )
{
Assert( i == 0 );
return value ? 1.0f : 0.0f;
}
template <> inline float GetComponent( const int &value, int i )
{
Assert( i == 0 );
return float( value );
}
template <> inline float GetComponent( const float &value, int i )
{
Assert( i == 0 );
return value;
}
template <> inline float GetComponent( const DmeTime_t &value, int i )
{
Assert( i == 0 );
return value.GetSeconds();
}
template <> inline float GetComponent( const Vector2D &value, int i )
{
return value[ i ];
}
template <> inline float GetComponent( const Vector &value, int i )
{
return value[ i ];
}
template <> inline float GetComponent( const QAngle &value, int i )
{
return value[ i ];
}
template <> inline float GetComponent( const Color &value, int i )
{
return value[ i ];
}
template <> inline float GetComponent( const Vector4D &value, int i )
{
return value[ i ];
}
template <> inline float GetComponent( const Quaternion &value, int i )
{
return value[ i ];
}
template <> inline float GetComponent( const VMatrix &value, int i )
{
return value.Base()[ i ];
}
//-----------------------------------------------------------------------------
// Attribute info...
//-----------------------------------------------------------------------------
template <typename T>
class CDmAttributeInfo
{
private:
enum { ATTRIBUTE_TYPE = AT_TYPE_INVALID };
typedef T StorageType_t;
friend class CDmxAttribute;
static DmAttributeType_t AttributeType()
{
return AT_TYPE_INVALID;
}
static const char *AttributeTypeName()
{
return "invalid";
}
static void SetDefaultValue( T& value )
{
Assert(0);
}
};
template <>
class CDmAttributeInfo< DmUnknownAttribute_t >
{
public:
enum { ATTRIBUTE_TYPE = AT_UNKNOWN };
typedef DmUnknownAttribute_t StorageType_t;
static DmAttributeType_t AttributeType()
{
return AT_UNKNOWN;
}
static const char *AttributeTypeName()
{
return "unknown";
}
static void SetDefaultValue( DmUnknownAttribute_t& value )
{
Assert(0);
}
};
#define DECLARE_ATTRIBUTE_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName, _defaultSetStatement ) \
template< > class CDmAttributeInfo< _className > \
{ \
public: \
enum { ATTRIBUTE_TYPE = _attributeType }; \
typedef _storageType StorageType_t; \
static DmAttributeType_t AttributeType() { return _attributeType; } \
static const char *AttributeTypeName() { return _attributeName; } \
static void SetDefaultValue( _className& value ) { _defaultSetStatement } \
}; \
#define DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName ) \
template< > class CDmAttributeInfo< CUtlVector<_className> > \
{ \
public: \
enum { ATTRIBUTE_TYPE = _attributeType }; \
typedef _storageType StorageType_t; \
static DmAttributeType_t AttributeType() { return _attributeType; } \
static const char *AttributeTypeName() { return _attributeName; } \
static void SetDefaultValue( CUtlVector< _className >& value ) { value.RemoveAll(); } \
}; \
#define DECLARE_ATTRIBUTE_TYPE( _className, _attributeType, _attributeName, _defaultSetStatement ) \
DECLARE_ATTRIBUTE_TYPE_INTERNAL( _className, _className, _attributeType, _attributeName, _defaultSetStatement )
#define DECLARE_ATTRIBUTE_ARRAY_TYPE( _className, _attributeType, _attributeName )\
DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, CUtlVector< _className >, _attributeType, _attributeName )
// NOTE: If you add an attribute type here, also add it to the list of DEFINE_ATTRIBUTE_TYPES in dmattribute.cpp
DECLARE_ATTRIBUTE_TYPE( int, AT_INT, "int", value = 0; )
DECLARE_ATTRIBUTE_TYPE( float, AT_FLOAT, "float", value = 0.0f; )
DECLARE_ATTRIBUTE_TYPE( bool, AT_BOOL, "bool", value = false; )
DECLARE_ATTRIBUTE_TYPE( Color, AT_COLOR, "color", value.SetColor( 0, 0, 0, 255 ); )
DECLARE_ATTRIBUTE_TYPE( Vector2D, AT_VECTOR2, "vector2", value.Init( 0.0f, 0.0f ); )
DECLARE_ATTRIBUTE_TYPE( Vector, AT_VECTOR3, "vector3", value.Init( 0.0f, 0.0f, 0.0f ); )
DECLARE_ATTRIBUTE_TYPE( Vector4D, AT_VECTOR4, "vector4", value.Init( 0.0f, 0.0f, 0.0f, 0.0f ); )
DECLARE_ATTRIBUTE_TYPE( QAngle, AT_QANGLE, "qangle", value.Init( 0.0f, 0.0f, 0.0f ); )
DECLARE_ATTRIBUTE_TYPE( Quaternion, AT_QUATERNION, "quaternion", value.Init( 0.0f, 0.0f, 0.0f, 1.0f ); )
DECLARE_ATTRIBUTE_TYPE( VMatrix, AT_VMATRIX, "matrix", MatrixSetIdentity( value ); )
DECLARE_ATTRIBUTE_TYPE( CUtlSymbolLarge, AT_STRING, "string", value = UTL_INVAL_SYMBOL_LARGE; )
DECLARE_ATTRIBUTE_TYPE( CUtlBinaryBlock, AT_VOID, "binary", value.Set( NULL, 0 ); )
DECLARE_ATTRIBUTE_TYPE( DmeTime_t, AT_TIME, "time", value.SetTenthsOfMS( 0 ); )
DECLARE_ATTRIBUTE_TYPE_INTERNAL( DmElementHandle_t, DmElementAttribute_t, AT_ELEMENT, "element", value = DMELEMENT_HANDLE_INVALID; )
DECLARE_ATTRIBUTE_ARRAY_TYPE( int, AT_INT_ARRAY, "int_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( float, AT_FLOAT_ARRAY, "float_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( bool, AT_BOOL_ARRAY, "bool_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( Color, AT_COLOR_ARRAY, "color_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector2D, AT_VECTOR2_ARRAY, "vector2_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector, AT_VECTOR3_ARRAY, "vector3_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector4D, AT_VECTOR4_ARRAY, "vector4_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( QAngle, AT_QANGLE_ARRAY, "qangle_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( Quaternion, AT_QUATERNION_ARRAY, "quaternion_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( VMatrix, AT_VMATRIX_ARRAY, "matrix_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( CUtlSymbolLarge, AT_STRING_ARRAY, "string_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( CUtlBinaryBlock, AT_VOID_ARRAY, "binary_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE( DmeTime_t, AT_TIME_ARRAY, "time_array" )
DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( DmElementHandle_t, DmElementArray_t, AT_ELEMENT_ARRAY, "element_array" )
#endif // DMATTRIBUTETYPES_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,263 @@
//========= Copyright <20> 1996-2005, Valve LLC, All rights reserved. ============
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DMEHANDLE_H
#define DMEHANDLE_H
#ifdef _WIN32
#pragma once
#endif
#include "datamodel/idatamodel.h"
#include "datamodel/dmelement.h"
//-----------------------------------------------------------------------------
// Purpose: CDmeHandle is a templatized wrapper around DmElementHandle_t
//-----------------------------------------------------------------------------
template< class DmeType, HandleType_t HandleType = HT_WEAK >
class CDmeHandle : public CDmeElementRefHelper
{
public:
CDmeHandle() : m_handle( DMELEMENT_HANDLE_INVALID )
{
}
explicit CDmeHandle( CDmElement *pObject ) : m_handle( DMELEMENT_HANDLE_INVALID )
{
Set( pObject );
}
CDmeHandle( DmElementHandle_t h ) : m_handle( DMELEMENT_HANDLE_INVALID )
{
Set( h );
}
CDmeHandle( const CDmeHandle< DmeType, HandleType > &handle ) : m_handle( DMELEMENT_HANDLE_INVALID )
{
Set( handle.m_handle );
}
template < class T, HandleType_t HT >
CDmeHandle( const CDmeHandle< T, HT > &handle ) : m_handle( DMELEMENT_HANDLE_INVALID )
{
DmeType *p = ( T* )NULL; // triggers compiler error if converting from invalid handle type
NOTE_UNUSED( p );
Set( handle.GetHandle() );
}
~CDmeHandle()
{
if ( !g_pDataModel )
return; // some handles are static, and don't get destroyed until program termination
Unref( m_handle, HandleType );
}
template < class T, HandleType_t HT >
CDmeHandle& operator=( const CDmeHandle< T, HT > &handle )
{
DmeType *p = ( T* )NULL; // triggers compiler error if converting from invalid handle type
NOTE_UNUSED( p );
Set( handle.GetHandle() );
return *this;
}
DmeType *Get()
{
return static_cast< DmeType* >( g_pDataModel->GetElement( m_handle ) );
}
const DmeType *Get() const
{
return static_cast< DmeType* >( g_pDataModel->GetElement( m_handle ) );
}
DmElementHandle_t GetHandle() const
{
return m_handle;
}
void Set( CDmElement *pObject )
{
Set( pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID );
}
void Set( DmElementHandle_t h )
{
if ( h == m_handle )
return;
Unref( m_handle, HandleType );
m_handle = h;
if ( h != DMELEMENT_HANDLE_INVALID )
{
CDmElement *pElement = g_pDataModel->GetElement( m_handle );
Assert( pElement );
if ( pElement && !pElement->IsA( DmeType::GetStaticTypeSymbol() ) )
{
m_handle = DMELEMENT_HANDLE_INVALID;
}
}
Ref( m_handle, HandleType );
}
operator DmeType*()
{
return Get();
}
operator const DmeType*() const
{
return Get();
}
operator DmElementHandle_t() const
{
return m_handle;
}
DmeType* operator->()
{
return Get();
}
const DmeType* operator->() const
{
return Get();
}
CDmeHandle& operator=( DmElementHandle_t h )
{
Set( h );
return *this;
}
CDmeHandle& operator=( CDmElement *pObject )
{
Set( pObject );
return *this;
}
bool operator==( const CDmeHandle< DmeType > &h ) const
{
return m_handle == h.m_handle;
}
bool operator!=( const CDmeHandle< DmeType > &h ) const
{
return !operator==( h );
}
bool operator<( const CDmeHandle< DmeType > &h ) const
{
return m_handle < h.m_handle;
}
bool operator==( DmeType *pObject ) const
{
DmElementHandle_t h = pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID;
return m_handle == h;
}
bool operator!=( DmeType *pObject ) const
{
return !operator==( pObject );
}
bool operator==( DmElementHandle_t h ) const
{
return ( m_handle == h );
}
bool operator!=( DmElementHandle_t h ) const
{
return ( m_handle != h );
}
operator bool() const
{
return ( Get() != NULL );
}
bool operator!() const
{
return ( Get() == NULL );
}
private:
DmElementHandle_t m_handle;
};
typedef CDmeHandle< CDmElement, HT_STRONG > CDmeCountedHandle;
typedef CDmeHandle< CDmElement, HT_UNDO > CDmeUndoHandle;
//-----------------------------------------------------------------------------
// Vector of element handles
//-----------------------------------------------------------------------------
typedef CUtlVector< CDmeHandle<CDmElement> > DmeHandleVec_t;
// NOTE: these methods only append, so if there is already data in the list, it will remain
template< typename T >
inline void ConvertHandleToPtrVector( const CUtlVector< CDmeHandle< T > > &in, CUtlVector< T * > &out )
{
int c = in.Count();
for ( int i = 0; i < c; ++i )
{
out.AddToTail( in[ i ].Get() );
}
}
template< typename T >
inline void ConvertPtrToHandleVector( const CUtlVector< T * > &in, CUtlVector< CDmeHandle< T > > &out )
{
int c = in.Count();
for ( int i = 0; i < c; ++i )
{
out.AddToTail( CDmeHandle< T >( in[ i ] ) );
}
}
//-----------------------------------------------------------------------------
// helper class for undo classes to allow them to hold onto refcounted element handles
//-----------------------------------------------------------------------------
template< typename T >
class CDmAttributeUndoStorageType
{
public:
typedef T UndoStorageType;
};
template<>
class CDmAttributeUndoStorageType< DmElementHandle_t >
{
public:
typedef CDmeUndoHandle UndoStorageType;
};
template<>
class CDmAttributeUndoStorageType< CUtlVector< DmElementHandle_t > >
{
public:
typedef CUtlVector< CDmeUndoHandle > UndoStorageType;
};
#endif // DMEHANDLE_H

1210
public/datamodel/dmelement.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
//====== Copyright <20> 1996-2004, Valve Corporation, All rights reserved. =======
//http://www.nfl.com/gamecenter/2010010900/2009/POST18/eagles@cowboys#tab:watch
// Purpose:
//
//=============================================================================
#ifndef DMELEMENTFACTORYHELPER_H
#define DMELEMENTFACTORYHELPER_H
#ifdef _WIN32
#pragma once
#endif
#include "datamodel/idatamodel.h"
#include "datamodel/dmelement.h"
#include "datamodel/dmattribute.h"
#include "datamodel/dmattributevar.h"
#include "tier1/utlvector.h"
#include "tier1/utlsymbollarge.h"
//-----------------------------------------------------------------------------
// Internal interface for IDmElementFactory
//-----------------------------------------------------------------------------
class CDmElementFactoryInternal : public IDmElementFactory
{
public:
virtual void SetElementTypeSymbol( CUtlSymbolLarge sym ) = 0;
virtual bool IsAbstract() const = 0;
virtual CUtlSymbolLarge GetElementTypeSymbol() const = 0;
virtual CUtlSymbolLarge GetParentElementTypeSymbol() const = 0;
virtual void AddOnElementCreatedCallback( IDmeElementCreated *pCallback );
virtual void RemoveOnElementCreatedCallback( IDmeElementCreated *pCallback );
virtual void OnElementCreated( CDmElement* pElement );
private:
CUtlVector< IDmeElementCreated* > m_CallBackList;
};
//-----------------------------------------------------------------------------
// Class used to register factories into a global list
//-----------------------------------------------------------------------------
class CDmElementFactoryHelper
{
public:
// Static list of helpers
static CDmElementFactoryHelper *s_pHelpers[2];
// Create all the hud elements
static void InstallFactories( );
public:
// Construction
CDmElementFactoryHelper( const char *pClassName, CDmElementFactoryInternal *pFactory, bool bIsStandardFactory );
// Accessors
CDmElementFactoryHelper *GetNext () { return m_pNext; }
CDmElementFactoryHelper *GetParent () { return m_pParent; }
CDmElementFactoryHelper *GetChild () { return m_pChild; }
CDmElementFactoryHelper *GetSibling() { return m_pSibling; }
const char *GetClassname();
CDmElementFactoryInternal *GetFactory();
private:
CDmElementFactoryHelper() {}
// Next factory in list
CDmElementFactoryHelper *m_pNext;
// class hierarchy links
CDmElementFactoryHelper *m_pParent;
CDmElementFactoryHelper *m_pChild;
CDmElementFactoryHelper *m_pSibling;
// Creation function to use for this technology
CDmElementFactoryInternal *m_pFactory;
const char *m_pszClassname;
};
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline const char *CDmElementFactoryHelper::GetClassname()
{
return m_pszClassname;
}
inline CDmElementFactoryInternal *CDmElementFactoryHelper::GetFactory()
{
return m_pFactory;
}
//-----------------------------------------------------------------------------
// Helper Template factory for simple creation of factories
//-----------------------------------------------------------------------------
template < class T >
class CDmElementFactory : public CDmElementFactoryInternal
{
public:
CDmElementFactory( const char *pLookupName ) : m_pLookupName( pLookupName ) {}
// Creation, destruction
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id )
{
return new T( handle, m_pLookupName, id, pElementName, fileid );
}
virtual void Destroy( DmElementHandle_t hElement )
{
CDmElement *pElement = g_pDataModel->GetElement( hElement );
if ( pElement )
{
T *pActualElement = static_cast< T* >( pElement );
delete pActualElement;
}
}
// Sets the type symbol, used for "isa" implementation
virtual void SetElementTypeSymbol( CUtlSymbolLarge sym )
{
T::SetTypeSymbol( sym );
}
virtual bool IsAbstract() const { return false; }
virtual CUtlSymbolLarge GetElementTypeSymbol() const
{
return T::GetStaticTypeSymbol();
}
virtual CUtlSymbolLarge GetParentElementTypeSymbol() const
{
CUtlSymbolLarge baseClassSym = T::BaseClass::GetStaticTypeSymbol();
if ( baseClassSym == T::GetStaticTypeSymbol() )
return UTL_INVAL_SYMBOL_LARGE; // only CDmElement has itself as it's BaseClass - this lets us know we're at the top of the hierarchy
return baseClassSym;
}
private:
const char *m_pLookupName;
};
template < class T >
class CDmAbstractElementFactory : public CDmElementFactoryInternal
{
public:
CDmAbstractElementFactory() {}
// Creation, destruction
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id )
{
return NULL;
}
virtual void Destroy( DmElementHandle_t hElement )
{
}
// Sets the type symbol, used for "isa" implementation
virtual void SetElementTypeSymbol( CUtlSymbolLarge sym )
{
T::SetTypeSymbol( sym );
}
virtual bool IsAbstract() const { return true; }
virtual CUtlSymbolLarge GetElementTypeSymbol() const
{
return T::GetStaticTypeSymbol();
}
virtual CUtlSymbolLarge GetParentElementTypeSymbol() const
{
CUtlSymbolLarge baseClassSym = T::BaseClass::GetStaticTypeSymbol();
if ( baseClassSym == T::GetStaticTypeSymbol() )
return UTL_INVAL_SYMBOL_LARGE; // only CDmElement has itself as it's BaseClass - this lets us know we're at the top of the hierarchy
return baseClassSym;
}
private:
};
//-----------------------------------------------------------------------------
// Helper macro to create the class factory
//-----------------------------------------------------------------------------
#if defined( MOVIEOBJECTS_LIB ) || defined ( DATAMODEL_LIB ) || defined ( DMECONTROLS_LIB ) || defined ( MDLOBJECTS_LIB )
#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \
className *g_##className##LinkerHack = NULL;
#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmAbstractElementFactory< className > g_##className##_Factory; \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \
className *g_##className##LinkerHack = NULL;
#else
#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
className *g_##className##LinkerHack = NULL;
#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmAbstractElementFactory< className > g_##className##_Factory; \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
className *g_##className##LinkerHack = NULL;
#endif
// Used by classes defined in movieobjects or scenedatabase that must be explicitly installed
#define IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
className *g_##className##LinkerHack = NULL;
//-----------------------------------------------------------------------------
// Used to instantiate classes in libs from dlls/exes
//-----------------------------------------------------------------------------
#define USING_ELEMENT_FACTORY( className ) \
extern C##className *g_##C##className##LinkerHack; \
C##className *g_##C##className##PullInModule = g_##C##className##LinkerHack;
//-----------------------------------------------------------------------------
// Installs dm element factories
//-----------------------------------------------------------------------------
void InstallDmElementFactories( );
#endif // DMELEMENTFACTORYHELPER_H

View File

@@ -0,0 +1,47 @@
//====== Copyright <20> 1996-2004, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef DMELEMENTHANDLE_H
#define DMELEMENTHANDLE_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// handle to an CDmElement
//-----------------------------------------------------------------------------
#define PERFORM_HANDLE_TYPECHECKING 0
#if PERFORM_HANDLE_TYPECHECKING
// this is here to make sure we're being type-safe about element handles
// otherwise, the compiler lets us cast to bool incorrectly
// the other solution would be to redefine DmElementHandle_t s.t. DMELEMENT_HANDLE_INVALID==0
struct DmElementHandle_t
{
DmElementHandle_t() : handle( 0xffffffff ) {}
explicit DmElementHandle_t( int h ) : handle( h ) {}
inline bool operator==( const DmElementHandle_t &h ) const { return handle == h.handle; }
inline bool operator!=( const DmElementHandle_t &h ) const { return handle != h.handle; }
inline bool operator<( const DmElementHandle_t &h ) const { return handle < h.handle; }
// inline operator int() const { return handle; } // if we're okay with implicit int casts, uncomment this method
int handle;
};
const DmElementHandle_t DMELEMENT_HANDLE_INVALID;
#else // PERFORM_HANDLE_TYPECHECKING
enum DmElementHandle_t
{
DMELEMENT_HANDLE_INVALID = 0xffffffff
};
#endif // PERFORM_HANDLE_TYPECHECKING
#endif // DMELEMENTHANDLE_H

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