diff --git a/common/qlimits.h b/common/qlimits.h index 839cd75b..9afc984a 100644 --- a/common/qlimits.h +++ b/common/qlimits.h @@ -24,7 +24,7 @@ // Resource counts; -#define MAX_MODEL_INDEX_BITS 11 // sent as a short +#define MAX_MODEL_INDEX_BITS 12 // sent as a short #define MAX_MODELS (1<= 0 ) @@ -3948,33 +3939,21 @@ void C_BaseAnimating::FireObsoleteEvent( const Vector& origin, const QAngle& ang // Obsolete. Use the AE_CL_CREATE_PARTICLE_EFFECT event instead, which uses the artist driven particle system & editor. case AE_CLIENT_EFFECT_ATTACH: { - int iAttachment = -1; - int iParam = 0; + int iAttachment; + int iParam; char token[128]; char effectFunc[128]; const char *p = options; p = nexttoken(token, p, ' '); - - if( token ) - { - Q_strncpy( effectFunc, token, sizeof(effectFunc) ); - } + Q_strncpy( effectFunc, token, sizeof(effectFunc) ); p = nexttoken(token, p, ' '); - - if( token ) - { - iAttachment = atoi(token); - } + iAttachment = token[0] ? atoi(token) : -1; p = nexttoken(token, p, ' '); - - if( token ) - { - iParam = atoi(token); - } + iParam = token[0] ? atoi(token) : 0; if ( iAttachment != -1 && m_Attachments.Count() >= iAttachment ) { @@ -5279,8 +5258,9 @@ float C_BaseAnimating::FrameAdvance( float flInterval ) // Stubs for weapon prediction void C_BaseAnimating::ResetSequenceInfo( void ) { - if (GetSequence() == -1) + if ( GetSequence() == -1 ) { + // This shouldn't happen. Setting m_nSequence blindly is a horrible coding practice. SetSequence( 0 ); } @@ -5292,17 +5272,20 @@ void C_BaseAnimating::ResetSequenceInfo( void ) CStudioHdr *pStudioHdr = GetModelPtr(); m_flGroundSpeed = GetSequenceGroundSpeed( pStudioHdr, GetSequence() ) * GetModelScale(); - m_bSequenceLoops = ((GetSequenceFlags( pStudioHdr, GetSequence() ) & STUDIO_LOOPING) != 0); + m_bSequenceLoops = ( ( GetSequenceFlags( pStudioHdr, GetSequence() ) & STUDIO_LOOPING ) != 0 ); // m_flAnimTime = gpGlobals->time; m_flPlaybackRate = 1.0; m_bSequenceFinished = false; m_flLastEventCheck = 0; - m_nNewSequenceParity = ( ++m_nNewSequenceParity ) & EF_PARITY_MASK; - m_nResetEventsParity = ( ++m_nResetEventsParity ) & EF_PARITY_MASK; - + m_nNewSequenceParity = ( m_nNewSequenceParity + 1 ) & EF_PARITY_MASK; + m_nResetEventsParity = ( m_nResetEventsParity + 1 ) & EF_PARITY_MASK; + // FIXME: why is this called here? Nothing should have changed to make this nessesary - SetEventIndexForSequence( pStudioHdr->pSeqdesc( GetSequence() ) ); + if ( pStudioHdr ) + { + SetEventIndexForSequence( pStudioHdr->pSeqdesc( GetSequence() ) ); + } } //========================================================= diff --git a/game/client/c_baseentity.cpp b/game/client/c_baseentity.cpp index 074955fc..7521a394 100644 --- a/game/client/c_baseentity.cpp +++ b/game/client/c_baseentity.cpp @@ -571,7 +571,8 @@ void SpewInterpolatedVar( CInterpolatedVar< Vector > *pVar ) { Msg( "--------------------------------------------------\n" ); int i = pVar->GetHead(); - CApparentVelocity apparent; + Vector v0(0, 0, 0); + CApparentVelocity apparent(v0); float prevtime = 0.0f; while ( 1 ) { @@ -594,7 +595,8 @@ void SpewInterpolatedVar( CInterpolatedVar< Vector > *pVar, float flNow, float f Msg( "--------------------------------------------------\n" ); int i = pVar->GetHead(); - CApparentVelocity apparent; + Vector v0(0, 0, 0); + CApparentVelocity apparent(v0); float newtime = 999999.0f; Vector newVec( 0, 0, 0 ); bool bSpew = true; @@ -662,7 +664,7 @@ void SpewInterpolatedVar( CInterpolatedVar< float > *pVar ) { Msg( "--------------------------------------------------\n" ); int i = pVar->GetHead(); - CApparentVelocity apparent; + CApparentVelocity apparent(0.0f); while ( 1 ) { float changetime; @@ -684,7 +686,8 @@ void GetInterpolatedVarTimeRange( CInterpolatedVar *pVar, float &flMin, float flMax = -1e23; int i = pVar->GetHead(); - CApparentVelocity apparent; + Vector v0(0, 0, 0); + CApparentVelocity apparent(v0); while ( 1 ) { float changetime; @@ -892,6 +895,8 @@ C_BaseEntity::C_BaseEntity() : m_iv_angRotation( "C_BaseEntity::m_iv_angRotation" ), m_iv_vecVelocity( "C_BaseEntity::m_iv_vecVelocity" ) { + m_pAttributes = NULL; + AddVar( &m_vecOrigin, &m_iv_vecOrigin, LATCH_SIMULATION_VAR ); AddVar( &m_angRotation, &m_iv_angRotation, LATCH_SIMULATION_VAR ); // Removing this until we figure out why velocity introduces view hitching. @@ -1299,19 +1304,6 @@ bool C_BaseEntity::VPhysicsIsFlesh( void ) return false; } -//----------------------------------------------------------------------------- -// Returns the health fraction -//----------------------------------------------------------------------------- -float C_BaseEntity::HealthFraction() const -{ - if (GetMaxHealth() == 0) - return 1.0f; - - float flFraction = (float)GetHealth() / (float)GetMaxHealth(); - flFraction = clamp( flFraction, 0.0f, 1.0f ); - return flFraction; -} - //----------------------------------------------------------------------------- // Purpose: Retrieves the coordinate frame for this entity. @@ -2624,6 +2616,25 @@ void C_BaseEntity::PostDataUpdate( DataUpdateType_t updateType ) } } +//----------------------------------------------------------------------------- +// Purpose: Latch simulation values when the entity has not changed +//----------------------------------------------------------------------------- +void C_BaseEntity::OnDataUnchangedInPVS() +{ + Interp_RestoreToLastNetworked( GetVarMapping() ); + + // For non-predicted and non-client only ents, we need to latch network values into the interpolation histories + if ( !GetPredictable() && !IsClientCreated() ) + { + OnLatchInterpolatedVariables( LATCH_SIMULATION_VAR ); + } + + Assert( m_hNetworkMoveParent.Get() || !m_hNetworkMoveParent.IsValid() ); + HierarchySetParent(m_hNetworkMoveParent); + + MarkMessageReceived(); +} + //----------------------------------------------------------------------------- // Purpose: // Input : *context - @@ -3741,7 +3752,7 @@ void C_BaseEntity::AddColoredDecal( const Vector& rayStart, const Vector& rayEnd case mod_brush: { - color32 cColor32 = { cColor.r(), cColor.g(), cColor.b(), cColor.a() }; + color32 cColor32 = { (byte)cColor.r(), (byte)cColor.g(), (byte)cColor.b(), (byte)cColor.a() }; effects->DecalColorShoot( decalIndex, index, model, GetAbsOrigin(), GetAbsAngles(), decalCenter, 0, 0, cColor32 ); } break; @@ -6309,6 +6320,9 @@ bool C_BaseEntity::ValidateEntityAttachedToPlayer( bool &bShouldRetry ) if ( FStrEq( pszModel, "models/props_lakeside_event/bomb_temp_hat.mdl" ) ) return true; + + if ( FStrEq( pszModel, "models/props_moonbase/powersupply_flag.mdl" ) ) + return true; } // Any entity that's not an item parented to a player is invalid. diff --git a/game/client/c_baseentity.h b/game/client/c_baseentity.h index e00513df..c3504bcc 100644 --- a/game/client/c_baseentity.h +++ b/game/client/c_baseentity.h @@ -58,6 +58,7 @@ class C_BaseCombatCharacter; class CEntityMapData; class ConVar; class CDmgAccumulator; +class IHasAttributes; struct CSoundParameters; @@ -335,6 +336,7 @@ public: // save out interpolated values virtual void PreDataUpdate( DataUpdateType_t updateType ); virtual void PostDataUpdate( DataUpdateType_t updateType ); + virtual void OnDataUnchangedInPVS(); virtual void ValidateModelIndex( void ); @@ -516,6 +518,7 @@ public: // Used when the collision prop is told to ask game code for the world-space surrounding box virtual void ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs ); + virtual float GetHealthBarHeightOffset() const { return 0.f; } // Returns the entity-to-world transform matrix3x4_t &EntityToWorldTransform(); @@ -686,7 +689,7 @@ public: virtual bool ShouldDraw(); inline bool IsVisible() const { return m_hRender != INVALID_CLIENT_RENDER_HANDLE; } - void UpdateVisibility(); + virtual void UpdateVisibility(); // Returns true if the entity changes its position every frame on the server but it doesn't // set animtime. In that case, the client returns true here so it copies the server time to @@ -743,7 +746,8 @@ public: virtual void SetHealth(int iHealth) {} virtual int GetHealth() const { return 0; } virtual int GetMaxHealth() const { return 1; } - virtual bool IsVisibleToTargetID( void ) { return false; } + virtual bool IsVisibleToTargetID( void ) const { return false; } + virtual bool IsHealthBarVisible( void ) const { return false; } // Returns the health fraction float HealthFraction() const; @@ -1172,7 +1176,17 @@ public: // Sets the origin + angles to match the last position received void MoveToLastReceivedPosition( bool force = false ); + // Return the IHasAttributes interface for this base entity. Removes the need for: + // dynamic_cast< IHasAttributes * >( pEntity ); + // Which is remarkably slow. + // GetAttribInterface( CBaseEntity *pEntity ) in attribute_manager.h uses + // this function, tests for NULL, and Asserts m_pAttributes == dynamic_cast. + inline IHasAttributes *GetHasAttributesInterfacePtr() const { return m_pAttributes; } + protected: + // NOTE: m_pAttributes needs to be set in the leaf class constructor. + IHasAttributes *m_pAttributes; + // Only meant to be called from subclasses void DestroyModelInstance(); diff --git a/game/client/c_baseflex.cpp b/game/client/c_baseflex.cpp index bd2461fb..c6675b32 100644 --- a/game/client/c_baseflex.cpp +++ b/game/client/c_baseflex.cpp @@ -562,11 +562,11 @@ Vector C_BaseFlex::SetViewTarget( CStudioHdr *pStudioHdr ) m_iEyeUpdown = FindFlexController( "eyes_updown" ); m_iEyeRightleft = FindFlexController( "eyes_rightleft" ); - if ( m_iEyeUpdown != -1 ) + if ( m_iEyeUpdown != LocalFlexController_t(-1) ) { pStudioHdr->pFlexcontroller( m_iEyeUpdown )->localToGlobal = AddGlobalFlexController( "eyes_updown" ); } - if ( m_iEyeRightleft != -1 ) + if ( m_iEyeRightleft != LocalFlexController_t(-1) ) { pStudioHdr->pFlexcontroller( m_iEyeRightleft )->localToGlobal = AddGlobalFlexController( "eyes_rightleft" ); } @@ -594,13 +594,13 @@ Vector C_BaseFlex::SetViewTarget( CStudioHdr *pStudioHdr ) // calculate animated eye deflection Vector eyeDeflect; QAngle eyeAng( 0, 0, 0 ); - if ( m_iEyeUpdown != -1 ) + if ( m_iEyeUpdown != LocalFlexController_t(-1) ) { mstudioflexcontroller_t *pflex = pStudioHdr->pFlexcontroller( m_iEyeUpdown ); eyeAng.x = g_flexweight[ pflex->localToGlobal ]; } - if ( m_iEyeRightleft != -1 ) + if ( m_iEyeRightleft != LocalFlexController_t(-1) ) { mstudioflexcontroller_t *pflex = pStudioHdr->pFlexcontroller( m_iEyeRightleft ); eyeAng.y = g_flexweight[ pflex->localToGlobal ]; @@ -1057,7 +1057,7 @@ void C_BaseFlex::GetToolRecordingState( KeyValues *msg ) Vector viewtarget = m_viewtarget; // Use the unfiltered value // HACK HACK: Unmap eyes right/left amounts - if (m_iEyeUpdown != -1 && m_iEyeRightleft != -1) + if (m_iEyeUpdown != LocalFlexController_t(-1) && m_iEyeRightleft != LocalFlexController_t(-1)) { mstudioflexcontroller_t *flexupdown = hdr->pFlexcontroller( m_iEyeUpdown ); mstudioflexcontroller_t *flexrightleft = hdr->pFlexcontroller( m_iEyeRightleft ); diff --git a/game/client/c_basetempentity.h b/game/client/c_basetempentity.h index ffc742af..c1313c52 100644 --- a/game/client/c_basetempentity.h +++ b/game/client/c_basetempentity.h @@ -55,6 +55,7 @@ public: virtual void NotifyShouldTransmit( ShouldTransmitState_t state ); virtual void PreDataUpdate( DataUpdateType_t updateType ); virtual void PostDataUpdate( DataUpdateType_t updateType ); + virtual void OnDataUnchangedInPVS( void ) { } virtual void OnPreDataChanged( DataUpdateType_t updateType ); virtual void OnDataChanged( DataUpdateType_t updateType ); virtual void SetDormant( bool bDormant ); diff --git a/game/client/c_baseviewmodel.cpp b/game/client/c_baseviewmodel.cpp index 0999fee0..2dad4088 100644 --- a/game/client/c_baseviewmodel.cpp +++ b/game/client/c_baseviewmodel.cpp @@ -192,7 +192,7 @@ bool C_BaseViewModel::Interpolate( float currentTime ) } -inline bool C_BaseViewModel::ShouldFlipViewModel() +bool C_BaseViewModel::ShouldFlipViewModel() { #ifdef CSTRIKE_DLL // If cl_righthand is set, then we want them all right-handed. diff --git a/game/client/c_colorcorrection.cpp b/game/client/c_colorcorrection.cpp index 3a6f9ce8..91cb1946 100644 --- a/game/client/c_colorcorrection.cpp +++ b/game/client/c_colorcorrection.cpp @@ -122,7 +122,7 @@ void C_ColorCorrection::ClientThink() return; } - CBaseEntity *pPlayer = UTIL_PlayerByIndex(1); + C_BaseEntity *pPlayer = C_BasePlayer::GetLocalPlayer(); if( !pPlayer ) return; diff --git a/game/client/c_entitydissolve.cpp b/game/client/c_entitydissolve.cpp index d8e12616..a30fa43c 100644 --- a/game/client/c_entitydissolve.cpp +++ b/game/client/c_entitydissolve.cpp @@ -575,7 +575,10 @@ void C_EntityDissolve::ClientThink( void ) #ifdef TF_CLIENT_DLL else { - pEnt->Release(); + // Hide the ragdoll -- don't actually delete it or else things get unhappy when + // we get a message from the server telling us to delete it + pEnt->AddEffects( EF_NODRAW ); + pEnt->ParticleProp()->StopEmission(); } #endif } diff --git a/game/client/c_func_breakablesurf.cpp b/game/client/c_func_breakablesurf.cpp index a253ba52..721a7e23 100644 --- a/game/client/c_func_breakablesurf.cpp +++ b/game/client/c_func_breakablesurf.cpp @@ -154,7 +154,7 @@ private: Assert( type < NUM_EDGE_STYLES ); Assert( type >= 0 ); // Clear old value - m_nPanelBits[ w ][ h ] &= ( ~0x03 << 2 ); + m_nPanelBits[ w ][ h ] &= 0xF0; // ( ~0x03 << 2 ); Left shifting a negative value has undefined behavior. Use the constant 0xF0 instead. // Insert new value m_nPanelBits[ w ][ h ] |= ( type << 2 ); } diff --git a/game/client/c_particle_system.cpp b/game/client/c_particle_system.cpp index fc70c8aa..efdea476 100644 --- a/game/client/c_particle_system.cpp +++ b/game/client/c_particle_system.cpp @@ -198,12 +198,19 @@ void ParticleEffectCallback( const CEffectData &data ) pEnt->ParticleProp()->StopEmission(); } - pEffect = pEnt->ParticleProp()->Create( pszName, (ParticleAttachment_t)data.m_nDamageType, data.m_nAttachmentIndex ); + Vector vOffset = vec3_origin; + ParticleAttachment_t iAttachType = (ParticleAttachment_t)data.m_nDamageType; + if ( iAttachType == PATTACH_ABSORIGIN_FOLLOW || iAttachType == PATTACH_POINT_FOLLOW || iAttachType == PATTACH_ROOTBONE_FOLLOW ) + { + vOffset = data.m_vStart; + } + + pEffect = pEnt->ParticleProp()->Create( pszName, iAttachType, data.m_nAttachmentIndex, vOffset ); AssertMsg2( pEffect.IsValid() && pEffect->IsValid(), "%s could not create particle effect %s", C_BaseEntity::Instance( data.m_hEntity )->GetDebugName(), pszName ); if ( pEffect.IsValid() && pEffect->IsValid() ) { - if ( (ParticleAttachment_t)data.m_nDamageType == PATTACH_CUSTOMORIGIN ) + if ( iAttachType == PATTACH_CUSTOMORIGIN ) { pEffect->SetSortOrigin( data.m_vOrigin ); pEffect->SetControlPoint( 0, data.m_vOrigin ); diff --git a/game/client/c_rope.cpp b/game/client/c_rope.cpp index 77389bd0..e17f2b9a 100644 --- a/game/client/c_rope.cpp +++ b/game/client/c_rope.cpp @@ -193,7 +193,7 @@ public: if( pReturn == NULL ) { int iMaxSize = m_QueuedRopeMemory[m_nCurrentStack].GetMaxSize(); - Warning( "Overflowed rope queued rendering memory stack. Needed %d, have %d/%d\n", bytes, iMaxSize - m_QueuedRopeMemory[m_nCurrentStack].GetUsed(), iMaxSize ); + Warning( "Overflowed rope queued rendering memory stack. Needed %llu, have %d/%d\n", (uint64)bytes, iMaxSize - m_QueuedRopeMemory[m_nCurrentStack].GetUsed(), iMaxSize ); pReturn = malloc( bytes ); m_DeleteOnSwitch[m_nCurrentStack].AddToTail( pReturn ); } diff --git a/game/client/c_sceneentity.cpp b/game/client/c_sceneentity.cpp index d56a67c8..74dd0032 100644 --- a/game/client/c_sceneentity.cpp +++ b/game/client/c_sceneentity.cpp @@ -214,11 +214,11 @@ void C_SceneEntity::SetupClientOnlyScene( const char *pszFilename, C_BaseFlex *p V_strcpy( szFilename, szSceneHWM ); } - Assert( szFilename && szFilename[ 0 ] ); - if ( szFilename && szFilename[ 0 ] ) + Assert( szFilename[ 0 ] ); + if ( szFilename[ 0 ] ) { LoadSceneFromFile( szFilename ); - + if (!CommandLine()->FindParm("-hushasserts")) { Assert( m_pScene ); @@ -335,8 +335,8 @@ void C_SceneEntity::PostDataUpdate( DataUpdateType_t updateType ) if ( updateType == DATA_UPDATE_CREATED ) { - Assert( szFilename && szFilename[ 0 ] ); - if ( szFilename && szFilename[ 0 ] ) + Assert( szFilename[ 0 ] ); + if ( szFilename[ 0 ] ) { LoadSceneFromFile( szFilename ); @@ -373,6 +373,8 @@ void C_SceneEntity::PostDataUpdate( DataUpdateType_t updateType ) SetNextClientThink( CLIENT_THINK_ALWAYS ); } + + m_bWasPlaying = !m_bIsPlayingBack; // force it to be "changed" } // Playback state changed... diff --git a/game/client/c_te_bloodstream.cpp b/game/client/c_te_bloodstream.cpp index b528044e..dfdfb66f 100644 --- a/game/client/c_te_bloodstream.cpp +++ b/game/client/c_te_bloodstream.cpp @@ -114,7 +114,7 @@ void TE_BloodStream( IRecipientFilter& filter, float delay, float arc = 0.05; int count, count2; float num; - int speedCopy = amount; + float speedCopy = amount; Vector dir; VectorCopy( *direction, dir ); diff --git a/game/client/c_te_decal.cpp b/game/client/c_te_decal.cpp index fb60cd7b..d9f70108 100644 --- a/game/client/c_te_decal.cpp +++ b/game/client/c_te_decal.cpp @@ -139,7 +139,7 @@ void TE_Decal( IRecipientFilter& filter, float delay, // Only decal the world + brush models // Here we deal with decals on entities. C_BaseEntity* ent; - if ( ( ent = cl_entitylist->GetEnt( entity ) ) == false ) + if ( ( ent = cl_entitylist->GetEnt( entity ) ) == NULL ) return; ent->AddDecal( *start, *pos, *pos, hitbox, diff --git a/game/client/c_te_legacytempents.cpp b/game/client/c_te_legacytempents.cpp index e15f009c..2cec2713 100644 --- a/game/client/c_te_legacytempents.cpp +++ b/game/client/c_te_legacytempents.cpp @@ -1539,7 +1539,7 @@ void CTempEnts::BloodSprite( const Vector &org, int r, int g, int b, int a, int { C_LocalTempEntity *pTemp; int frameCount = modelinfo->GetModelFrameCount( model ); - color32 impactcolor = { r, g, b, a }; + color32 impactcolor = { (byte)r, (byte)g, (byte)b, (byte)a }; //Large, single blood sprite is a high-priority tent if ( ( pTemp = TempEntAllocHigh( org, model ) ) != NULL ) diff --git a/game/client/c_team_train_watcher.cpp b/game/client/c_team_train_watcher.cpp index 454c34b2..1f795115 100644 --- a/game/client/c_team_train_watcher.cpp +++ b/game/client/c_team_train_watcher.cpp @@ -163,18 +163,13 @@ void C_TeamTrainWatcher::OnDataChanged( DataUpdateType_t updateType ) int nNumHills = ObjectiveResource()->GetNumNodeHillData( GetTeamNumber() ); if ( nNumHills > 0 ) { - float flStart, flEnd; + float flStart = 0, flEnd = 0; for ( int i = 0 ; i < nNumHills ; i++ ) { ObjectiveResource()->GetHillData( GetTeamNumber(), i, flStart, flEnd ); - if ( m_flTotalProgress >= flStart && m_flTotalProgress<= flEnd ) - { - ObjectiveResource()->SetTrainOnHill( GetTeamNumber(), i, true ); - } - else - { - ObjectiveResource()->SetTrainOnHill( GetTeamNumber(), i, false ); - } + + bool state = ( m_flTotalProgress >= flStart && m_flTotalProgress <= flEnd ); + ObjectiveResource()->SetTrainOnHill( GetTeamNumber(), i, state ); } } } diff --git a/game/client/cdll_client_int.cpp b/game/client/cdll_client_int.cpp index 11db176b..c97c9436 100644 --- a/game/client/cdll_client_int.cpp +++ b/game/client/cdll_client_int.cpp @@ -1717,7 +1717,11 @@ void CHLClient::LevelShutdown( void ) messagechars->Clear(); +#ifndef TF_CLIENT_DLL + // don't want to do this for TF2 because we have particle systems in our + // character loadout screen that can be viewed when we're not connected to a server g_pParticleSystemMgr->UncacheAllParticleSystems(); +#endif UncacheAllMaterials(); #ifdef _XBOX diff --git a/game/client/client_base.vpc b/game/client/client_base.vpc index 7eaee661..305c8efe 100644 --- a/game/client/client_base.vpc +++ b/game/client/client_base.vpc @@ -53,9 +53,8 @@ $Configuration { $AdditionalIncludeDirectories ".\;$BASE;$SRCDIR\vgui2\include;$SRCDIR\vgui2\controls;$SRCDIR\game\shared;.\game_controls;$SRCDIR\thirdparty\sixensesdk\include" $PreprocessorDefinitions "$BASE;NO_STRING_T;CLIENT_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead" - $PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;fopen=dont_use_fopen" [$WIN32] - $PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;" [$OSXALL] - $PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;USE_WEBM_FOR_REPLAY;" [$LINUXALL] + $PreprocessorDefinitions "$BASE;fopen=dont_use_fopen" [$WIN32] + $PreprocessorDefinitions "$BASE;USE_WEBM_FOR_REPLAY;" [$LINUXALL] $PreprocessorDefinitions "$BASE;CURL_STATICLIB" [$WIN32 && $BUILD_REPLAY] $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)" $Create/UsePCHThroughFile "cbase.h" diff --git a/game/client/client_virtualreality.cpp b/game/client/client_virtualreality.cpp index 36abb6b8..ee38f30a 100644 --- a/game/client/client_virtualreality.cpp +++ b/game/client/client_virtualreality.cpp @@ -21,6 +21,7 @@ #include "vgui_controls/Controls.h" #include "tier0/vprof_telemetry.h" #include +#include "steam/steam_api.h" const char *COM_GetModDirectory(); // return the mod dir (rather than the complete -game param, which can be a path) @@ -212,6 +213,7 @@ void CalcFovFromProjection ( float *pFov, const VMatrix &proj ) Assert ( proj.m[3][2] == -1.0f ); Assert ( proj.m[3][3] == 0.0f ); + /* // The math here: // A view-space vector (x,y,z,1) is transformed by the projection matrix // / xscale 0 xoffset 0 \ @@ -226,6 +228,7 @@ void CalcFovFromProjection ( float *pFov, const VMatrix &proj ) // = xscale*(x/z) + xoffset (I flipped the signs of both sides) // => (+-1 - xoffset)/xscale = x/z // ...and x/z is tan(theta), and theta is the half-FOV. + */ float fov_px = 2.0f * RAD2DEG ( atanf ( fabsf ( ( 1.0f - xoffset ) / xscale ) ) ); float fov_nx = 2.0f * RAD2DEG ( atanf ( fabsf ( ( -1.0f - xoffset ) / xscale ) ) ); @@ -1363,28 +1366,32 @@ void CClientVirtualReality::Activate() if( !g_pSourceVR ) return; - // see if VR mode is even enabled - if( materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter == -1 ) + // These checks don't apply if we're in VR mode because Steam said so. + if ( !ShouldForceVRActive() ) { - Warning( "Enable VR mode in the video options before trying to use it.\n" ); - return; - } + // see if VR mode is even enabled + if ( materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter == -1 ) + { + Warning( "Enable VR mode in the video options before trying to use it.\n" ); + return; + } - // See if we have an actual adapter - int32 nVRModeAdapter = g_pSourceVR->GetVRModeAdapter(); - if( nVRModeAdapter == -1 ) - { - Warning( "Unable to get VRMode adapter from OpenVR. VR mode cannot be enabled. Try restarting and then enabling VR again.\n" ); - return; - } + // See if we have an actual adapter + int32 nVRModeAdapter = g_pSourceVR->GetVRModeAdapter(); + if ( nVRModeAdapter == -1 ) + { + Warning( "Unable to get VRMode adapter from OpenVR. VR mode cannot be enabled. Try restarting and then enabling VR again.\n" ); + return; + } - // we can only activate if we've got a VR device - if( materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter != nVRModeAdapter ) - { - Warning( "VR Mode expects adapter %d which is different from %d which we are currently using. Try restarting and enabling VR mode again.\n", - nVRModeAdapter, materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter ); - engine->ExecuteClientCmd( "mat_enable_vrmode 0\n" ); - return; + // we can only activate if we've got a VR device + if ( materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter != nVRModeAdapter ) + { + Warning( "VR Mode expects adapter %d which is different from %d which we are currently using. Try restarting and enabling VR mode again.\n", + nVRModeAdapter, materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter ); + engine->ExecuteClientCmd( "mat_enable_vrmode 0\n" ); + return; + } } @@ -1429,18 +1436,22 @@ void CClientVirtualReality::Activate() int nViewportWidth, nViewportHeight; g_pSourceVR->GetViewportBounds( ISourceVirtualReality::VREye_Left, NULL, NULL, &nViewportWidth, &nViewportHeight ); - vgui::surface()->SetFullscreenViewportAndRenderTarget( 0, 0, nViewportWidth, nViewportHeight, g_pSourceVR->GetRenderTarget( ISourceVirtualReality::VREye_Left, ISourceVirtualReality::RT_Color ) ); + g_pMatSystemSurface->SetFullscreenViewportAndRenderTarget( 0, 0, nViewportWidth, nViewportHeight, g_pSourceVR->GetRenderTarget( ISourceVirtualReality::VREye_Left, ISourceVirtualReality::RT_Color ) ); vgui::ivgui()->SetVRMode( true ); - VRRect_t rect; - if( g_pSourceVR->GetDisplayBounds( &rect ) ) + // we can skip this extra mode change if we've always been in VR mode + if ( !ShouldForceVRActive() ) { + VRRect_t rect; + if ( g_pSourceVR->GetDisplayBounds( &rect ) ) + { - // set mode - char szCmd[ 256 ]; - Q_snprintf( szCmd, sizeof( szCmd ), "mat_setvideomode %i %i %i\n", rect.nWidth, rect.nHeight, vr_force_windowed.GetBool()? 1 : 0 ); - engine->ClientCmd_Unrestricted( szCmd ); + // set mode + char szCmd[256]; + Q_snprintf( szCmd, sizeof(szCmd), "mat_setvideomode %i %i %i\n", rect.nWidth, rect.nHeight, vr_force_windowed.GetBool() ? 1 : 0 ); + engine->ClientCmd_Unrestricted( szCmd ); + } } } @@ -1455,7 +1466,7 @@ void CClientVirtualReality::Deactivate() g_pMatSystemSurface->ForceScreenSizeOverride(false, 0, 0 ); g_pMaterialSystem->GetRenderContext()->Viewport( 0, 0, m_nNonVRWidth, m_nNonVRHeight ); - vgui::surface()->SetFullscreenViewportAndRenderTarget( 0, 0, m_nNonVRWidth, m_nNonVRHeight, NULL ); + g_pMatSystemSurface->SetFullscreenViewportAndRenderTarget( 0, 0, m_nNonVRWidth, m_nNonVRHeight, NULL ); static ConVarRef cl_software_cursor( "cl_software_cursor" ); vgui::surface()->SetSoftwareCursor( cl_software_cursor.GetBool() ); @@ -1499,7 +1510,7 @@ void CClientVirtualReality::Deactivate() // Called when startup is complete void CClientVirtualReality::StartupComplete() { - if( vr_activate_default.GetBool() ) + if ( vr_activate_default.GetBool() || ShouldForceVRActive() ) Activate(); } diff --git a/game/client/cliententitylist.cpp b/game/client/cliententitylist.cpp index 758ab8f8..615da03d 100644 --- a/game/client/cliententitylist.cpp +++ b/game/client/cliententitylist.cpp @@ -354,6 +354,67 @@ void CClientEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ) } +#if defined( STAGING_ONLY ) + +// Defined in tier1 / interface.cpp for Windows and native for POSIX platforms. +extern "C" int backtrace( void **buffer, int size ); + +static struct +{ + int entnum; + float time; + C_BaseEntity *pBaseEntity; + void *backtrace_addrs[ 16 ]; +} g_RemoveEntityBacktraces[ 1024 ]; +static uint32 g_RemoveEntityBacktracesIndex = 0; + +static void OnRemoveEntityBacktraceHook( int entnum, C_BaseEntity *pBaseEntity ) +{ + int index = g_RemoveEntityBacktracesIndex++; + if ( g_RemoveEntityBacktracesIndex >= ARRAYSIZE( g_RemoveEntityBacktraces ) ) + g_RemoveEntityBacktracesIndex = 0; + + g_RemoveEntityBacktraces[ index ].entnum = entnum; + g_RemoveEntityBacktraces[ index ].time = gpGlobals->curtime; + g_RemoveEntityBacktraces[ index ].pBaseEntity = pBaseEntity; + + memset( g_RemoveEntityBacktraces[ index ].backtrace_addrs, 0, sizeof( g_RemoveEntityBacktraces[ index ].backtrace_addrs ) ); + backtrace( g_RemoveEntityBacktraces[ index ].backtrace_addrs, ARRAYSIZE( g_RemoveEntityBacktraces[ index ].backtrace_addrs ) ); +} + +// Should help us track down CL_PreserveExistingEntity Host_Error() issues: +// 1. Set cl_removeentity_backtrace_capture to 1. +// 2. When error hits, run "cl_removeentity_backtrace_dump [entnum]". +// 3. In debugger, track down what functions the spewed addresses refer to. +static ConVar cl_removeentity_backtrace_capture( "cl_removeentity_backtrace_capture", "0", 0, + "For debugging. Capture backtraces for CClientEntityList::OnRemoveEntity calls." ); + +CON_COMMAND( cl_removeentity_backtrace_dump, "Dump backtraces for client OnRemoveEntity calls." ) +{ + if ( !cl_removeentity_backtrace_capture.GetBool() ) + { + Msg( "cl_removeentity_backtrace_dump error: cl_removeentity_backtrace_capture not enabled. Backtraces not captured.\n" ); + return; + } + + int entnum = ( args.ArgC() >= 2 ) ? atoi( args[ 1 ] ) : -1; + + for ( int i = 0; i < ARRAYSIZE( g_RemoveEntityBacktraces ); i++ ) + { + if ( g_RemoveEntityBacktraces[ i ].time && + ( entnum == -1 || g_RemoveEntityBacktraces[ i ].entnum == entnum ) ) + { + Msg( "%d: time:%.2f pBaseEntity:%p\n", g_RemoveEntityBacktraces[i].entnum, + g_RemoveEntityBacktraces[ i ].time, g_RemoveEntityBacktraces[ i ].pBaseEntity ); + for ( int j = 0; j < ARRAYSIZE( g_RemoveEntityBacktraces[ i ].backtrace_addrs ); j++ ) + { + Msg( " %p\n", g_RemoveEntityBacktraces[ i ].backtrace_addrs[ j ] ); + } + } + } +} + +#endif // STAGING_ONLY void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ) { @@ -380,6 +441,13 @@ void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity(); +#if defined( STAGING_ONLY ) + if ( cl_removeentity_backtrace_capture.GetBool() ) + { + OnRemoveEntityBacktraceHook( entnum, pBaseEntity ); + } +#endif // STAGING_ONLY + if ( pBaseEntity ) { if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE ) diff --git a/game/client/clientmode_shared.cpp b/game/client/clientmode_shared.cpp index 1642c3cb..356ef1f8 100644 --- a/game/client/clientmode_shared.cpp +++ b/game/client/clientmode_shared.cpp @@ -228,9 +228,9 @@ static void __MsgFunc_VGUIMenu( bf_read &msg ) && keys->GetInt( "type", 0 ) == 2 // URL message type ) { const char *pszURL = keys->GetString( "msg", "" ); - if ( Q_strncmp( pszURL, "http://", 7 ) != 0 && Q_strncmp( pszURL, "https://", 8 ) != 0 ) + if ( Q_strncmp( pszURL, "http://", 7 ) != 0 && Q_strncmp( pszURL, "https://", 8 ) != 0 && Q_stricmp( pszURL, "about:blank" ) != 0 ) { - Warning( "Blocking MOTD URL '%s'; must begin with 'http://' or 'https://'\n", pszURL ); + Warning( "Blocking MOTD URL '%s'; must begin with 'http://' or 'https://' or be about:blank\n", pszURL ); keys->deleteThis(); return; } @@ -470,8 +470,17 @@ bool ClientModeShared::ShouldDrawEntity(C_BaseEntity *pEnt) return true; } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- bool ClientModeShared::ShouldDrawParticles( ) { +#ifdef TF_CLIENT_DLL + C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer(); + if ( pTFPlayer && !pTFPlayer->ShouldPlayerDrawParticles() ) + return false; +#endif // TF_CLIENT_DLL + return true; } diff --git a/game/client/detailobjectsystem.cpp b/game/client/detailobjectsystem.cpp index a6e08d3a..f318a636 100644 --- a/game/client/detailobjectsystem.cpp +++ b/game/client/detailobjectsystem.cpp @@ -1481,7 +1481,7 @@ void CDetailObjectSystem::LevelInitPreEntity() PrecacheMaterial( DETAIL_SPRITE_MATERIAL ); IMaterial *pMat = m_DetailSpriteMaterial; // adjust for non-square textures (cropped) - float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight(); + float flRatio = (float)( pMat->GetMappingWidth() ) / pMat->GetMappingHeight(); if ( flRatio > 1.0 ) { for( int i = 0; iGetUILanguage( uilanguage, sizeof( uilanguage ) ); Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_%s.html", mapName, uilanguage ); diff --git a/game/client/game_controls/vguitextwindow.cpp b/game/client/game_controls/vguitextwindow.cpp index ef154b2b..4d521215 100644 --- a/game/client/game_controls/vguitextwindow.cpp +++ b/game/client/game_controls/vguitextwindow.cpp @@ -102,11 +102,7 @@ CTextWindow::CTextWindow(IViewPort *pViewPort) : Frame(NULL, PANEL_INFO ) SetTitleBarVisible( false ); m_pTextMessage = new TextEntry( this, "TextMessage" ); -#if defined( ENABLE_CHROMEHTMLWINDOW ) m_pHTMLMessage = new CMOTDHTML( this,"HTMLMessage" ); -#else - m_pHTMLMessage = NULL; -#endif m_pTitleLabel = new Label( this, "MessageTitle", "Message Title" ); m_pOK = new Button(this, "ok", "#PropertyDialog_OK"); @@ -165,7 +161,6 @@ void CTextWindow::ShowText( const char *text ) void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable ) { -#if defined( ENABLE_CHROMEHTMLWINDOW ) #ifdef _DEBUG Msg( "CTextWindow::ShowURL( %s )\n", URL ); #endif @@ -196,8 +191,6 @@ void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable ) m_pHTMLMessage->SetVisible( true ); m_pHTMLMessage->OpenURL( URL, NULL ); m_bShownURL = true; - -#endif } void CTextWindow::ShowIndex( const char *entry ) @@ -286,9 +279,8 @@ void CTextWindow::Update( void ) m_pTitleLabel->SetText( m_szTitle ); -#if defined( ENABLE_CHROMEHTMLWINDOW ) - m_pHTMLMessage->SetVisible( false ); -#endif + if ( m_pHTMLMessage ) + m_pHTMLMessage->SetVisible( false ); m_pTextMessage->SetVisible( false ); if ( m_nContentType == TYPE_INDEX ) @@ -427,13 +419,11 @@ void CTextWindow::ShowPanel( bool bShow ) SetVisible( false ); SetMouseInputEnabled( false ); -#if defined( ENABLE_CHROMEHTMLWINDOW ) - if ( m_bUnloadOnDismissal && m_bShownURL ) + if ( m_bUnloadOnDismissal && m_bShownURL && m_pHTMLMessage ) { m_pHTMLMessage->OpenURL( "about:blank", NULL ); m_bShownURL = false; } -#endif } } diff --git a/game/client/hl2/hud_damageindicator.cpp b/game/client/hl2/hud_damageindicator.cpp index d9dde1a1..777d812b 100644 --- a/game/client/hl2/hud_damageindicator.cpp +++ b/game/client/hl2/hud_damageindicator.cpp @@ -178,7 +178,7 @@ void CHudDamageIndicator::DrawDamageIndicator(int side) int x1 = m_flDmgX; int x2 = m_flDmgX + m_flDmgWide; - int y[4] = { m_flDmgY, m_flDmgY + insetY, m_flDmgY + m_flDmgTall1 - insetY, m_flDmgY + m_flDmgTall1 }; + int y[4] = { (int)m_flDmgY, (int)(m_flDmgY + insetY), (int)(m_flDmgY + m_flDmgTall1 - insetY), (int)(m_flDmgY + m_flDmgTall1) }; int alpha[4] = { 0.0f, 1.0f, 1.0f, 0.0f }; // see if we're high damage diff --git a/game/client/hl2/hud_weaponselection.cpp b/game/client/hl2/hud_weaponselection.cpp index 8860baa9..25f64132 100644 --- a/game/client/hl2/hud_weaponselection.cpp +++ b/game/client/hl2/hud_weaponselection.cpp @@ -598,13 +598,13 @@ void CHudWeaponSelection::Paint() // bucket style int screenCenterX = (int) fCenterX; - int screenCenterY = (int) fCenterY - 15; // Height isn't quite screen height, so adjust for center alignement + int screenCenterY = (int) fCenterY - 15; // Height isn't quite screen height, so adjust for center alignment // Modifiers for the four directions. Used to change the x and y offsets // of each box based on which bucket we're drawing. Bucket directions are // 0 = UP, 1 = RIGHT, 2 = DOWN, 3 = LEFT - int xModifiers[] = { 0, 1, 0, -1 }; - int yModifiers[] = { -1, 0, 1, 0 }; + int xModifiers[] = { 0, 1, 0, -1, -1, 1 }; + int yModifiers[] = { -1, 0, 1, 0, 1, 1 }; // Draw the four buckets for ( int i = 0; i < MAX_WEAPON_SLOTS; ++i ) @@ -1453,7 +1453,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) return; // Don't try and read past our possible number of slots - if ( iSlot > MAX_WEAPON_SLOTS ) + if ( iSlot >= MAX_WEAPON_SLOTS ) return; // Make sure the player's allowed to switch weapons diff --git a/game/client/hud.cpp b/game/client/hud.cpp index 69e735e5..9461e5da 100644 --- a/game/client/hud.cpp +++ b/game/client/hud.cpp @@ -512,7 +512,7 @@ void CHud::Shutdown( void ) //----------------------------------------------------------------------------- -// Purpose: LevelInit's called whenever a new level's starting +// Purpose: LevelInit's called whenever a new level is starting //----------------------------------------------------------------------------- void CHud::LevelInit( void ) { @@ -533,11 +533,11 @@ void CHud::LevelInit( void ) } //----------------------------------------------------------------------------- -// Purpose: LevelShutdown's called whenever a level's finishing +// Purpose: LevelShutdown's called whenever a level is finishing //----------------------------------------------------------------------------- void CHud::LevelShutdown( void ) { - // Tell all the registered hud elements to LevelInit + // Tell all the registered hud elements to LevelShutdown for ( int i = 0; i < m_HudList.Size(); i++ ) { m_HudList[i]->LevelShutdown(); diff --git a/game/client/hud.h b/game/client/hud.h index dab02bfc..f664d385 100644 --- a/game/client/hud.h +++ b/game/client/hud.h @@ -107,9 +107,9 @@ public: void VidInit( void ); // Shutdown's called when the engine's shutting down void Shutdown( void ); - // LevelInit's called whenever a new level's starting + // LevelInit's called whenever a new level is starting void LevelInit( void ); - // LevelShutdown's called whenever a level's finishing + // LevelShutdown's called whenever a level is finishing void LevelShutdown( void ); void ResetHUD( void ); diff --git a/game/client/hud_basechat.h b/game/client/hud_basechat.h index cdb6d907..82fec9d6 100644 --- a/game/client/hud_basechat.h +++ b/game/client/hud_basechat.h @@ -241,7 +241,7 @@ public: void MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf); virtual void Printf( int iFilter, PRINTF_FORMAT_STRING const char *fmt, ... ); - virtual void ChatPrintf( int iPlayerIndex, int iFilter, PRINTF_FORMAT_STRING const char *fmt, ... ); + virtual void ChatPrintf( int iPlayerIndex, int iFilter, PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 4, 5 ); virtual void StartMessageMode( int iMessageModeType ); virtual void StopMessageMode( void ); diff --git a/game/client/hud_basedeathnotice.cpp b/game/client/hud_basedeathnotice.cpp index b5468f94..81e12b59 100644 --- a/game/client/hud_basedeathnotice.cpp +++ b/game/client/hud_basedeathnotice.cpp @@ -65,6 +65,7 @@ void CHudBaseDeathNotice::Init( void ) ListenForGameEvent( "teamplay_point_captured" ); ListenForGameEvent( "teamplay_capture_blocked" ); ListenForGameEvent( "teamplay_flag_event" ); + ListenForGameEvent( "rd_robot_killed" ); } //----------------------------------------------------------------------------- diff --git a/game/client/hud_closecaption.cpp b/game/client/hud_closecaption.cpp index 7df2b4c2..302bc6a7 100644 --- a/game/client/hud_closecaption.cpp +++ b/game/client/hud_closecaption.cpp @@ -844,6 +844,7 @@ CHudCloseCaption::CHudCloseCaption( const char *pElementName ) HOOK_HUD_MESSAGE( CHudCloseCaption, CloseCaption ); char uilanguage[ 64 ]; + uilanguage[0] = 0; engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); if ( !Q_stricmp( uilanguage, "english" ) ) @@ -2752,6 +2753,7 @@ void OnCaptionLanguageChanged( IConVar *pConVar, const char *pOldString, float f } char uilanguage[ 64 ]; + uilanguage[0] = 0; engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption ); diff --git a/game/client/hud_vote.cpp b/game/client/hud_vote.cpp index 6e6ddb5c..044bbfbb 100644 --- a/game/client/hud_vote.cpp +++ b/game/client/hud_vote.cpp @@ -662,7 +662,8 @@ void CVoteSetupDialog::OnItemSelected( vgui::Panel *panel ) for ( int index = 0; index < m_VoteIssuesPopFiles.Count(); index++ ) { // Don't show the current pop file - if ( TFObjectiveResource()->GetMvMPopFileName() == '\0' ) + const char *pszPopFileName = TFObjectiveResource()->GetMvMPopFileName(); + if ( !pszPopFileName || !pszPopFileName[0] ) { // Use the map name char szShortMapName[ MAX_MAP_NAME ]; @@ -982,6 +983,12 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) char szTime[256]; wchar_t wszTime[256]; + bool bMinutes = ( nTime > 65 ); + if ( bMinutes ) + { + nTime /= 60; + } + const char *pszTimeString = ( bMinutes ) ? ( ( nTime < 2 ) ? "#GameUI_vote_failed_recently_min" : "#GameUI_vote_failed_recently_mins" ) : "#GameUI_vote_failed_recently"; Q_snprintf( szTime, sizeof ( szTime), "%i", nTime ); g_pVGuiLocalize->ConvertANSIToUnicode( szTime, wszTime, sizeof( wszTime ) ); @@ -1020,8 +1027,8 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_name_required" ); break; - case VOTE_FAILED_FAILED_RECENTLY: - g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_recently" ), 1, wszTime ); + case VOTE_FAILED_ON_COOLDOWN: + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof( wszHeaderString ), g_pVGuiLocalize->Find( pszTimeString ), 1, wszTime ); pwszHeaderString = wszHeaderString; m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString ); break; diff --git a/game/client/hudelement.h b/game/client/hudelement.h index ef0e27f4..52e9d80a 100644 --- a/game/client/hudelement.h +++ b/game/client/hudelement.h @@ -36,9 +36,9 @@ public: // called whenever the video mode changes, and whenever Init() would be called, so the hud can vid init itself virtual void VidInit( void ) { return; } - // LevelInit's called whenever a new level's starting + // LevelInit's called whenever a new level is starting virtual void LevelInit( void ) { return; }; - // LevelShutdown's called whenever a level's finishing + // LevelShutdown's called whenever a level is finishing virtual void LevelShutdown( void ) { return; }; // called whenever the hud receives "reset" message, which is (usually) every time the client respawns after getting killed diff --git a/game/client/in_joystick.cpp b/game/client/in_joystick.cpp index 8703bca8..425bdbea 100644 --- a/game/client/in_joystick.cpp +++ b/game/client/in_joystick.cpp @@ -846,6 +846,8 @@ void CInput::JoyStickMove( float frametime, CUserCmd *cmd ) { angle = m_flPreviousJoystickYaw * joy_yawsensitivity.GetFloat() * aspeed * 180.0; } + + angle = JoyStickAdjustYaw( angle ); viewangles[YAW] += angle; cmd->mousedx = angle; diff --git a/game/client/input.h b/game/client/input.h index 00bbb02f..29ad1884 100644 --- a/game/client/input.h +++ b/game/client/input.h @@ -141,6 +141,7 @@ private: void ControllerMove ( float frametime, CUserCmd *cmd ); void JoyStickMove ( float frametime, CUserCmd *cmd ); float ScaleAxisValue( const float axisValue, const float axisThreshold ); + virtual float JoyStickAdjustYaw( float flSpeed ) { return flSpeed; } // Call this to get the cursor position. The call will be logged in the VCR file if there is one. void GetMousePos(int &x, int &y); diff --git a/game/client/particlemgr.cpp b/game/client/particlemgr.cpp index ae049e7d..471e671b 100644 --- a/game/client/particlemgr.cpp +++ b/game/client/particlemgr.cpp @@ -97,8 +97,8 @@ CParticleSubTextureGroup::~CParticleSubTextureGroup() CParticleSubTexture::CParticleSubTexture() { - m_tCoordMins[0] = m_tCoordMins[0] = 0; - m_tCoordMaxs[0] = m_tCoordMaxs[0] = 1; + m_tCoordMins[0] = m_tCoordMins[1] = 0; + m_tCoordMaxs[0] = m_tCoordMaxs[1] = 1; m_pGroup = &m_DefaultGroup; m_pMaterial = NULL; diff --git a/game/client/prediction.cpp b/game/client/prediction.cpp index 0c61e68a..db4d6a27 100644 --- a/game/client/prediction.cpp +++ b/game/client/prediction.cpp @@ -931,7 +931,8 @@ void CPrediction::SetIdealPitch ( C_BasePlayer *player, const Vector& origin, co Vector top, bottom; float floor_height[MAX_FORWARD]; int i, j; - int step, dir, steps; + float step, dir; + int steps; trace_t tr; if ( player->GetGroundEntity() == NULL ) diff --git a/game/client/replay/replayyoutubeapi.cpp b/game/client/replay/replayyoutubeapi.cpp index e39d5dcb..3b86066c 100644 --- a/game/client/replay/replayyoutubeapi.cpp +++ b/game/client/replay/replayyoutubeapi.cpp @@ -24,7 +24,7 @@ #include "confirm_dialog.h" #include "replay/vgui/replaybrowserdetailspanel.h" -#include "base_gcmessages.h" +#include "base_gcmessages.pb.h" #include "youtubeapi.h" #include "steamworks_gamestats.h" diff --git a/game/client/replay/vgui/replayperformanceeditor.cpp b/game/client/replay/vgui/replayperformanceeditor.cpp index f9d7caf3..75e8b44c 100644 --- a/game/client/replay/vgui/replayperformanceeditor.cpp +++ b/game/client/replay/vgui/replayperformanceeditor.cpp @@ -576,7 +576,7 @@ public: BaseClass::PerformLayout(); int nWidth = XRES( 140 ); - int nMargins[2] = { XRES( 5 ), YRES( 5 ) }; + int nMargins[2] = { (int)XRES( 5 ), (int)YRES( 5 ) }; int nVBuf = YRES( 0 ); int nLastY = -1; int nY = nMargins[1]; @@ -1969,7 +1969,7 @@ void CReplayPerformanceEditorPanel::PerformLayout() dynamic_cast< CExLabel * >( m_pPlayerCellsPanel->FindChildByName( "RedLabel" ) ), dynamic_cast< CExLabel * >( m_pPlayerCellsPanel->FindChildByName( "BlueLabel" ) ) }; - int nMargins[2] = { XRES( 5 ), YRES( 2 ) }; + int nMargins[2] = { (int)XRES( 5 ), (int)YRES( 2 ) }; for ( int i = 0; i < 2; ++i ) { pRedBlueLabels[i]->SizeToContents(); @@ -2473,6 +2473,7 @@ void CReplayPerformanceEditorPanel::OnCommand( const char *command ) { ReplayCamera()->SetMode( OBS_MODE_ROAMING ); UpdateCameraSelectionPosition( CAM_FREE ); + m_bCurrentTargetNeedsVisibilityUpdate = true; g_pReplayPerformanceController->AddEvent_Camera_Change_Free( flCurTime ); AddSetViewEvent(); DisplayPerformanceTip( "#Replay_PerfTip_EnterFreeCam", &replay_perftip_count_freecam_enter, MAX_TIP_DISPLAYS ); diff --git a/game/client/sixense/in_sixense_gesture_bindings.cpp b/game/client/sixense/in_sixense_gesture_bindings.cpp index 213d8409..1cab81eb 100644 --- a/game/client/sixense/in_sixense_gesture_bindings.cpp +++ b/game/client/sixense/in_sixense_gesture_bindings.cpp @@ -879,10 +879,6 @@ bool SixenseGestureBindings::ActionTokenToStr( sixenseUtils::IButtonStates::Acti { Q_snprintf( buf, buflen, "tilt_gesture" ); } - else if( action == sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS ) - { - Q_snprintf( buf, buflen, "button_press" ); - } else if( action == sixenseUtils::IButtonStates::ACTION_TRIGGER_PRESS ) { Q_snprintf( buf, buflen, "trigger_press" ); diff --git a/game/client/vgui_fpspanel.cpp b/game/client/vgui_fpspanel.cpp index a1e7d282..ceb801d8 100644 --- a/game/client/vgui_fpspanel.cpp +++ b/game/client/vgui_fpspanel.cpp @@ -18,6 +18,7 @@ #include "filesystem.h" #include "../common/xbox/xboxstubs.h" #include "steam/steam_api.h" +#include "tier0/cpumonitoring.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -189,12 +190,12 @@ void GetFPSColor( int nFps, unsigned char ucColor[3] ) if ( IsPC() && g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 95 ) { nFPSThreshold1 = 60; - nFPSThreshold1 = 50; + nFPSThreshold2 = 50; } else if ( IsX360() || g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 90 ) { nFPSThreshold1 = 30; - nFPSThreshold1 = 25; + nFPSThreshold2 = 25; } if ( nFps >= nFPSThreshold1 ) @@ -208,6 +209,28 @@ void GetFPSColor( int nFps, unsigned char ucColor[3] ) } } +//----------------------------------------------------------------------------- +// Purpose: Set the color appropriately based on the CPU's frequency percentage +//----------------------------------------------------------------------------- +void GetCPUColor( float cpuPercentage, unsigned char ucColor[3] ) +{ + // These colors are for poor CPU performance + ucColor[0] = 255; ucColor[1] = 0; ucColor[2] = 0; + + if ( cpuPercentage >= kCPUMonitoringWarning1 ) + { + // Excellent CPU performance + ucColor[0] = 10; + ucColor[1] = 200; + } + else if ( cpuPercentage >= kCPUMonitoringWarning2 ) + { + // Medium CPU performance + ucColor[0] = 220; + ucColor[1] = 220; + } +} + //----------------------------------------------------------------------------- // Purpose: // Input : @@ -272,6 +295,17 @@ void CFPSPanel::Paint() GetFPSColor( nFps, ucColor ); g_pMatSystemSurface->DrawColoredText( m_hFont, x, 2, ucColor[0], ucColor[1], ucColor[2], 255, "%3i fps on %s", nFps, engine->GetLevelName() ); } + + const CPUFrequencyResults frequency = GetCPUFrequencyResults(); + double currentTime = Plat_FloatTime(); + const double displayTime = 5.0f; // Display frequency results for this long. + if ( frequency.m_GHz > 0 && frequency.m_timeStamp + displayTime > currentTime ) + { + int lineHeight = vgui::surface()->GetFontTall( m_hFont ); + // Optionally print out the CPU frequency monitoring data. + GetCPUColor( frequency.m_percentage, ucColor ); + g_pMatSystemSurface->DrawColoredText( m_hFont, x, lineHeight + 2, ucColor[0], ucColor[1], ucColor[2], 255, "CPU frequency percent: %3.1f%% Min percent: %3.1f%%", frequency.m_percentage, frequency.m_lowestPercentage ); + } } } m_lastRealTime = gpGlobals->realtime; diff --git a/game/client/vgui_messagechars.cpp b/game/client/vgui_messagechars.cpp index ac587bc1..aa215341 100644 --- a/game/client/vgui_messagechars.cpp +++ b/game/client/vgui_messagechars.cpp @@ -235,9 +235,10 @@ int CMessageCharsPanel::AddText( Assert( !msg->text ); - msg->text = new char[ Q_strlen( data ) + 1 ]; + int textLength = Q_strlen( data ) + 1; + msg->text = new char[ textLength ]; Assert( msg->text ); - Q_strncpy( msg->text, data, sizeof( msg->text ) ); + Q_strncpy( msg->text, data, textLength ); if ( flTime ) msg->fTTL = gpGlobals->curtime + flTime; diff --git a/game/client/vgui_netgraphpanel.cpp b/game/client/vgui_netgraphpanel.cpp index 3fbd1113..caeb19ca 100644 --- a/game/client/vgui_netgraphpanel.cpp +++ b/game/client/vgui_netgraphpanel.cpp @@ -20,6 +20,7 @@ #include #include #include "tier0/vprof.h" +#include "tier0/cpumonitoring.h" #include "cdll_bounded_cvars.h" #include "materialsystem/imaterialsystem.h" @@ -761,7 +762,7 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban Q_snprintf( sz, sizeof( sz ), "lerp: %5.1f ms", GetClientInterpAmount() * 1000.0f ); - int interpcolor[ 3 ] = { GRAPH_RED, GRAPH_GREEN, GRAPH_BLUE }; + int interpcolor[ 3 ] = { (int)GRAPH_RED, (int)GRAPH_GREEN, (int)GRAPH_BLUE }; float flInterp = GetClientInterpAmount(); if ( flInterp > 0.001f ) { @@ -817,7 +818,7 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban { Q_snprintf( sz, sizeof( sz ), "sv : %5.1f var: %4.2f msec", m_flServerFramerate, m_flServerFramerateStdDeviation * 1000.0f ); - int servercolor[ 3 ] = { GRAPH_RED, GRAPH_GREEN, GRAPH_BLUE }; + int servercolor[ 3 ] = { (int)GRAPH_RED, (int)GRAPH_GREEN, (int)GRAPH_BLUE }; if ( m_flServerFramerate < 10.0f ) { @@ -876,6 +877,35 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban g_pMatSystemSurface->DrawColoredText( m_hFontSmall, x, y, 0, 0, 128, 255, "voice" ); y -= textTall; } + else + { + const CPUFrequencyResults frequency = GetCPUFrequencyResults(); + double currentTime = Plat_FloatTime(); + const double displayTime = 5.0f; // Display frequency results for this long. + if ( frequency.m_GHz > 0 && frequency.m_timeStamp + displayTime > currentTime ) + { + // Optionally print out the CPU frequency monitoring data. + uint8 cpuColor[4] = { (uint8)GRAPH_RED, (uint8)GRAPH_GREEN, (uint8)GRAPH_BLUE, 255 }; + + if ( frequency.m_percentage < kCPUMonitoringWarning2 ) + { + cpuColor[0] = 255; + cpuColor[1] = 31; + cpuColor[2] = 31; + } + else if ( frequency.m_percentage < kCPUMonitoringWarning1 ) + { + cpuColor[0] = 255; + cpuColor[1] = 125; + cpuColor[2] = 31; + } + // Experimental fading out as data becomes stale. Probably too distracting. + //float age = currentTime - frequency.m_timeStamp; + //cpuColor.a *= ( displayTime - age ) / displayTime; + g_pMatSystemSurface->DrawColoredText( font, x, y, cpuColor[0], cpuColor[1], cpuColor[2], cpuColor[3], + "CPU freq: %3.1f%% Min: %3.1f%%", frequency.m_percentage, frequency.m_lowestPercentage ); + } + } } //----------------------------------------------------------------------------- diff --git a/game/client/vgui_schemevisualizer.cpp b/game/client/vgui_schemevisualizer.cpp index fbdd8afb..06473442 100644 --- a/game/client/vgui_schemevisualizer.cpp +++ b/game/client/vgui_schemevisualizer.cpp @@ -177,7 +177,7 @@ void CSchemeVisualizer::AddBordersToList() void CSchemeVisualizer::AddFontsToList() { #ifdef POSIX - const char strOAccent[] = { 0xc3, 0x93, 0x00 }; // UTF-8 for U+00D3 (LATIN CAPITAL LETTER O WITH ACUTE) + const char strOAccent[] = { (char)0xc3, (char)0x93, 0x00 }; // UTF-8 for U+00D3 (LATIN CAPITAL LETTER O WITH ACUTE) #else const uint8 strOAccent[] = { 0xd3, 0x00 }; #endif diff --git a/game/client/viewpostprocess.cpp b/game/client/viewpostprocess.cpp index 885bbf40..1e65fcfc 100644 --- a/game/client/viewpostprocess.cpp +++ b/game/client/viewpostprocess.cpp @@ -1885,7 +1885,8 @@ static void DrawPyroVignette( int nDestX, int nDestY, int nWidth, int nHeight, / if ( pyro_vignette.GetInt() > 1 ) { - Vector2D vMaxSize( ( float )nScreenWidth / ( float )nScreenWidth / NUM_PYRO_SEGMENTS * 2.0f, ( float )nScreenHeight / ( float )nScreenHeight / NUM_PYRO_SEGMENTS * 2.0f ); + float flPyroSegments = 2.0f / NUM_PYRO_SEGMENTS; + Vector2D vMaxSize( flPyroSegments, flPyroSegments ); if ( !bInit ) { diff --git a/game/client/viewrender.cpp b/game/client/viewrender.cpp index 3c325278..fa87c343 100644 --- a/game/client/viewrender.cpp +++ b/game/client/viewrender.cpp @@ -1435,8 +1435,8 @@ static void GetFogColorTransition( fogparams_t *pFogParams, float *pColorPrimary { float flPercent = 1.0f - (( pFogParams->lerptime - gpGlobals->curtime ) / pFogParams->duration ); - float flPrimaryColorLerp[3] = { pFogParams->colorPrimaryLerpTo.GetR(), pFogParams->colorPrimaryLerpTo.GetG(), pFogParams->colorPrimaryLerpTo.GetB() }; - float flSecondaryColorLerp[3] = { pFogParams->colorSecondaryLerpTo.GetR(), pFogParams->colorSecondaryLerpTo.GetG(), pFogParams->colorSecondaryLerpTo.GetB() }; + float flPrimaryColorLerp[3] = { (float)pFogParams->colorPrimaryLerpTo.GetR(), (float)pFogParams->colorPrimaryLerpTo.GetG(), (float)pFogParams->colorPrimaryLerpTo.GetB() }; + float flSecondaryColorLerp[3] = { (float)pFogParams->colorSecondaryLerpTo.GetR(), (float)pFogParams->colorSecondaryLerpTo.GetG(), (float)pFogParams->colorSecondaryLerpTo.GetB() }; CheckAndTransitionColor( flPercent, pColorPrimary, flPrimaryColorLerp ); CheckAndTransitionColor( flPercent, pColorSecondary, flSecondaryColorLerp ); @@ -1459,8 +1459,8 @@ static void GetFogColor( fogparams_t *pFogParams, float *pColor ) } else { - float flPrimaryColor[3] = { pFogParams->colorPrimary.GetR(), pFogParams->colorPrimary.GetG(), pFogParams->colorPrimary.GetB() }; - float flSecondaryColor[3] = { pFogParams->colorSecondary.GetR(), pFogParams->colorSecondary.GetG(), pFogParams->colorSecondary.GetB() }; + float flPrimaryColor[3] = { (float)pFogParams->colorPrimary.GetR(), (float)pFogParams->colorPrimary.GetG(), (float)pFogParams->colorPrimary.GetB() }; + float flSecondaryColor[3] = { (float)pFogParams->colorSecondary.GetR(), (float)pFogParams->colorSecondary.GetG(), (float)pFogParams->colorSecondary.GetB() }; GetFogColorTransition( pFogParams, flPrimaryColor, flSecondaryColor ); @@ -2248,7 +2248,7 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT // let vgui know where to render stuff for the forced-to-framebuffer panels if( UseVR() ) { - vgui::surface()->SetFullscreenViewportAndRenderTarget( viewFramebufferX, viewFramebufferY, viewFramebufferWidth, viewFramebufferHeight, saveRenderTarget ); + g_pMatSystemSurface->SetFullscreenViewportAndRenderTarget( viewFramebufferX, viewFramebufferY, viewFramebufferWidth, viewFramebufferHeight, saveRenderTarget ); } // clear the render target if we need to @@ -3885,7 +3885,7 @@ static void DrawOpaqueRenderables_DrawStaticProps( CClientRenderablesList::CEntr for( CClientRenderablesList::CEntry *itEntity = pEntitiesBegin; itEntity < pEntitiesEnd; ++ itEntity ) { if ( itEntity->m_pRenderable ) - NULL; + /**/; else continue; @@ -3935,7 +3935,7 @@ void CRendering3dView::DrawOpaqueRenderables( ERenderDepthMode DepthMode ) RopeManager()->ResetRenderCache(); g_pParticleSystemMgr->ResetRenderCache(); - bool const bDrawopaquestaticpropslast = r_drawopaquestaticpropslast.GetBool(); + //bool const bDrawopaquestaticpropslast = r_drawopaquestaticpropslast.GetBool(); // @@ -4101,16 +4101,20 @@ void CRendering3dView::DrawOpaqueRenderables( ERenderDepthMode DepthMode ) for ( int bucket = 0; bucket < RENDER_GROUP_CFG_NUM_OPAQUE_ENT_BUCKETS; ++ bucket ) { - if ( bDrawopaquestaticpropslast ) + // PVS-Studio pointed out that the two sides of the if/else were identical. Fixing + // this long-broken behavior would change rendering, so I fixed the code but + // commented out the new behavior. Uncomment the if statement and else block + // when needed. + //if ( bDrawopaquestaticpropslast ) { DrawOpaqueRenderables_Range( pEnts[bucket][0], pEnts[bucket][1], DepthMode ); DrawOpaqueRenderables_DrawStaticProps( pProps[bucket][0], pProps[bucket][1], DepthMode ); } - else + /*else { - DrawOpaqueRenderables_Range( pEnts[bucket][0], pEnts[bucket][1], DepthMode ); DrawOpaqueRenderables_DrawStaticProps( pProps[bucket][0], pProps[bucket][1], DepthMode ); - } + DrawOpaqueRenderables_Range( pEnts[bucket][0], pEnts[bucket][1], DepthMode ); + }*/ } diff --git a/game/protobuf_include.vpc b/game/protobuf_include.vpc index 078b4166..7f711841 100644 --- a/game/protobuf_include.vpc +++ b/game/protobuf_include.vpc @@ -8,10 +8,10 @@ $MacroRequired "PLATFORM" $Project { - $Folder "Libraries" + $Folder "Link Libraries" { - $Libexternal libprotobuf [!$VS2012 && !$VS2013] + $Libexternal $SRCDIR\lib\public\2010\libprotobuf [$VS2010] $Libexternal 2012\libprotobuf [$VS2012] - $Libexternal 2013\libprotobuf [$VS2013] + $Libexternal libprotobuf [$VS2013 || !$WINDOWS] } } diff --git a/game/server/AI_Criteria.cpp b/game/server/AI_Criteria.cpp index 6b523970..ce7911b3 100644 --- a/game/server/AI_Criteria.cpp +++ b/game/server/AI_Criteria.cpp @@ -27,13 +27,8 @@ AI_CriteriaSet::AI_CriteriaSet() : m_Lookup( 0, 0, CritEntry_t::LessFunc ) //----------------------------------------------------------------------------- AI_CriteriaSet::AI_CriteriaSet( const AI_CriteriaSet& src ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ) { - m_Lookup.Purge(); - for ( short i = src.m_Lookup.FirstInorder(); - i != src.m_Lookup.InvalidIndex(); - i = src.m_Lookup.NextInorder( i ) ) - { - m_Lookup.Insert( src.m_Lookup[ i ] ); - } + // Use fast Copy CUtlRBTree CopyFrom. WARNING: It only handles POD. + m_Lookup.CopyFrom( src.m_Lookup ); } //----------------------------------------------------------------------------- @@ -162,7 +157,6 @@ void AI_CriteriaSet::Describe() { for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) ) { - CritEntry_t *entry = &m_Lookup[ i ]; if ( entry->weight != 1.0f ) @@ -199,9 +193,9 @@ AI_Response::AI_Response() { m_Type = RESPONSE_NONE; m_szResponseName[0] = 0; + m_szMatchingRule[0] = 0; + m_pCriteria = NULL; - m_szMatchingRule[0]=0; - m_szContext = NULL; m_bApplyContextToWorld = false; } @@ -209,13 +203,8 @@ AI_Response::AI_Response() //----------------------------------------------------------------------------- AI_Response::AI_Response( const AI_Response &from ) { - Assert( (void*)(&m_Type) == (void*)this ); m_pCriteria = NULL; - memcpy( this, &from, sizeof(*this) ); - m_pCriteria = NULL; - m_szContext = NULL; - SetContext( from.m_szContext ); - m_bApplyContextToWorld = from.m_bApplyContextToWorld; + *this = from; } //----------------------------------------------------------------------------- @@ -224,20 +213,34 @@ AI_Response::AI_Response( const AI_Response &from ) AI_Response::~AI_Response() { delete m_pCriteria; - delete[] m_szContext; + m_pCriteria = NULL; } //----------------------------------------------------------------------------- AI_Response &AI_Response::operator=( const AI_Response &from ) { Assert( (void*)(&m_Type) == (void*)this ); + + if (this == &from) + return *this; + + m_Type = from.m_Type; + + V_strcpy_safe( m_szResponseName, from.m_szResponseName ); + V_strcpy_safe( m_szMatchingRule, from.m_szMatchingRule ); + delete m_pCriteria; m_pCriteria = NULL; - memcpy( this, &from, sizeof(*this) ); - m_pCriteria = NULL; - m_szContext = NULL; - SetContext( from.m_szContext ); + + // Copy criteria. + if (from.m_pCriteria) + m_pCriteria = new AI_CriteriaSet(*from.m_pCriteria); + + m_Params = from.m_Params; + + m_szContext = from.m_szContext; m_bApplyContextToWorld = from.m_bApplyContextToWorld; + return *this; } @@ -246,15 +249,22 @@ AI_Response &AI_Response::operator=( const AI_Response &from ) // Input : *response - // *criteria - //----------------------------------------------------------------------------- -void AI_Response::Init( ResponseType_t type, const char *responseName, const AI_CriteriaSet& criteria, const AI_ResponseParams& responseparams, const char *ruleName, const char *applyContext, bool bApplyContextToWorld ) +void AI_Response::Init( ResponseType_t type, const char *responseName, const AI_CriteriaSet& criteria, + const AI_ResponseParams& responseparams, const char *ruleName, const char *applyContext, + bool bApplyContextToWorld ) { m_Type = type; - Q_strncpy( m_szResponseName, responseName, sizeof( m_szResponseName ) ); + + V_strcpy_safe( m_szResponseName, responseName ); + V_strcpy_safe( m_szMatchingRule, ruleName ? ruleName : "NULL" ); + // Copy underlying criteria + Assert( !m_pCriteria ); m_pCriteria = new AI_CriteriaSet( criteria ); - Q_strncpy( m_szMatchingRule, ruleName ? ruleName : "NULL", sizeof( m_szMatchingRule ) ); + m_Params = responseparams; - SetContext( applyContext ); + + m_szContext = applyContext; m_bApplyContextToWorld = bApplyContextToWorld; } @@ -269,35 +279,29 @@ void AI_Response::Describe() m_pCriteria->Describe(); } if ( m_szMatchingRule[ 0 ] ) - { DevMsg( "Matched rule '%s', ", m_szMatchingRule ); - } - if ( m_szContext ) - { - DevMsg( "Contexts to set '%s' on %s, ", m_szContext, m_bApplyContextToWorld ? "world" : "speaker" ); - } + if ( m_szContext.Length() ) + DevMsg( "Contexts to set '%s' on %s, ", m_szContext.Get(), m_bApplyContextToWorld ? "world" : "speaker" ); - DevMsg( "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName ); + DevMsg( "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName ); } //----------------------------------------------------------------------------- // Purpose: -// Output : char const //----------------------------------------------------------------------------- -void AI_Response::GetName( char *buf, size_t buflen ) const +const char * AI_Response::GetNamePtr() const { - Q_strncpy( buf, m_szResponseName, buflen ); + return m_szResponseName; } - //----------------------------------------------------------------------------- // Purpose: -// Output : char const //----------------------------------------------------------------------------- -void AI_Response::GetResponse( char *buf, size_t buflen ) const +const char * AI_Response::GetResponsePtr() const { - GetName( buf, buflen ); + return m_szResponseName; } + //----------------------------------------------------------------------------- // Purpose: // Input : type - @@ -313,25 +317,15 @@ const char *AI_Response::DescribeResponse( ResponseType_t type ) switch( type ) { - default: - { - Assert( 0 ); - } - // Fall through - case RESPONSE_NONE: - return "RESPONSE_NONE"; - case RESPONSE_SPEAK: - return "RESPONSE_SPEAK"; - case RESPONSE_SENTENCE: - return "RESPONSE_SENTENCE"; - case RESPONSE_SCENE: - return "RESPONSE_SCENE"; - case RESPONSE_RESPONSE: - return "RESPONSE_RESPONSE"; - case RESPONSE_PRINT: - return "RESPONSE_PRINT"; + case RESPONSE_NONE: return "RESPONSE_NONE"; + case RESPONSE_SPEAK: return "RESPONSE_SPEAK"; + case RESPONSE_SENTENCE: return "RESPONSE_SENTENCE"; + case RESPONSE_SCENE: return "RESPONSE_SCENE"; + case RESPONSE_RESPONSE: return "RESPONSE_RESPONSE"; + case RESPONSE_PRINT: return "RESPONSE_PRINT"; } + Assert( 0 ); return "RESPONSE_NONE"; } @@ -447,16 +441,7 @@ float AI_Response::GetPreDelay() const //----------------------------------------------------------------------------- void AI_Response::SetContext( const char *context ) { - delete[] m_szContext; - m_szContext = NULL; - - if ( context ) - { - int len = Q_strlen( context ); - m_szContext = new char[ len + 1 ]; - Q_memcpy( m_szContext, context, len ); - m_szContext[ len ] = 0; - } + m_szContext = context; } //----------------------------------------------------------------------------- diff --git a/game/server/AI_Criteria.h b/game/server/AI_Criteria.h index 6562db19..183453ed 100644 --- a/game/server/AI_Criteria.h +++ b/game/server/AI_Criteria.h @@ -84,8 +84,10 @@ private: Q_strncpy( value, str, sizeof( value ) ); } } - - CUtlSymbol criterianame; + + // We use CUtlRBTree CopyFrom() in ctor, so CritEntry_t must be POD. If you add + // CUtlString or something then you must change AI_CriteriaSet copy ctor. + CUtlSymbol criterianame; char value[ 64 ]; float weight; }; @@ -178,10 +180,10 @@ public: ~AI_Response(); AI_Response &operator=( const AI_Response &from ); - void Release(); + void Release(); - void GetName( char *buf, size_t buflen ) const; - void GetResponse( char *buf, size_t buflen ) const; + const char * GetNamePtr() const; + const char * GetResponsePtr() const; const AI_ResponseParams *GetParams() const { return &m_Params; } ResponseType_t GetType() const { return (ResponseType_t)m_Type; } soundlevel_t GetSoundLevel() const; @@ -195,7 +197,7 @@ public: float GetPreDelay() const; void SetContext( const char *context ); - const char * GetContext( void ) const { return m_szContext; } + const char * GetContext( void ) const { return m_szContext.Length() ? m_szContext.Get() : NULL; } bool IsApplyContextToWorld( void ) { return m_bApplyContextToWorld; } @@ -230,7 +232,7 @@ private: AI_ResponseParams m_Params; - char * m_szContext; + CUtlString m_szContext; bool m_bApplyContextToWorld; }; diff --git a/game/server/BaseAnimatingOverlay.cpp b/game/server/BaseAnimatingOverlay.cpp index a1bb1a93..b4dcb72c 100644 --- a/game/server/BaseAnimatingOverlay.cpp +++ b/game/server/BaseAnimatingOverlay.cpp @@ -104,9 +104,14 @@ void CAnimationLayer::Init( CBaseAnimatingOverlay *pOverlay ) m_nSequence = 0; m_nPriority = 0; m_nOrder.Set( CBaseAnimatingOverlay::MAX_OVERLAYS ); + + m_flBlendIn = 0.0; + m_flBlendOut = 0.0; + m_flKillRate = 100.0; m_flKillDelay = 0.0; m_flPlaybackRate = 1.0; + m_flLastEventCheck = 0.0; m_flLastAccess = gpGlobals->curtime; m_flLayerAnimtime = 0; m_flLayerFadeOuttime = 0; diff --git a/game/server/EnvFade.cpp b/game/server/EnvFade.cpp index 7e219bba..c0d7ef9a 100644 --- a/game/server/EnvFade.cpp +++ b/game/server/EnvFade.cpp @@ -95,7 +95,7 @@ void CEnvFade::InputFade( inputdata_t &inputdata ) if ( m_spawnflags & SF_FADE_ONLYONE ) { - if ( inputdata.pActivator->IsNetClient() ) + if ( inputdata.pActivator && inputdata.pActivator->IsNetClient() ) { UTIL_ScreenFade( inputdata.pActivator, m_clrRender, Duration(), HoldTime(), fadeFlags ); } diff --git a/game/server/MaterialModifyControl.cpp b/game/server/MaterialModifyControl.cpp index 176770ea..3ea32430 100644 --- a/game/server/MaterialModifyControl.cpp +++ b/game/server/MaterialModifyControl.cpp @@ -271,7 +271,7 @@ void CMaterialModifyControl::InputStartFloatLerp( inputdata_t &inputdata ) { bool bWrap = atoi(pszParam) != 0; // We don't implement wrap currently. - bWrap = bWrap; + NOTE_UNUSED( bWrap ); // Got all the parameters. Save 'em and return; m_flFloatLerpStartValue = flStartValue; diff --git a/game/server/ServerNetworkProperty.cpp b/game/server/ServerNetworkProperty.cpp index 00cba04e..28467bc9 100644 --- a/game/server/ServerNetworkProperty.cpp +++ b/game/server/ServerNetworkProperty.cpp @@ -108,6 +108,9 @@ IHandleEntity *CServerNetworkProperty::GetEntityHandle( ) void CServerNetworkProperty::Release() { delete m_pOuter; + // Don't zero m_pOuter or reference any member variables after + // the delete call because the object may be deleted. + //m_pOuter = NULL; } diff --git a/game/server/ai_activity.cpp b/game/server/ai_activity.cpp index 78d69a92..a6da835a 100644 --- a/game/server/ai_activity.cpp +++ b/game/server/ai_activity.cpp @@ -2157,4 +2157,33 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_IDLE ); ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_ARM ); ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_FIRE ); + + ADD_ACTIVITY_TO_SR( ACT_BREADSAPPER_VM_DRAW ); + ADD_ACTIVITY_TO_SR( ACT_BREADSAPPER_VM_IDLE ); + + ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_HITLEFT ); + ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_HITRIGHT ); + ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_SWINGHARD ); + ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_IDLE ); + ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_DRAW ); + + ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_GLOVES_IDLE ); + ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_GLOVES_HITRIGHT ); + ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_GLOVES_HITUP ); + + ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_VM_DRAW ); + ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_VM_IDLE ); + ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_VM_PRIMARYATTACK ); + + ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_DEPLOY ); + ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_DEPLOY_IDLE ); + ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_RETRACT ); + ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_RETRACT_IDLE ); + + ADD_ACTIVITY_TO_SR( ACT_BOT_SPAWN ); + ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC ); + ADD_ACTIVITY_TO_SR( ACT_BOT_PRIMARY_MOVEMENT ); + ADD_ACTIVITY_TO_SR( ACT_BOT_GESTURE_FLINCH ); + ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC_START ); + ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC_END ); } diff --git a/game/server/ai_basenpc.cpp b/game/server/ai_basenpc.cpp index 54b47636..2cbab903 100644 --- a/game/server/ai_basenpc.cpp +++ b/game/server/ai_basenpc.cpp @@ -7710,7 +7710,9 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) if (!pEnemy || !pEnemy->IsAlive()) { if ( pEnemy ) + { DbgEnemyMsg( this, " %s rejected: dead\n", pEnemy->GetDebugName() ); + } continue; } @@ -7785,7 +7787,9 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) { DbgEnemyMsg( this, " %s accepted (1)\n", pEnemy->GetDebugName() ); if ( pBestEnemy ) + { DbgEnemyMsg( this, " (%s displaced)\n", pBestEnemy->GetDebugName() ); + } iBestPriority = IRelationPriority ( pEnemy ); iBestDistSq = (pEnemy->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); @@ -7799,7 +7803,9 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) { DbgEnemyMsg( this, " %s accepted\n", pEnemy->GetDebugName() ); if ( pBestEnemy ) + { DbgEnemyMsg( this, " (%s displaced due to priority, %d > %d )\n", pBestEnemy->GetDebugName(), IRelationPriority( pEnemy ), iBestPriority ); + } // this entity is disliked MORE than the entity that we // currently think is the best visible enemy. No need to do // a distance check, just get mad at this one for now. @@ -7933,7 +7939,9 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) DbgEnemyMsg( this, " %s accepted\n", pEnemy->GetDebugName() ); if ( pBestEnemy ) + { DbgEnemyMsg( this, " (%s displaced due to distance/visibility)\n", pBestEnemy->GetDebugName() ); + } fBestSeen = fCurSeen; fBestVisible = fCurVisible; iBestDistSq = iDistSq; @@ -7942,7 +7950,9 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) bBestUnreachable = bUnreachable; } else + { DbgEnemyMsg( this, " %s rejected: lower priority\n", pEnemy->GetDebugName() ); + } } DbgEnemyMsg( this, "} == %s\n", pBestEnemy->GetDebugName() ); @@ -8033,6 +8043,7 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget ) { vecProjection.x = -vecTarget.y; vecProjection.y = vecTarget.x; + vecProjection.z = 0; return UTIL_VecToYaw( vecProjection - GetLocalOrigin() ); } @@ -8040,6 +8051,7 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget ) { vecProjection.x = vecTarget.y; vecProjection.y = vecTarget.x; + vecProjection.z = 0; return UTIL_VecToYaw( vecProjection - GetLocalOrigin() ); } diff --git a/game/server/ai_basenpc.h b/game/server/ai_basenpc.h index f5224f15..7abad0ae 100644 --- a/game/server/ai_basenpc.h +++ b/game/server/ai_basenpc.h @@ -1761,7 +1761,6 @@ public: virtual Activity GetFlinchActivity( bool bHeavyDamage, bool bGesture ); - virtual bool ShouldGib( const CTakeDamageInfo &info ) { return false; } // Always ragdoll, unless specified by the leaf class virtual bool Event_Gibbed( const CTakeDamageInfo &info ); virtual void Event_Killed( const CTakeDamageInfo &info ); diff --git a/game/server/ai_behavior_lead.cpp b/game/server/ai_behavior_lead.cpp index cc4e0aed..18c7f3cc 100644 --- a/game/server/ai_behavior_lead.cpp +++ b/game/server/ai_behavior_lead.cpp @@ -269,7 +269,7 @@ bool CAI_LeadBehavior::GetClosestPointOnRoute( const Vector &targetPos, Vector * float flNearestDist = 999999999; float flPathDist, flPathDist2D; - Vector vecNearestPoint; + Vector vecNearestPoint(0, 0, 0); Vector vecPrevPos = GetOuter()->GetAbsOrigin(); for ( ; (waypoint != NULL) ; waypoint = waypoint->GetNext() ) { diff --git a/game/server/ai_blended_movement.cpp b/game/server/ai_blended_movement.cpp index 0e150702..8e3426ba 100644 --- a/game/server/ai_blended_movement.cpp +++ b/game/server/ai_blended_movement.cpp @@ -1864,7 +1864,7 @@ float ChangeDistance( float flInterval, float flGoalDistance, float flGoalVeloci // I need to speed up flNewVelocity = flCurVelocity + flGoalAccel * flInterval; if (flNewVelocity > flGoalVelocity) - flGoalVelocity = flGoalVelocity; + flNewVelocity = flGoalVelocity; } else if (flNewVelocity < flIdealVelocity) { diff --git a/game/server/ai_debug.h b/game/server/ai_debug.h index 0285240d..0281281d 100644 --- a/game/server/ai_debug.h +++ b/game/server/ai_debug.h @@ -51,8 +51,8 @@ enum AIMsgFlags AIMF_IGNORE_SELECTED = 0x01 }; -void DevMsg( CAI_BaseNPC *pAI, unsigned flags, PRINTF_FORMAT_STRING const char *pszFormat, ... ); -void DevMsg( CAI_BaseNPC *pAI, PRINTF_FORMAT_STRING const char *pszFormat, ... ); +void DevMsg( CAI_BaseNPC *pAI, unsigned flags, PRINTF_FORMAT_STRING const char *pszFormat, ... ) FMTFUNCTION( 3, 4 ); +void DevMsg( CAI_BaseNPC *pAI, PRINTF_FORMAT_STRING const char *pszFormat, ... ) FMTFUNCTION( 2, 3 ); //----------------------------------------------------------------------------- diff --git a/game/server/ai_movesolver.cpp b/game/server/ai_movesolver.cpp index a2af1a99..40ebd64d 100644 --- a/game/server/ai_movesolver.cpp +++ b/game/server/ai_movesolver.cpp @@ -114,7 +114,7 @@ bool CAI_MoveSolver::Solve( const AI_MoveSuggestion_t *pSuggestions, int nSugges AI_MoveSuggestion_t *pHighSuggestion; }; - Solution_t solutions[NUM_SOLUTIONS] = { 0 }; + Solution_t solutions[NUM_SOLUTIONS] = { { 0, 0, NULL } }; //--------------------------------- diff --git a/game/server/ai_navigator.h b/game/server/ai_navigator.h index 07321570..c5a1db13 100644 --- a/game/server/ai_navigator.h +++ b/game/server/ai_navigator.h @@ -43,7 +43,7 @@ extern ConVar ai_debug_nav; do \ { \ if (DbgNav()) \ - DevMsg( pAI, CFmtStr( "[Nav] %s", static_cast(pszMsg) ) ); \ + DevMsg( pAI, "[Nav] %s", static_cast(pszMsg) ); \ } while (0) #define DbgNavMsg1( pAI, pszMsg, a ) DbgNavMsg( pAI, CFmtStr(static_cast(pszMsg), (a) ) ) #define DbgNavMsg2( pAI, pszMsg, a, b ) DbgNavMsg( pAI, CFmtStr(static_cast(pszMsg), (a), (b) ) ) diff --git a/game/server/ai_playerally.cpp b/game/server/ai_playerally.cpp index ac644805..84a3746e 100644 --- a/game/server/ai_playerally.cpp +++ b/game/server/ai_playerally.cpp @@ -548,10 +548,11 @@ void CAI_PlayerAlly::PrescheduleThink( void ) if ( m_flNextIdleSpeechTime && m_flNextIdleSpeechTime < gpGlobals->curtime ) { AISpeechSelection_t selection; + if ( SelectNonCombatSpeech( &selection ) ) { SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.pResponse ); + SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); m_flNextIdleSpeechTime = gpGlobals->curtime + RandomFloat( 20,30 ); } else @@ -593,22 +594,23 @@ bool CAI_PlayerAlly::SelectSpeechResponse( AIConcept_t concept, const char *pszM { if ( IsAllowedToSpeak( concept ) ) { - AI_Response *pResponse = SpeakFindResponse( concept, pszModifiers ); - if ( pResponse ) + bool result = SpeakFindResponse( pSelection->Response, concept, pszModifiers ); + if ( result ) { - pSelection->Set( concept, pResponse, pTarget ); + pSelection->concept = concept; + pSelection->hSpeechTarget = pTarget; return true; } } + return false; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CAI_PlayerAlly::SetPendingSpeech( AIConcept_t concept, AI_Response *pResponse ) +void CAI_PlayerAlly::SetPendingSpeech( AIConcept_t concept, AI_Response &Response ) { - m_PendingResponse = *pResponse; - pResponse->Release(); + m_PendingResponse = Response; m_PendingConcept = concept; m_TimePendingSet = gpGlobals->curtime; } @@ -690,7 +692,7 @@ bool CAI_PlayerAlly::SelectInterjection() if ( SelectIdleSpeech( &selection ) ) { SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.pResponse ); + SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); return true; } } @@ -889,9 +891,8 @@ void CAI_PlayerAlly::AnswerQuestion( CAI_PlayerAlly *pQuestioner, int iQARandomN } } - Assert( selection.pResponse ); SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.pResponse ); + SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); // Prevent idle speech for a while DeferAllIdleSpeech( random->RandomFloat( TALKER_DEFER_IDLE_SPEAK_MIN, TALKER_DEFER_IDLE_SPEAK_MAX ), GetSpeechTarget()->MyNPCPointer() ); @@ -939,11 +940,11 @@ int CAI_PlayerAlly::SelectNonCombatSpeechSchedule() if ( !HasPendingSpeech() ) { AISpeechSelection_t selection; + if ( SelectNonCombatSpeech( &selection ) ) { - Assert( selection.pResponse ); SetSpeechTarget( selection.hSpeechTarget ); - SetPendingSpeech( selection.concept.c_str(), selection.pResponse ); + SetPendingSpeech( selection.concept.c_str(), selection.Response ); } } @@ -1018,14 +1019,14 @@ void CAI_PlayerAlly::StartTask( const Task_t *pTask ) case TASK_TALKER_SPEAK_PENDING: if ( !m_PendingConcept.empty() ) { - AI_Response *pResponse = new AI_Response; - *pResponse = m_PendingResponse; - SpeakDispatchResponse( m_PendingConcept.c_str(), pResponse ); + SpeakDispatchResponse( m_PendingConcept.c_str(), m_PendingResponse ); m_PendingConcept.erase(); TaskComplete(); } else + { TaskFail( FAIL_NO_SOUND ); + } break; default: @@ -1692,15 +1693,15 @@ bool CAI_PlayerAlly::RespondedTo( const char *ResponseConcept, bool bForce, bool { // We're being forced to respond to the event, probably because it's the // player dying or something equally important. - AI_Response *result = SpeakFindResponse( ResponseConcept, NULL ); + AI_Response response; + bool result = SpeakFindResponse( response, ResponseConcept, NULL ); if ( result ) { // We've got something to say. Stop any scenes we're in, and speak the response. if ( bCancelScene ) RemoveActorFromScriptedScenes( this, false ); - bool spoke = SpeakDispatchResponse( ResponseConcept, result ); - return spoke; + return SpeakDispatchResponse( ResponseConcept, response ); } return false; diff --git a/game/server/ai_playerally.h b/game/server/ai_playerally.h index 13b4bccf..c6f1f9a9 100644 --- a/game/server/ai_playerally.h +++ b/game/server/ai_playerally.h @@ -248,21 +248,9 @@ enum AISpeechTargetSearchFlags_t struct AISpeechSelection_t { - AISpeechSelection_t() - : pResponse(NULL) - { - } - - void Set( AIConcept_t newConcept, AI_Response *pNewResponse, CBaseEntity *pTarget = NULL ) - { - pResponse = pNewResponse; - concept = newConcept; - hSpeechTarget = pTarget; - } - - std::string concept; - AI_Response * pResponse; - EHANDLE hSpeechTarget; + std::string concept; + AI_Response Response; + EHANDLE hSpeechTarget; }; //------------------------------------- @@ -347,7 +335,7 @@ public: //--------------------------------- bool SelectSpeechResponse( AIConcept_t concept, const char *pszModifiers, CBaseEntity *pTarget, AISpeechSelection_t *pSelection ); - void SetPendingSpeech( AIConcept_t concept, AI_Response *pResponse ); + void SetPendingSpeech( AIConcept_t concept, AI_Response &Response ); void ClearPendingSpeech(); bool HasPendingSpeech() { return !m_PendingConcept.empty(); } diff --git a/game/server/ai_speech.cpp b/game/server/ai_speech.cpp index 51550652..1827d2c2 100644 --- a/game/server/ai_speech.cpp +++ b/game/server/ai_speech.cpp @@ -38,10 +38,7 @@ CAI_TimedSemaphore g_AIFoesTalkSemaphore; ConceptHistory_t::~ConceptHistory_t() { - if ( response ) - { - delete response; - } + delete response; response = NULL; } @@ -57,14 +54,16 @@ ConceptHistory_t::ConceptHistory_t( const ConceptHistory_t& src ) ConceptHistory_t& ConceptHistory_t::operator =( const ConceptHistory_t& src ) { - if ( this == &src ) - return *this; - - timeSpoken = src.timeSpoken; - response = NULL; - if ( src.response ) + if ( this != &src ) { - response = new AI_Response( *src.response ); + timeSpoken = src.timeSpoken; + + delete response; + response = NULL; + if ( src.response ) + { + response = new AI_Response( *src.response ); + } } return *this; @@ -89,14 +88,14 @@ public: pSave->StartBlock(); { - // Write element name pSave->WriteString( ch->GetElementName( i ) ); // Write data pSave->WriteAll( pHistory ); + // Write response blob - bool hasresponse = pHistory->response != NULL ? true : false; + bool hasresponse = !!pHistory->response; pSave->WriteBool( &hasresponse ); if ( hasresponse ) { @@ -118,6 +117,7 @@ public: { char conceptname[ 512 ]; conceptname[ 0 ] = 0; + ConceptHistory_t history; pRestore->StartBlock(); @@ -127,7 +127,6 @@ public: pRestore->ReadAll( &history ); bool hasresponse = false; - pRestore->ReadBool( &hasresponse ); if ( hasresponse ) { @@ -151,7 +150,7 @@ public: } } } - + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) { } @@ -251,14 +250,14 @@ void CAI_Expresser::TestAllResponses() if ( pResponseSystem ) { CUtlVector responses; + pResponseSystem->GetAllResponses( &responses ); for ( int i = 0; i < responses.Count(); i++ ) { - char response[ 256 ]; - responses[i]->GetResponse( response, sizeof( response ) ); + const char *szResponse = responses[i]->GetResponsePtr(); - Msg( "Response: %s\n", response ); - SpeakDispatchResponse( "", responses[i] ); + Msg( "Response: %s\n", szResponse ); + SpeakDispatchResponse( "", *responses[i] ); } } } @@ -273,13 +272,13 @@ static const int LEN_SPECIFIC_SCENE_MODIFIER = strlen( AI_SPECIFIC_SCENE_MODIFIE // NULL - // Output : AI_Response //----------------------------------------------------------------------------- -AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t concept, const char *modifiers /*= NULL*/ ) +bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t concept, const char *modifiers /*= NULL*/ ) { IResponseSystem *rs = GetOuter()->GetResponseSystem(); if ( !rs ) { Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); - return NULL; + return false; } AI_CriteriaSet set; @@ -287,7 +286,7 @@ AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t concept, const char * set.AppendCriteria( "concept", concept, CONCEPT_WEIGHT ); // Always include any optional modifiers - if ( modifiers != NULL ) + if ( modifiers ) { char copy_modifiers[ 255 ]; const char *pCopy; @@ -320,30 +319,19 @@ AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t concept, const char * } // Now that we have a criteria set, ask for a suitable response - AI_Response *result = new AI_Response; - Assert( result && "new AI_Response: Returned a NULL AI_Response!" ); - bool found = rs->FindBestResponse( set, *result, this ); + bool found = rs->FindBestResponse( set, outResponse, this ); if ( rr_debugresponses.GetInt() == 3 ) { if ( ( GetOuter()->MyNPCPointer() && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) || GetOuter()->IsPlayer() ) { - const char *pszName; - if ( GetOuter()->IsPlayer() ) - { - pszName = ((CBasePlayer*)GetOuter())->GetPlayerName(); - } - else - { - pszName = GetOuter()->GetDebugName(); - } + const char *pszName = GetOuter()->IsPlayer() ? + ((CBasePlayer*)GetOuter())->GetPlayerName() : GetOuter()->GetDebugName(); if ( found ) { - char response[ 256 ]; - result->GetResponse( response, sizeof( response ) ); - - Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, concept, response ); + const char *szReponse = outResponse.GetResponsePtr(); + Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, concept, szReponse ); } else { @@ -353,44 +341,28 @@ AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t concept, const char * } if ( !found ) - { - //Assert( !"rs->FindBestResponse: Returned a NULL AI_Response!" ); - delete result; - return NULL; - } + return false; - char response[ 256 ]; - result->GetResponse( response, sizeof( response ) ); + const char *szReponse = outResponse.GetResponsePtr(); + if ( !szReponse[0] ) + return false; - if ( !response[0] ) - { - delete result; - return NULL; - } + if ( ( outResponse.GetOdds() < 100 ) && ( random->RandomInt( 1, 100 ) <= outResponse.GetOdds() ) ) + return false; - if ( result->GetOdds() < 100 && random->RandomInt( 1, 100 ) <= result->GetOdds() ) - { - delete result; - return NULL; - } - - return result; + return true; } //----------------------------------------------------------------------------- // Purpose: Dispatches the result // Input : *response - //----------------------------------------------------------------------------- -bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *result, IRecipientFilter *filter /* = NULL */ ) +bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& response, IRecipientFilter *filter /* = NULL */ ) { - char response[ 256 ]; - result->GetResponse( response, sizeof( response ) ); - - float delay = result->GetDelay(); - bool spoke = false; - - soundlevel_t soundlevel = result->GetSoundLevel(); + float delay = response.GetDelay(); + const char *szResponse = response.GetResponsePtr(); + soundlevel_t soundlevel = response.GetSoundLevel(); if ( IsSpeaking() && concept[0] != 0 ) { @@ -404,63 +376,52 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res if ( IsRunningScriptedScene( GetOuter() ) ) { DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); - delete result; return false; } } - switch ( result->GetType() ) + switch ( response.GetType() ) { default: case RESPONSE_NONE: break; case RESPONSE_SPEAK: + if ( !response.ShouldntUseScene() ) { - if ( !result->ShouldntUseScene() ) - { - // This generates a fake CChoreoScene wrapping the sound.txt name - spoke = SpeakAutoGeneratedScene( response, delay ); - } - else - { - float speakTime = GetResponseDuration( result ); - GetOuter()->EmitSound( response ); + // This generates a fake CChoreoScene wrapping the sound.txt name + spoke = SpeakAutoGeneratedScene( szResponse, delay ); + } + else + { + float speakTime = GetResponseDuration( response ); + GetOuter()->EmitSound( szResponse ); - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); - NoteSpeaking( speakTime, delay ); - spoke = true; - } + DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), szResponse ); + NoteSpeaking( speakTime, delay ); + spoke = true; } break; case RESPONSE_SENTENCE: - { - spoke = ( -1 != SpeakRawSentence( response, delay, VOL_NORM, soundlevel ) ) ? true : false; - } + spoke = ( -1 != SpeakRawSentence( szResponse, delay, VOL_NORM, soundlevel ) ) ? true : false; break; case RESPONSE_SCENE: - { - spoke = SpeakRawScene( response, delay, result, filter ); - } + spoke = SpeakRawScene( szResponse, delay, &response, filter ); break; case RESPONSE_RESPONSE: - { - // This should have been recursively resolved already - Assert( 0 ); - } + // This should have been recursively resolved already + Assert( 0 ); break; case RESPONSE_PRINT: + if ( g_pDeveloper->GetInt() > 0 ) { - if ( g_pDeveloper->GetInt() > 0 ) - { - Vector vPrintPos; - GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); - NDebugOverlay::Text( vPrintPos, response, true, 1.5 ); - spoke = true; - } + Vector vPrintPos; + GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); + NDebugOverlay::Text( vPrintPos, szResponse, true, 1.5 ); + spoke = true; } break; } @@ -468,30 +429,27 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res if ( spoke ) { m_flLastTimeAcceptedSpeak = gpGlobals->curtime; - if ( DebuggingSpeech() && g_pDeveloper->GetInt() > 0 && response && result->GetType() != RESPONSE_PRINT ) + if ( DebuggingSpeech() && g_pDeveloper->GetInt() > 0 && response.GetType() != RESPONSE_PRINT ) { Vector vPrintPos; GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); - NDebugOverlay::Text( vPrintPos, CFmtStr( "%s: %s", concept, response ), true, 1.5 ); + NDebugOverlay::Text( vPrintPos, CFmtStr( "%s: %s", concept, szResponse ), true, 1.5 ); } - if ( result->IsApplyContextToWorld() ) + if ( response.IsApplyContextToWorld() ) { CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( 0 ) ); if ( pEntity ) { - pEntity->AddContext( result->GetContext() ); + pEntity->AddContext( response.GetContext() ); } } else { - GetOuter()->AddContext( result->GetContext() ); + GetOuter()->AddContext( response.GetContext() ); } - SetSpokeConcept( concept, result ); - } - else - { - delete result; + + SetSpokeConcept( concept, &response ); } return spoke; @@ -502,44 +460,33 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res // Input : *response - // Output : float //----------------------------------------------------------------------------- -float CAI_Expresser::GetResponseDuration( AI_Response *result ) +float CAI_Expresser::GetResponseDuration( AI_Response& response ) { - Assert( result ); - char response[ 256 ]; - result->GetResponse( response, sizeof( response ) ); + const char *szResponse = response.GetResponsePtr(); - switch ( result->GetType() ) + switch ( response.GetType() ) { default: case RESPONSE_NONE: break; + case RESPONSE_SPEAK: - { - return GetOuter()->GetSoundDuration( response, STRING( GetOuter()->GetModelName() ) ); - } - break; + return GetOuter()->GetSoundDuration( szResponse, STRING( GetOuter()->GetModelName() ) ); + case RESPONSE_SENTENCE: - { - Assert( 0 ); - return 999.0f; - } - break; + Assert( 0 ); + return 999.0f; + case RESPONSE_SCENE: - { - return GetSceneDuration( response ); - } - break; + return GetSceneDuration( szResponse ); + case RESPONSE_RESPONSE: - { - // This should have been recursively resolved already - Assert( 0 ); - } + // This should have been recursively resolved already + Assert( 0 ); break; + case RESPONSE_PRINT: - { - return 1.0; - } - break; + return 1.0; } return 0.0f; @@ -552,18 +499,18 @@ float CAI_Expresser::GetResponseDuration( AI_Response *result ) //----------------------------------------------------------------------------- bool CAI_Expresser::Speak( AIConcept_t concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) { - AI_Response *result = SpeakFindResponse( concept, modifiers ); + AI_Response response; + bool result = SpeakFindResponse( response, concept, modifiers ); if ( !result ) - { return false; - } SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), concept, gpGlobals->curtime ); - bool spoke = SpeakDispatchResponse( concept, result, filter ); + bool spoke = SpeakDispatchResponse( concept, response, filter ); if ( pszOutResponseChosen ) { - result->GetResponse( pszOutResponseChosen, bufsize ); + const char *szResponse = response.GetResponsePtr(); + Q_strncpy( pszOutResponseChosen, szResponse, bufsize ); } return spoke; @@ -808,17 +755,12 @@ void CAI_Expresser::SetSpokeConcept( AIConcept_t concept, AI_Response *response, ConceptHistory_t *slot = &m_ConceptHistories[ idx ]; slot->timeSpoken = gpGlobals->curtime; + // Update response info if ( response ) { - AI_Response *r = slot->response; - if ( r ) - { - delete r; - } - - // FIXME: Are we leaking AI_Responses? - slot->response = response; + delete slot->response; + slot->response = new AI_Response( *response ); } if ( bCallback ) @@ -885,13 +827,13 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ) if ( pFlex->MyNPCPointer() ) { - DevMsg( pFlex->MyNPCPointer(), string ); + DevMsg( pFlex->MyNPCPointer(), "%s", string ); } else { DevMsg( "%s", string ); } - UTIL_LogPrintf( string ); + UTIL_LogPrintf( "%s", string ); } diff --git a/game/server/ai_speech.h b/game/server/ai_speech.h index e4610b37..91dc389b 100644 --- a/game/server/ai_speech.h +++ b/game/server/ai_speech.h @@ -135,7 +135,7 @@ struct ConceptHistory_t ConceptHistory_t& operator = ( const ConceptHistory_t& src ); ~ConceptHistory_t(); - + float timeSpoken; AI_Response *response; }; @@ -159,9 +159,9 @@ public: bool Speak( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); // These two methods allow looking up a response and dispatching it to be two different steps - AI_Response *SpeakFindResponse( AIConcept_t concept, const char *modifiers = NULL ); - bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, IRecipientFilter *filter = NULL ); - float GetResponseDuration( AI_Response *response ); + bool SpeakFindResponse( AI_Response &response, AIConcept_t concept, const char *modifiers = NULL ); + bool SpeakDispatchResponse( AIConcept_t concept, AI_Response &response, IRecipientFilter *filter = NULL ); + float GetResponseDuration( AI_Response &response ); virtual int SpeakRawSentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); @@ -283,10 +283,10 @@ public: virtual bool Speak( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); // These two methods allow looking up a response and dispatching it to be two different steps - AI_Response * SpeakFindResponse( AIConcept_t concept, const char *modifiers = NULL ); - bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response ); - virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response *response ) { return; } - float GetResponseDuration( AI_Response *response ); + bool SpeakFindResponse( AI_Response& response, AIConcept_t concept, const char *modifiers = NULL ); + bool SpeakDispatchResponse( AIConcept_t concept, AI_Response& response ); + virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response& response ) { return; } + float GetResponseDuration( AI_Response& response ); float GetTimeSpeechComplete() const { return this->GetExpresser()->GetTimeSpeechComplete(); } @@ -360,15 +360,15 @@ inline IResponseSystem *CAI_ExpresserHost::GetResponseSystem() //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t concept, const char *modifiers /*= NULL*/ ) +inline bool CAI_ExpresserHost::SpeakFindResponse( AI_Response& response, AIConcept_t concept, const char *modifiers /*= NULL*/ ) { - return this->GetExpresser()->SpeakFindResponse( concept, modifiers ); + return this->GetExpresser()->SpeakFindResponse( response, concept, modifiers ); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t concept, AI_Response *response ) +inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t concept, AI_Response& response ) { if ( this->GetExpresser()->SpeakDispatchResponse( concept, response ) ) { @@ -382,7 +382,7 @@ inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t conc //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline float CAI_ExpresserHost::GetResponseDuration( AI_Response *response ) +inline float CAI_ExpresserHost::GetResponseDuration( AI_Response& response ) { return this->GetExpresser()->GetResponseDuration( response ); } diff --git a/game/server/ai_utils.cpp b/game/server/ai_utils.cpp index 3119d2f8..88c09e75 100644 --- a/game/server/ai_utils.cpp +++ b/game/server/ai_utils.cpp @@ -46,7 +46,7 @@ END_DATADESC() CAI_ShotRegulator::CAI_ShotRegulator() : m_nMinBurstShots(1), m_nMaxBurstShots(1) { m_flMinRestInterval = 0.0f; - m_flMinRestInterval = 0.0f; + m_flMaxRestInterval = 0.0f; m_flMinBurstInterval = 0.0f; m_flMaxBurstInterval = 0.0f; m_flNextShotTime = -1; diff --git a/game/server/baseentity.cpp b/game/server/baseentity.cpp index a023a767..781a6c55 100644 --- a/game/server/baseentity.cpp +++ b/game/server/baseentity.cpp @@ -303,7 +303,7 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity ) SendPropBool( SENDINFO( m_bAlternateSorting )), #ifdef TF_DLL - SendPropArray3( SENDINFO_ARRAY3(m_nModelIndexOverrides), SendPropInt( SENDINFO_ARRAY(m_nModelIndexOverrides), SP_MODEL_INDEX_BITS, SPROP_UNSIGNED ) ), + SendPropArray3( SENDINFO_ARRAY3(m_nModelIndexOverrides), SendPropInt( SENDINFO_ARRAY(m_nModelIndexOverrides), SP_MODEL_INDEX_BITS, 0 ) ), #endif END_SEND_TABLE() @@ -344,6 +344,8 @@ void CBaseEntityModelLoadProxy::Handler::OnModelLoadComplete( const model_t *pMo CBaseEntity::CBaseEntity( bool bServerOnly ) { + m_pAttributes = NULL; + COMPILE_TIME_ASSERT( MOVETYPE_LAST < (1 << MOVETYPE_MAX_BITS) ); COMPILE_TIME_ASSERT( MOVECOLLIDE_COUNT < (1 << MOVECOLLIDE_MAX_BITS) ); @@ -4822,7 +4824,7 @@ void CBaseEntity::PrecacheModelComponents( int nModelIndex ) char token[256]; const char *pOptions = pEvent->pszOptions(); nexttoken( token, pOptions, ' ' ); - if ( token ) + if ( token[0] ) { PrecacheParticleSystem( token ); } @@ -4908,7 +4910,9 @@ int CBaseEntity::PrecacheModel( const char *name, bool bPreload ) { if ( !name || !*name ) { +#ifdef STAGING_ONLY Msg( "Attempting to precache model, but model name is NULL\n"); +#endif return -1; } @@ -4917,8 +4921,7 @@ int CBaseEntity::PrecacheModel( const char *name, bool bPreload ) { if ( !engine->IsModelPrecached( name ) ) { - Assert( !"CBaseEntity::PrecacheModel: too late" ); - Warning( "Late precache of %s\n", name ); + DevMsg( "Late precache of %s -- not necessarily a bug now that we allow ~everything to be dynamically loaded.\n", name ); } } #if defined( WATCHACCESS ) @@ -5316,11 +5319,6 @@ void CC_Ent_FireTarget( const CCommand& args ) } static ConCommand firetarget("firetarget", CC_Ent_FireTarget, 0, FCVAR_CHEAT); -static bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs ) -{ - return Q_stricmp( lhs.String(), rhs.String() ) < 0; -} - class CEntFireAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback { public: @@ -6656,23 +6654,19 @@ void CBaseEntity::DispatchResponse( const char *conceptName ) AI_Response result; bool found = rs->FindBestResponse( set, result ); if ( !found ) - { return; - } // Handle the response here... - char response[ 256 ]; - result.GetResponse( response, sizeof( response ) ); + const char *szResponse = result.GetResponsePtr(); switch ( result.GetType() ) { case RESPONSE_SPEAK: - { - EmitSound( response ); - } + EmitSound( szResponse ); break; + case RESPONSE_SENTENCE: { - int sentenceIndex = SENTENCEG_Lookup( response ); + int sentenceIndex = SENTENCEG_Lookup( szResponse ); if( sentenceIndex == -1 ) { // sentence not found @@ -6684,16 +6678,13 @@ void CBaseEntity::DispatchResponse( const char *conceptName ) CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM ); } break; - case RESPONSE_SCENE: - { - // Try to fire scene w/o an actor - InstancedScriptedScene( NULL, response ); - } - break; - case RESPONSE_PRINT: - { - } + case RESPONSE_SCENE: + // Try to fire scene w/o an actor + InstancedScriptedScene( NULL, szResponse ); + break; + + case RESPONSE_PRINT: break; default: // Don't know how to handle .vcds!!! @@ -7051,7 +7042,7 @@ void CBaseEntity::SetRefEHandle( const CBaseHandle &handle ) if ( edict() ) { COMPILE_TIME_ASSERT( NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS <= 8*sizeof( edict()->m_NetworkSerialNumber ) ); - edict()->m_NetworkSerialNumber = (m_RefEHandle.GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1); + edict()->m_NetworkSerialNumber = m_RefEHandle.GetSerialNumber() & ( (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1 ); } } diff --git a/game/server/baseentity.h b/game/server/baseentity.h index 7bcc3c2e..758c335a 100644 --- a/game/server/baseentity.h +++ b/game/server/baseentity.h @@ -83,7 +83,7 @@ class CUserCmd; class CSkyCamera; class CEntityMapData; class INextBot; - +class IHasAttributes; typedef CUtlVector< CBaseEntity* > EntityList_t; @@ -1087,49 +1087,57 @@ public: int GetHealth() const { return m_iHealth; } void SetHealth( int amt ) { m_iHealth = amt; } + float HealthFraction() const; + // Ugly code to lookup all functions to make sure they are in the table when set. #ifdef _DEBUG - void FunctionCheck( void *pFunction, const char *name ); +#ifdef GNUC +#define ENTITYFUNCPTR_SIZE 8 +#else +#define ENTITYFUNCPTR_SIZE 4 +#endif + + void FunctionCheck( void *pFunction, const char *name ); ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name ) { -#ifdef GNUC - COMPILE_TIME_ASSERT( sizeof(func) == 8 ); -#else - COMPILE_TIME_ASSERT( sizeof(func) == 4 ); -#endif + COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE ); m_pfnTouch = func; FunctionCheck( *(reinterpret_cast(&m_pfnTouch)), name ); return func; } USEPTR UseSet( USEPTR func, char *name ) { -#ifdef GNUC - COMPILE_TIME_ASSERT( sizeof(func) == 8 ); -#else - COMPILE_TIME_ASSERT( sizeof(func) == 4 ); -#endif + COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE ); m_pfnUse = func; FunctionCheck( *(reinterpret_cast(&m_pfnUse)), name ); return func; } ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name ) { -#ifdef GNUC - COMPILE_TIME_ASSERT( sizeof(func) == 8 ); -#else - COMPILE_TIME_ASSERT( sizeof(func) == 4 ); -#endif + COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE ); m_pfnBlocked = func; FunctionCheck( *(reinterpret_cast(&m_pfnBlocked)), name ); return func; } -#endif +#endif // _DEBUG + virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); void AppendContextToCriteria( AI_CriteriaSet& set, const char *prefix = "" ); void DumpResponseCriteria( void ); - + + // Return the IHasAttributes interface for this base entity. Removes the need for: + // dynamic_cast< IHasAttributes * >( pEntity ); + // Which is remarkably slow. + // GetAttribInterface( CBaseEntity *pEntity ) in attribute_manager.h uses + // this function, tests for NULL, and Asserts m_pAttributes == dynamic_cast. + inline IHasAttributes *GetHasAttributesInterfacePtr() const { return m_pAttributes; } + +protected: + // NOTE: m_pAttributes needs to be set in the leaf class constructor. + IHasAttributes *m_pAttributes; + private: friend class CAI_Senses; CBaseEntity *m_pLink;// used for temporary link-list operations. diff --git a/game/server/baseflex.cpp b/game/server/baseflex.cpp index f173a04d..0687894b 100644 --- a/game/server/baseflex.cpp +++ b/game/server/baseflex.cpp @@ -1318,9 +1318,9 @@ static Activity DetermineExpressionMoveActivity( CChoreoEvent *event, CAI_BaseNP // Custom distance styles are appended to param2 with a space as a separator const char *pszAct = Q_strstr( sParam2, " " ); + char szActName[256]; if ( pszAct ) { - char szActName[256]; Q_strncpy( szActName, sParam2, sizeof(szActName) ); szActName[ (pszAct-sParam2) ] = '\0'; pszAct = szActName; @@ -2555,7 +2555,7 @@ void CFlexCycler::Think( void ) { m_flexnum = LookupFlex( szTemp ); - if (m_flexnum != -1 && m_flextarget[m_flexnum] != 1) + if (m_flexnum != LocalFlexController_t(-1) && m_flextarget[m_flexnum] != 1) { m_flextarget[m_flexnum] = 1.0; // SetFlexTarget( m_flexnum ); diff --git a/game/server/basemultiplayerplayer.cpp b/game/server/basemultiplayerplayer.cpp index ee5338e1..d467c14e 100644 --- a/game/server/basemultiplayerplayer.cpp +++ b/game/server/basemultiplayerplayer.cpp @@ -87,10 +87,11 @@ IResponseSystem *CBaseMultiplayerPlayer::GetResponseSystem() //----------------------------------------------------------------------------- // Purpose: Doesn't actually speak the concept. Just finds a response in the system. You then have to play it yourself. //----------------------------------------------------------------------------- -AI_Response *CBaseMultiplayerPlayer::SpeakConcept( int iConcept ) +bool CBaseMultiplayerPlayer::SpeakConcept( AI_Response &response, int iConcept ) { + // Save the current concept. m_iCurrentConcept = iConcept; - return SpeakFindResponse( g_pszMPConcepts[iConcept] ); + return SpeakFindResponse( response, g_pszMPConcepts[iConcept] ); } //----------------------------------------------------------------------------- diff --git a/game/server/basemultiplayerplayer.h b/game/server/basemultiplayerplayer.h index 8d61c3f2..0153adee 100644 --- a/game/server/basemultiplayerplayer.h +++ b/game/server/basemultiplayerplayer.h @@ -28,7 +28,7 @@ public: virtual bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); virtual IResponseSystem *GetResponseSystem(); - AI_Response *SpeakConcept( int iConcept ); + bool SpeakConcept( AI_Response& response, int iConcept ); virtual bool SpeakConceptIfAllowed( int iConcept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); virtual bool CanHearAndReadChatFrom( CBasePlayer *pPlayer ); diff --git a/game/server/cbase.cpp b/game/server/cbase.cpp index 944e6841..c6caba7a 100644 --- a/game/server/cbase.cpp +++ b/game/server/cbase.cpp @@ -281,7 +281,11 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) output: (%s,%s) -> (%s,%s,%.1f)(%s)\n", +#ifdef TF_DLL engine->GetServerTime(), +#else + gpGlobals->curtime, +#endif pCaller ? STRING(pCaller->m_iClassname) : "NULL", pCaller ? STRING(pCaller->GetEntityName()) : "NULL", STRING(ev->m_iTarget), @@ -298,7 +302,11 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) output: (%s,%s) -> (%s,%s)(%s)\n", +#ifdef TF_DLL engine->GetServerTime(), +#else + gpGlobals->curtime, +#endif pCaller ? STRING(pCaller->m_iClassname) : "NULL", pCaller ? STRING(pCaller->GetEntityName()) : "NULL", STRING(ev->m_iTarget), STRING(ev->m_iTargetInput), @@ -459,7 +467,7 @@ void CBaseEntityOutput::DeleteAllElements( void ) m_ActionList = NULL; while (pNext) { - register CEventAction *strikeThis = pNext; + CEventAction *strikeThis = pNext; pNext = pNext->m_pNext; delete strikeThis; } @@ -767,7 +775,13 @@ void CEventQueue::Dump( void ) { EventQueuePrioritizedEvent_t *pe = m_Events.m_pNext; - Msg( "Dumping event queue. Current time is: %.2f\n", engine->GetServerTime() ); + Msg("Dumping event queue. Current time is: %.2f\n", +#ifdef TF_DLL + engine->GetServerTime() +#else + gpGlobals->curtime +#endif + ); while ( pe != NULL ) { @@ -795,7 +809,11 @@ void CEventQueue::AddEvent( const char *target, const char *targetInput, variant { // build the new event EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t; +#ifdef TF_DLL newEvent->m_flFireTime = engine->GetServerTime() + fireDelay; // priority key in the priority queue +#else + newEvent->m_flFireTime = gpGlobals->curtime + fireDelay; // priority key in the priority queue +#endif newEvent->m_iTarget = MAKE_STRING( target ); newEvent->m_pEntTarget = NULL; newEvent->m_iTargetInput = MAKE_STRING( targetInput ); @@ -814,7 +832,11 @@ void CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, varian { // build the new event EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t; +#ifdef TF_DLL newEvent->m_flFireTime = engine->GetServerTime() + fireDelay; // primary priority key in the priority queue +#else + newEvent->m_flFireTime = gpGlobals->curtime + fireDelay; // primary priority key in the priority queue +#endif newEvent->m_iTarget = NULL_STRING; newEvent->m_pEntTarget = target; newEvent->m_iTargetInput = MAKE_STRING( targetInput ); @@ -885,7 +907,11 @@ void CEventQueue::ServiceEvents( void ) EventQueuePrioritizedEvent_t *pe = m_Events.m_pNext; +#ifdef TF_DLL while ( pe != NULL && pe->m_flFireTime <= engine->GetServerTime() ) +#else + while ( pe != NULL && pe->m_flFireTime <= gpGlobals->curtime ) +#endif { MDLCACHE_CRITICAL_SECTION(); @@ -1171,7 +1197,11 @@ int CEventQueue::Restore( IRestore &restore ) AddEvent( tmpEvent.m_pEntTarget, STRING(tmpEvent.m_iTargetInput), tmpEvent.m_VariantValue, +#ifdef TF_DLL tmpEvent.m_flFireTime - engine->GetServerTime(), +#else + tmpEvent.m_flFireTime - gpGlobals->curtime, +#endif tmpEvent.m_pActivator, tmpEvent.m_pCaller, tmpEvent.m_iOutputID ); @@ -1181,7 +1211,11 @@ int CEventQueue::Restore( IRestore &restore ) AddEvent( STRING(tmpEvent.m_iTarget), STRING(tmpEvent.m_iTargetInput), tmpEvent.m_VariantValue, +#ifdef TF_DLL tmpEvent.m_flFireTime - engine->GetServerTime(), +#else + tmpEvent.m_flFireTime - gpGlobals->curtime, +#endif tmpEvent.m_pActivator, tmpEvent.m_pCaller, tmpEvent.m_iOutputID ); diff --git a/game/server/client.cpp b/game/server/client.cpp index 39905046..5182653a 100644 --- a/game/server/client.cpp +++ b/game/server/client.cpp @@ -1349,6 +1349,7 @@ void CC_HurtMe_f(const CCommand &args) static ConCommand hurtme("hurtme", CC_HurtMe_f, "Hurts the player.\n\tArguments: ", FCVAR_CHEAT); +#ifdef DBGFLAG_ASSERT static bool IsInGroundList( CBaseEntity *ent, CBaseEntity *ground ) { if ( !ground || !ent ) @@ -1368,8 +1369,8 @@ static bool IsInGroundList( CBaseEntity *ent, CBaseEntity *ground ) } return false; - } +#endif static int DescribeGroundList( CBaseEntity *ent ) { diff --git a/game/server/entity_tools_server.cpp b/game/server/entity_tools_server.cpp index 7daa7bc4..20c99484 100644 --- a/game/server/entity_tools_server.cpp +++ b/game/server/entity_tools_server.cpp @@ -53,7 +53,27 @@ public: virtual void ApplyMultiDamage( void ); virtual void AddMultiDamage( const CTakeDamageInfo &pTakeDamageInfo, CBaseEntity *pEntity ); virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore ); + virtual ITempEntsSystem *GetTempEntsSystem( void ); + virtual CBaseTempEntity *GetTempEntList( void ); + virtual CGlobalEntityList *GetEntityList( void ); + virtual bool IsEntityPtr( void *pTest ); + virtual CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ); + virtual CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL ); + virtual CBaseEntity *FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ); + virtual CBaseEntity *FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName ); + virtual CBaseEntity *FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName ); + virtual CBaseEntity *FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + virtual CBaseEntity *FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + virtual CBaseEntity *FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ); + virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius ); + virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecMins, const Vector &vecMaxs ); + virtual CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + virtual CBaseEntity *FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + virtual CBaseEntity *FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + virtual CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold ); + virtual CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname ); + virtual CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); }; @@ -64,10 +84,11 @@ static CServerTools g_ServerTools; // VSERVERTOOLS_INTERFACE_VERSION_1 is compatible with the latest since we're only adding things to the end, so expose that as well. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools001, VSERVERTOOLS_INTERFACE_VERSION_1, g_ServerTools ); +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools002, VSERVERTOOLS_INTERFACE_VERSION_2, g_ServerTools ); EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION, g_ServerTools ); // When bumping the version to this interface, check that our assumption is still valid and expose the older version in the same way -COMPILE_TIME_ASSERT( VSERVERTOOLS_INTERFACE_VERSION_INT == 2 ); +COMPILE_TIME_ASSERT( VSERVERTOOLS_INTERFACE_VERSION_INT == 3 ); IServerEntity *CServerTools::GetIServerEntity( IClientEntity *pClientEntity ) @@ -347,6 +368,101 @@ ITempEntsSystem *CServerTools::GetTempEntsSystem( void ) return (ITempEntsSystem *)te; } +CBaseTempEntity *CServerTools::GetTempEntList( void ) +{ + return CBaseTempEntity::GetList(); +} + +CGlobalEntityList *CServerTools::GetEntityList( void ) +{ + return &gEntList; +} + +bool CServerTools::IsEntityPtr( void *pTest ) +{ + return gEntList.IsEntityPtr( pTest ); +} + +CBaseEntity *CServerTools::FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ) +{ + return gEntList.FindEntityByClassname( pStartEntity, szName ); +} + +CBaseEntity *CServerTools::FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller, IEntityFindFilter *pFilter ) +{ + return gEntList.FindEntityByName( pStartEntity, szName, pSearchingEntity, pActivator, pCaller, pFilter ); +} + +CBaseEntity *CServerTools::FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ) +{ + return gEntList.FindEntityInSphere( pStartEntity, vecCenter, flRadius ); +} + +CBaseEntity *CServerTools::FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName ) +{ + return gEntList.FindEntityByTarget( pStartEntity, szName ); +} + +CBaseEntity *CServerTools::FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName ) +{ + return gEntList.FindEntityByModel( pStartEntity, szModelName ); +} + +CBaseEntity *CServerTools::FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + return gEntList.FindEntityByNameNearest( szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); +} + +CBaseEntity *CServerTools::FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + return gEntList.FindEntityByNameWithin( pStartEntity, szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); +} + +CBaseEntity *CServerTools::FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ) +{ + return gEntList.FindEntityByClassnameNearest( szName, vecSrc, flRadius ); +} + +CBaseEntity *CServerTools::FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius ) +{ + return gEntList.FindEntityByClassnameWithin( pStartEntity, szName, vecSrc, flRadius ); +} + +CBaseEntity *CServerTools::FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecMins, const Vector &vecMaxs ) +{ + return gEntList.FindEntityByClassnameWithin( pStartEntity, szName, vecMins, vecMaxs ); +} + +CBaseEntity *CServerTools::FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + return gEntList.FindEntityGeneric( pStartEntity, szName, pSearchingEntity, pActivator, pCaller ); +} + +CBaseEntity *CServerTools::FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + return gEntList.FindEntityGenericWithin( pStartEntity, szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); +} + +CBaseEntity *CServerTools::FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + return gEntList.FindEntityGenericNearest( szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); +} + +CBaseEntity *CServerTools::FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold ) +{ + return gEntList.FindEntityNearestFacing( origin, facing, threshold ); +} + +CBaseEntity *CServerTools::FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname ) +{ + return gEntList.FindEntityClassNearestFacing( origin, facing, threshold, classname ); +} + +CBaseEntity *CServerTools::FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + return gEntList.FindEntityProcedural( szName, pSearchingEntity, pActivator, pCaller ); +} + // Interface from engine to tools for manipulating entities class CServerChoreoTools : public IServerChoreoTools diff --git a/game/server/entitylist.cpp b/game/server/entitylist.cpp index 3ad3cada..780070ae 100644 --- a/game/server/entitylist.cpp +++ b/game/server/entitylist.cpp @@ -1105,7 +1105,7 @@ void CGlobalEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ) void CGlobalEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ) { -#ifdef DEBUG +#ifdef DBGFLAG_ASSERT if ( !g_fInCleanupDelete ) { int i; diff --git a/game/server/entitylist.h b/game/server/entitylist.h index 22a6eaf3..b3ee07bd 100644 --- a/game/server/entitylist.h +++ b/game/server/entitylist.h @@ -155,7 +155,6 @@ public: CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold); CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname); - CBaseEntity *FindEntityByNetname( CBaseEntity *pStartEntity, const char *szModelName ); CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); diff --git a/game/server/env_tonemap_controller.cpp b/game/server/env_tonemap_controller.cpp index b4d3e43a..a7549872 100644 --- a/game/server/env_tonemap_controller.cpp +++ b/game/server/env_tonemap_controller.cpp @@ -169,7 +169,7 @@ void CEnvTonemapController::InputSetBloomScaleRange( inputdata_t &inputdata ) return; } m_flCustomBloomScale=bloom_max; - m_flCustomBloomScale=bloom_min; + m_flCustomBloomScaleMinimum=bloom_min; } //----------------------------------------------------------------------------- diff --git a/game/server/func_breakablesurf.cpp b/game/server/func_breakablesurf.cpp index 990e73c9..d7d55457 100644 --- a/game/server/func_breakablesurf.cpp +++ b/game/server/func_breakablesurf.cpp @@ -109,8 +109,6 @@ void CWindowPane::PaneTouch( CBaseEntity *pOther ) //------------------------------------------------------------------------------ void CWindowPane::Die( void ) { - Vector flForce = -1 * GetAbsVelocity(); - CPASFilter filter( GetAbsOrigin() ); te->ShatterSurface( filter, 0.0, &GetAbsOrigin(), &GetAbsAngles(), diff --git a/game/server/func_dust.cpp b/game/server/func_dust.cpp index a6f10cb5..5ab36a05 100644 --- a/game/server/func_dust.cpp +++ b/game/server/func_dust.cpp @@ -162,7 +162,7 @@ void CFunc_Dust::Spawn() //Since keyvalues can arrive in any order, and UTIL_StringToColor32 stomps alpha, //install the alpha value here. - color32 clr = { m_Color.m_Value.r, m_Color.m_Value.g, m_Color.m_Value.b, m_iAlpha }; + color32 clr = { m_Color.m_Value.r, m_Color.m_Value.g, m_Color.m_Value.b, (byte)m_iAlpha }; m_Color.Set( clr ); BaseClass::Spawn(); diff --git a/game/server/gameinterface.cpp b/game/server/gameinterface.cpp index b4d09bae..36c0385a 100644 --- a/game/server/gameinterface.cpp +++ b/game/server/gameinterface.cpp @@ -1888,9 +1888,13 @@ void CServerGameDLL::SetServerHibernation( bool bHibernating ) const char *CServerGameDLL::GetServerBrowserMapOverride() { #ifdef TF_DLL - if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager && g_pPopulationManager->GetPopulationFilenameShort() != '\0' ) + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) { - return g_pPopulationManager->GetPopulationFilenameShort(); + const char *pszFilenameShort = g_pPopulationManager ? g_pPopulationManager->GetPopulationFilenameShort() : NULL; + if ( pszFilenameShort && pszFilenameShort[0] ) + { + return pszFilenameShort; + } } #endif return NULL; @@ -1923,6 +1927,15 @@ const char *CServerGameDLL::GetServerBrowserGameData() return rchResult; } +//----------------------------------------------------------------------------- +void CServerGameDLL::Status( void (*print) (const char *fmt, ...) ) +{ + if ( g_pGameRules ) + { + g_pGameRules->Status( print ); + } +} + //----------------------------------------------------------------------------- // Purpose: Called during a transition, to build a map adjacency list //----------------------------------------------------------------------------- @@ -2964,17 +2977,20 @@ void CServerGameClients::ClientSetupVisibility( edict_t *pViewEntity, edict_t *p // Flush the remaining areaportal states. engine->SetAreaPortalStates( portalNums, isOpen, iOutPortal ); - // Update the area bits that get sent to the client. - pPlayer->m_Local.UpdateAreaBits( pPlayer, portalBits ); + if ( pPlayer ) + { + // Update the area bits that get sent to the client. + pPlayer->m_Local.UpdateAreaBits( pPlayer, portalBits ); #ifdef PORTAL - // *After* the player's view has updated its area bits, add on any other areas seen by portals - CPortal_Player* pPortalPlayer = dynamic_cast( pPlayer ); - if ( pPortalPlayer ) - { - pPortalPlayer->UpdatePortalViewAreaBits( pvs, pvssize ); - } + // *After* the player's view has updated its area bits, add on any other areas seen by portals + CPortal_Player* pPortalPlayer = dynamic_cast( pPlayer ); + if ( pPortalPlayer ) + { + pPortalPlayer->UpdatePortalViewAreaBits( pvs, pvssize ); + } #endif //PORTAL + } } @@ -3325,7 +3341,7 @@ void MessageWriteEHandle( CBaseEntity *pEntity ) { EHANDLE hEnt = pEntity; - int iSerialNum = hEnt.GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1; + int iSerialNum = hEnt.GetSerialNumber() & ( (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1 ); iEncodedEHandle = hEnt.GetEntryIndex() | (iSerialNum << MAX_EDICT_BITS); } else diff --git a/game/server/gameinterface.h b/game/server/gameinterface.h index a824852d..a59380be 100644 --- a/game/server/gameinterface.h +++ b/game/server/gameinterface.h @@ -28,35 +28,35 @@ extern INetworkStringTable *g_pStringTableServerPopFiles; class CServerGameClients : public IServerGameClients { public: - virtual bool ClientConnect( edict_t *pEntity, char const* pszName, char const* pszAddress, char *reject, int maxrejectlen ); - virtual void ClientActive( edict_t *pEntity, bool bLoadGame ); - virtual void ClientDisconnect( edict_t *pEntity ); - virtual void ClientPutInServer( edict_t *pEntity, const char *playername ); - virtual void ClientCommand( edict_t *pEntity, const CCommand &args ); - virtual void ClientSettingsChanged( edict_t *pEntity ); - virtual void ClientSetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char *pvs, int pvssize ); + virtual bool ClientConnect( edict_t *pEntity, char const* pszName, char const* pszAddress, char *reject, int maxrejectlen ) OVERRIDE; + virtual void ClientActive( edict_t *pEntity, bool bLoadGame ) OVERRIDE; + virtual void ClientDisconnect( edict_t *pEntity ) OVERRIDE; + virtual void ClientPutInServer( edict_t *pEntity, const char *playername ) OVERRIDE; + virtual void ClientCommand( edict_t *pEntity, const CCommand &args ) OVERRIDE; + virtual void ClientSettingsChanged( edict_t *pEntity ) OVERRIDE; + virtual void ClientSetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char *pvs, int pvssize ) OVERRIDE; virtual float ProcessUsercmds( edict_t *player, bf_read *buf, int numcmds, int totalcmds, - int dropped_packets, bool ignore, bool paused ); + int dropped_packets, bool ignore, bool paused ) OVERRIDE; // Player is running a command - virtual void PostClientMessagesSent_DEPRECIATED( void ); - virtual void SetCommandClient( int index ); - virtual CPlayerState *GetPlayerState( edict_t *player ); - virtual void ClientEarPosition( edict_t *pEntity, Vector *pEarOrigin ); + virtual void PostClientMessagesSent_DEPRECIATED( void ) OVERRIDE; + virtual void SetCommandClient( int index ) OVERRIDE; + virtual CPlayerState *GetPlayerState( edict_t *player ) OVERRIDE; + virtual void ClientEarPosition( edict_t *pEntity, Vector *pEarOrigin ) OVERRIDE; - virtual void GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const; + virtual void GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const OVERRIDE; // returns number of delay ticks if player is in Replay mode (0 = no delay) - virtual int GetReplayDelay( edict_t *player, int& entity ); + virtual int GetReplayDelay( edict_t *player, int& entity ) OVERRIDE; // Anything this game .dll wants to add to the bug reporter text (e.g., the entity/model under the picker crosshair) // can be added here - virtual void GetBugReportInfo( char *buf, int buflen ); - virtual void NetworkIDValidated( const char *pszUserName, const char *pszNetworkID ); + virtual void GetBugReportInfo( char *buf, int buflen ) OVERRIDE; + virtual void NetworkIDValidated( const char *pszUserName, const char *pszNetworkID ) OVERRIDE; // The client has submitted a keyvalues command - virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues ); + virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues ) OVERRIDE; // Notify that the player is spawned - virtual void ClientSpawned( edict_t *pPlayer ); + virtual void ClientSpawned( edict_t *pPlayer ) OVERRIDE; }; @@ -64,73 +64,73 @@ class CServerGameDLL : public IServerGameDLL { public: virtual bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, - CreateInterfaceFn fileSystemFactory, CGlobalVars *pGlobals); - virtual void DLLShutdown( void ); + CreateInterfaceFn fileSystemFactory, CGlobalVars *pGlobals) OVERRIDE; + virtual void DLLShutdown( void ) OVERRIDE; // Get the simulation interval (must be compiled with identical values into both client and game .dll for MOD!!!) - virtual bool ReplayInit( CreateInterfaceFn fnReplayFactory ); - virtual float GetTickInterval( void ) const; - virtual bool GameInit( void ); - virtual void GameShutdown( void ); - virtual bool LevelInit( const char *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background ); - virtual void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ); - virtual void LevelShutdown( void ); - virtual void GameFrame( bool simulating ); // could be called multiple times before sending data to clients - virtual void PreClientUpdate( bool simulating ); // called after all GameFrame() calls, before sending data to clients + virtual bool ReplayInit( CreateInterfaceFn fnReplayFactory ) OVERRIDE; + virtual float GetTickInterval( void ) const OVERRIDE; + virtual bool GameInit( void ) OVERRIDE; + virtual void GameShutdown( void ) OVERRIDE; + virtual bool LevelInit( const char *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background ) OVERRIDE; + virtual void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) OVERRIDE; + virtual void LevelShutdown( void ) OVERRIDE; + virtual void GameFrame( bool simulating ) OVERRIDE; // could be called multiple times before sending data to clients + virtual void PreClientUpdate( bool simulating ) OVERRIDE; // called after all GameFrame() calls, before sending data to clients - virtual ServerClass* GetAllServerClasses( void ); - virtual const char *GetGameDescription( void ); - virtual void CreateNetworkStringTables( void ); + virtual ServerClass* GetAllServerClasses( void ) OVERRIDE; + virtual const char *GetGameDescription( void ) OVERRIDE; + virtual void CreateNetworkStringTables( void ) OVERRIDE; // Save/restore system hooks - virtual CSaveRestoreData *SaveInit( int size ); - virtual void SaveWriteFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ); - virtual void SaveReadFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ); - virtual void SaveGlobalState( CSaveRestoreData * ); - virtual void RestoreGlobalState( CSaveRestoreData * ); - virtual int CreateEntityTransitionList( CSaveRestoreData *, int ); - virtual void BuildAdjacentMapList( void ); + virtual CSaveRestoreData *SaveInit( int size ) OVERRIDE; + virtual void SaveWriteFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ) OVERRIDE; + virtual void SaveReadFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ) OVERRIDE; + virtual void SaveGlobalState( CSaveRestoreData * ) OVERRIDE; + virtual void RestoreGlobalState( CSaveRestoreData * ) OVERRIDE; + virtual int CreateEntityTransitionList( CSaveRestoreData *, int ) OVERRIDE; + virtual void BuildAdjacentMapList( void ) OVERRIDE; - virtual void PreSave( CSaveRestoreData * ); - virtual void Save( CSaveRestoreData * ); - virtual void GetSaveComment( char *comment, int maxlength, float flMinutes, float flSeconds, bool bNoTime = false ); + virtual void PreSave( CSaveRestoreData * ) OVERRIDE; + virtual void Save( CSaveRestoreData * ) OVERRIDE; + virtual void GetSaveComment( char *comment, int maxlength, float flMinutes, float flSeconds, bool bNoTime = false ) OVERRIDE; #ifdef _XBOX - virtual void GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ); + virtual void GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ) OVERRIDE; #endif - virtual void WriteSaveHeaders( CSaveRestoreData * ); + virtual void WriteSaveHeaders( CSaveRestoreData * ) OVERRIDE; - virtual void ReadRestoreHeaders( CSaveRestoreData * ); - virtual void Restore( CSaveRestoreData *, bool ); - virtual bool IsRestoring(); + virtual void ReadRestoreHeaders( CSaveRestoreData * ) OVERRIDE; + virtual void Restore( CSaveRestoreData *, bool ) OVERRIDE; + virtual bool IsRestoring() OVERRIDE; // Retrieve info needed for parsing the specified user message - virtual bool GetUserMessageInfo( int msg_type, char *name, int maxnamelength, int& size ); + virtual bool GetUserMessageInfo( int msg_type, char *name, int maxnamelength, int& size ) OVERRIDE; - virtual CStandardSendProxies* GetStandardSendProxies(); + virtual CStandardSendProxies* GetStandardSendProxies() OVERRIDE; - virtual void PostInit(); - virtual void Think( bool finalTick ); + virtual void PostInit() OVERRIDE; + virtual void Think( bool finalTick ) OVERRIDE; - virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ); + virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) OVERRIDE; - virtual void PreSaveGameLoaded( char const *pSaveName, bool bInGame ); + virtual void PreSaveGameLoaded( char const *pSaveName, bool bInGame ) OVERRIDE; // Returns true if the game DLL wants the server not to be made public. // Used by commentary system to hide multiplayer commentary servers from the master. - virtual bool ShouldHideServer( void ); + virtual bool ShouldHideServer( void ) OVERRIDE; - virtual void InvalidateMdlCache(); + virtual void InvalidateMdlCache() OVERRIDE; - virtual void SetServerHibernation( bool bHibernating ); + virtual void SetServerHibernation( bool bHibernating ) OVERRIDE; float m_fAutoSaveDangerousTime; float m_fAutoSaveDangerousMinHealthToCommit; bool m_bIsHibernating; // Called after the steam API has been activated post-level startup - virtual void GameServerSteamAPIActivated( void ); + virtual void GameServerSteamAPIActivated( void ) OVERRIDE; // Called after the steam API has been shutdown post-level startup - virtual void GameServerSteamAPIShutdown( void ); + virtual void GameServerSteamAPIShutdown( void ) OVERRIDE; // interface to the new GC based lobby system virtual IServerGCLobby *GetServerGCLobby() OVERRIDE; @@ -138,6 +138,9 @@ public: virtual const char *GetServerBrowserMapOverride() OVERRIDE; virtual const char *GetServerBrowserGameData() OVERRIDE; + // Called to add output to the status command + virtual void Status( void (*print) (const char *fmt, ...) ); + private: // This can just be a wrapper on MapEntity_ParseAllEntities, but CS does some tricks in here diff --git a/game/server/genericactor.cpp b/game/server/genericactor.cpp index 0bc36521..bad6454d 100644 --- a/game/server/genericactor.cpp +++ b/game/server/genericactor.cpp @@ -372,7 +372,7 @@ void CFlextalkActor::ProcessSceneEvents( void ) { m_flexnum = LookupFlex( szTemp ); - if (m_flexnum != -1 && m_flextarget[m_flexnum] != 1) + if (m_flexnum != LocalFlexController_t(-1) && m_flextarget[m_flexnum] != 1) { m_flextarget[m_flexnum] = 1.0; // SetFlexTarget( m_flexnum ); diff --git a/game/server/globalstate.cpp b/game/server/globalstate.cpp index 43390d90..98f504b6 100644 --- a/game/server/globalstate.cpp +++ b/game/server/globalstate.cpp @@ -131,6 +131,7 @@ public: entity.name = m_nameList.AddString( pGlobalname ); entity.levelName = m_nameList.AddString( pMapName ); entity.state = state; + entity.counter = 0; int index = GetIndex( m_nameList.String( entity.name ) ); if ( index >= 0 ) diff --git a/game/server/hl2/npc_citizen17.cpp b/game/server/hl2/npc_citizen17.cpp index 42e45034..e50ce0b4 100644 --- a/game/server/hl2/npc_citizen17.cpp +++ b/game/server/hl2/npc_citizen17.cpp @@ -143,23 +143,23 @@ struct citizen_expression_list_t // Scared citizen_expression_list_t ScaredExpressions[STATES_WITH_EXPRESSIONS] = { - { "scenes/Expressions/citizen_scared_idle_01.vcd" }, - { "scenes/Expressions/citizen_scared_alert_01.vcd" }, - { "scenes/Expressions/citizen_scared_combat_01.vcd" }, + { { "scenes/Expressions/citizen_scared_idle_01.vcd" } }, + { { "scenes/Expressions/citizen_scared_alert_01.vcd" } }, + { { "scenes/Expressions/citizen_scared_combat_01.vcd" } }, }; // Normal citizen_expression_list_t NormalExpressions[STATES_WITH_EXPRESSIONS] = { - { "scenes/Expressions/citizen_normal_idle_01.vcd" }, - { "scenes/Expressions/citizen_normal_alert_01.vcd" }, - { "scenes/Expressions/citizen_normal_combat_01.vcd" }, + { { "scenes/Expressions/citizen_normal_idle_01.vcd" } }, + { { "scenes/Expressions/citizen_normal_alert_01.vcd" } }, + { { "scenes/Expressions/citizen_normal_combat_01.vcd" } }, }; // Angry citizen_expression_list_t AngryExpressions[STATES_WITH_EXPRESSIONS] = { - { "scenes/Expressions/citizen_angry_idle_01.vcd" }, - { "scenes/Expressions/citizen_angry_alert_01.vcd" }, - { "scenes/Expressions/citizen_angry_combat_01.vcd" }, + { { "scenes/Expressions/citizen_angry_idle_01.vcd" } }, + { { "scenes/Expressions/citizen_angry_alert_01.vcd" } }, + { { "scenes/Expressions/citizen_angry_combat_01.vcd" } }, }; //----------------------------------------------------------------------------- @@ -4197,8 +4197,6 @@ void CNPC_Citizen::AddInsignia() void CNPC_Citizen::RemoveInsignia() { - // This is crap right now. - CBaseEntity *FirstEnt(); CBaseEntity *pEntity = gEntList.FirstEnt(); while( pEntity ) diff --git a/game/server/hl2/npc_metropolice.cpp b/game/server/hl2/npc_metropolice.cpp index f87b473b..6a43b131 100644 --- a/game/server/hl2/npc_metropolice.cpp +++ b/game/server/hl2/npc_metropolice.cpp @@ -1675,7 +1675,7 @@ float CNPC_MetroPolice::AimBurstAtReactionTime( float flReactionTime, float flDi #define AIM_AT_SHOT_SPEED_COUNT 6 #define AIM_AT_SHOT_DIST_COUNT 6 -static int s_pShotCountFraction[AIM_AT_TIME_DIST_COUNT][AIM_AT_TIME_SPEED_COUNT] = +static float s_pShotCountFraction[AIM_AT_TIME_DIST_COUNT][AIM_AT_TIME_SPEED_COUNT] = { { 3.0f, 3.0f, 2.5f, 1.5f, 1.0f, 0.0f }, { 3.0f, 3.0f, 2.5f, 1.25f, 0.5f, 0.0f }, diff --git a/game/server/hl2/npc_scanner.cpp b/game/server/hl2/npc_scanner.cpp index eb1c6c46..b9b2cd9c 100644 --- a/game/server/hl2/npc_scanner.cpp +++ b/game/server/hl2/npc_scanner.cpp @@ -1988,7 +1988,7 @@ void CNPC_CScanner::BlindFlashTarget( CBaseEntity *pTarget ) if ( tr.startsolid == false && tr.fraction == 1.0) { - color32 white = { 255, 255, 255, SCANNER_FLASH_MAX_VALUE * dotPr }; + color32 white = { 255, 255, 255, (byte)(SCANNER_FLASH_MAX_VALUE * dotPr) }; if ( ( g_pMaterialSystemHardwareConfig != NULL ) && ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) ) { diff --git a/game/server/hl2/npc_strider.cpp b/game/server/hl2/npc_strider.cpp index 015fe0e6..4741632e 100644 --- a/game/server/hl2/npc_strider.cpp +++ b/game/server/hl2/npc_strider.cpp @@ -1130,7 +1130,7 @@ void CNPC_Strider::GatherConditions() !WeaponLOSCondition( GetAdjustedOrigin(), GetEnemy()->BodyTarget( GetAdjustedOrigin() ), false ) ) ) { #if 0 - if ( !HasCondition( COND_STRIDER_SHOULD_CROUCH ) && !HasCondition( COND_STRIDER_SHOULD_CROUCH ) ) + if ( !HasCondition( COND_STRIDER_SHOULD_CROUCH ) ) SetIdealHeight( MIN( GetMaxHeight(), GetHeight() + 75.0 * 0.1 ) ); // default to rising up #endif GatherHeightConditions( GetAdjustedOrigin(), GetEnemy() ); @@ -1161,7 +1161,7 @@ void CNPC_Strider::GatherConditions() //--------------------------------------------------------- void CNPC_Strider::GatherHeightConditions( const Vector &vTestPos, CBaseEntity *pEntity ) { - if ( HasCondition( COND_STRIDER_SHOULD_CROUCH ) && HasCondition( COND_STRIDER_SHOULD_CROUCH ) ) + if ( HasCondition( COND_STRIDER_SHOULD_CROUCH ) ) return; float maxZ = (GetAbsOrigin().z - (GetMaxHeightModel() - GetMaxHeight())); diff --git a/game/server/ilagcompensationmanager.h b/game/server/ilagcompensationmanager.h index 3c637113..36adf4be 100644 --- a/game/server/ilagcompensationmanager.h +++ b/game/server/ilagcompensationmanager.h @@ -23,6 +23,7 @@ public: // Called during player movement to set up/restore after lag compensation virtual void StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ) = 0; virtual void FinishLagCompensation( CBasePlayer *player ) = 0; + virtual bool IsCurrentlyDoingLagCompensation() const = 0; }; extern ILagCompensationManager *lagcompensation; diff --git a/game/server/modelentities.cpp b/game/server/modelentities.cpp index 9f31a656..91c8412c 100644 --- a/game/server/modelentities.cpp +++ b/game/server/modelentities.cpp @@ -191,7 +191,7 @@ void CFuncBrush::TurnOn( void ) } -bool CFuncBrush::IsOn( void ) +bool CFuncBrush::IsOn( void ) const { return !IsEffectActive( EF_NODRAW ); } diff --git a/game/server/modelentities.h b/game/server/modelentities.h index 8d134980..bee96f8b 100644 --- a/game/server/modelentities.h +++ b/game/server/modelentities.h @@ -18,7 +18,7 @@ //----------------------------------------------------------------------------- // Purpose: basic solid geometry // enabled state: brush is visible -// disabled staute: brush not visible +// disabled state: brush not visible //----------------------------------------------------------------------------- class CFuncBrush : public CBaseEntity { @@ -32,8 +32,8 @@ public: virtual int DrawDebugTextOverlays( void ); - void TurnOff( void ); - void TurnOn( void ); + virtual void TurnOff( void ); + virtual void TurnOn( void ); // Input handlers void InputTurnOff( inputdata_t &inputdata ); @@ -56,7 +56,7 @@ public: DECLARE_DATADESC(); - virtual bool IsOn( void ); + virtual bool IsOn( void ) const; }; diff --git a/game/server/nav.h b/game/server/nav.h index a6476dad..7bdcedcf 100644 --- a/game/server/nav.h +++ b/game/server/nav.h @@ -334,11 +334,11 @@ inline void DirectionToVector2D( NavDirType dir, Vector2D *v ) { switch( dir ) { + default: Assert(0); case NORTH: v->x = 0.0f; v->y = -1.0f; break; case SOUTH: v->x = 0.0f; v->y = 1.0f; break; case EAST: v->x = 1.0f; v->y = 0.0f; break; case WEST: v->x = -1.0f; v->y = 0.0f; break; - default: break; } } @@ -348,11 +348,11 @@ inline void CornerToVector2D( NavCornerType dir, Vector2D *v ) { switch( dir ) { + default: Assert(0); case NORTH_WEST: v->x = -1.0f; v->y = -1.0f; break; case NORTH_EAST: v->x = 1.0f; v->y = -1.0f; break; case SOUTH_EAST: v->x = 1.0f; v->y = 1.0f; break; case SOUTH_WEST: v->x = -1.0f; v->y = 1.0f; break; - default: break; } v->NormalizeInPlace(); @@ -365,6 +365,8 @@ inline void GetCornerTypesInDirection( NavDirType dir, NavCornerType *first, Nav { switch ( dir ) { + default: + Assert(0); case NORTH: *first = NORTH_WEST; *second = NORTH_EAST; @@ -381,8 +383,6 @@ inline void GetCornerTypesInDirection( NavDirType dir, NavCornerType *first, Nav *first = NORTH_WEST; *second = SOUTH_WEST; break; - default: - break; } } diff --git a/game/server/nav_area.cpp b/game/server/nav_area.cpp index b25c4fa3..94a12702 100644 --- a/game/server/nav_area.cpp +++ b/game/server/nav_area.cpp @@ -192,6 +192,8 @@ CNavArea::CNavArea( void ) m_avoidanceObstacleHeight = 0.0f; m_totalCost = 0.0f; + m_costSoFar = 0.0f; + m_pathLengthSoFar = 0.0f; ResetNodes(); @@ -244,6 +246,8 @@ CNavArea::CNavArea( void ) m_isInheritedFrom = false; m_funcNavCostVector.RemoveAll(); + + m_nVisTestCounter = (uint32)-1; } //-------------------------------------------------------------------------------------------------------------- @@ -3381,16 +3385,10 @@ void CNavArea::AddToOpenList( void ) } // insert self in ascending cost order - // Since costs are positive, IEEE754 let's us compare as integers (see http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm) CNavArea *area, *last = NULL; - int thisCostBits = *reinterpret_cast(&m_totalCost); - - Assert ( m_totalCost >= 0.0f ); for( area = m_openList; area; area = area->m_nextOpen ) { - Assert ( area->GetTotalCost() >= 0.0f ); - int thoseCostBits = *reinterpret_cast(&area->m_totalCost); - if ( thisCostBits < thoseCostBits ) + if ( GetTotalCost() < area->GetTotalCost() ) { break; } @@ -5630,7 +5628,7 @@ void CNavArea::ComputeVisibilityToMesh( void ) /** * The center and all four corners must ALL be visible */ -bool CNavArea::IsEntirelyVisible( const Vector &eye, CBaseEntity *ignore ) const +bool CNavArea::IsEntirelyVisible( const Vector &eye, const CBaseEntity *ignore ) const { Vector corner; trace_t result; @@ -5663,7 +5661,7 @@ bool CNavArea::IsEntirelyVisible( const Vector &eye, CBaseEntity *ignore ) const /** * The center or any of the four corners may be visible */ -bool CNavArea::IsPartiallyVisible( const Vector &eye, CBaseEntity *ignore ) const +bool CNavArea::IsPartiallyVisible( const Vector &eye, const CBaseEntity *ignore ) const { Vector corner; trace_t result; diff --git a/game/server/nav_area.h b/game/server/nav_area.h index 6eba5966..aaec738b 100644 --- a/game/server/nav_area.h +++ b/game/server/nav_area.h @@ -18,6 +18,15 @@ // BOTPORT: Clean up relationship between team index and danger storage in nav areas enum { MAX_NAV_TEAMS = 2 }; +#ifdef STAGING_ONLY +inline void DebuggerBreakOnNaN_StagingOnly( float val ) +{ + if ( IS_NAN( val ) ) + DebuggerBreak(); +} +#else +#define DebuggerBreakOnNaN_StagingOnly( _val ) +#endif class CFuncElevator; class CFuncNavPrerequisite; @@ -445,14 +454,14 @@ public: static void ClearSearchLists( void ); // clears the open and closed lists for a new search - void SetTotalCost( float value ) { Assert( value >= 0.0 && !IS_NAN(value) ); m_totalCost = value; } - float GetTotalCost( void ) const { return m_totalCost; } + void SetTotalCost( float value ) { DebuggerBreakOnNaN_StagingOnly( value ); Assert( value >= 0.0 && !IS_NAN(value) ); m_totalCost = value; } + float GetTotalCost( void ) const { DebuggerBreakOnNaN_StagingOnly( m_totalCost ); return m_totalCost; } - void SetCostSoFar( float value ) { Assert( value >= 0.0 && !IS_NAN(value) ); m_costSoFar = value; } - float GetCostSoFar( void ) const { return m_costSoFar; } + void SetCostSoFar( float value ) { DebuggerBreakOnNaN_StagingOnly( value ); Assert( value >= 0.0 && !IS_NAN(value) ); m_costSoFar = value; } + float GetCostSoFar( void ) const { DebuggerBreakOnNaN_StagingOnly( m_costSoFar ); return m_costSoFar; } - void SetPathLengthSoFar( float value ) { Assert( value >= 0.0 && !IS_NAN(value) ); m_pathLengthSoFar = value; } - float GetPathLengthSoFar( void ) const { return m_pathLengthSoFar; } + void SetPathLengthSoFar( float value ) { DebuggerBreakOnNaN_StagingOnly( value ); Assert( value >= 0.0 && !IS_NAN(value) ); m_pathLengthSoFar = value; } + float GetPathLengthSoFar( void ) const { DebuggerBreakOnNaN_StagingOnly( m_pathLengthSoFar ); return m_pathLengthSoFar; } //- editing ----------------------------------------------------------------------------------------- virtual void Draw( void ) const; // draw area for debugging & editing @@ -515,8 +524,8 @@ public: } }; - virtual bool IsEntirelyVisible( const Vector &eye, CBaseEntity *ignore = NULL ) const; // return true if entire area is visible from given eyepoint (CPU intensive) - virtual bool IsPartiallyVisible( const Vector &eye, CBaseEntity *ignore = NULL ) const; // return true if any portion of the area is visible from given eyepoint (CPU intensive) + virtual bool IsEntirelyVisible( const Vector &eye, const CBaseEntity *ignore = NULL ) const; // return true if entire area is visible from given eyepoint (CPU intensive) + virtual bool IsPartiallyVisible( const Vector &eye, const CBaseEntity *ignore = NULL ) const; // return true if any portion of the area is visible from given eyepoint (CPU intensive) virtual bool IsPotentiallyVisible( const CNavArea *area ) const; // return true if given area is potentially visible from somewhere in this area (very fast) virtual bool IsPotentiallyVisibleToTeam( int team ) const; // return true if any portion of this area is visible to anyone on the given team (very fast) diff --git a/game/server/nav_generate.cpp b/game/server/nav_generate.cpp index fe577273..44122df0 100644 --- a/game/server/nav_generate.cpp +++ b/game/server/nav_generate.cpp @@ -1809,6 +1809,8 @@ void CNavMesh::StitchAreaIntoMesh( CNavArea *area, NavDirType dir, Functor &func Vector corner1, corner2; switch ( dir ) { + default: + Assert(0); case NORTH: corner1 = area->GetCorner( NORTH_WEST ); corner2 = area->GetCorner( NORTH_EAST ); diff --git a/game/server/nav_mesh.cpp b/game/server/nav_mesh.cpp index 5cb58318..bc0e7321 100644 --- a/game/server/nav_mesh.cpp +++ b/game/server/nav_mesh.cpp @@ -49,7 +49,9 @@ ConVar nav_max_vis_delta_list_length( "nav_max_vis_delta_list_length", "64", FCV extern ConVar nav_show_potentially_visible; +#ifdef STAGING_ONLY int g_DebugPathfindCounter = 0; +#endif bool FindGroundForNode( Vector *pos, Vector *normal ); diff --git a/game/server/nav_mesh.h b/game/server/nav_mesh.h index 21dc200b..1a6c74a1 100644 --- a/game/server/nav_mesh.h +++ b/game/server/nav_mesh.h @@ -1259,8 +1259,10 @@ extern CNavMesh *TheNavMesh; // factory for creating the Navigation Mesh extern CNavMesh *NavMeshFactory( void ); +#ifdef STAGING_ONLY // for debugging the A* algorithm, if nonzero, show debug display and decrement for each pathfind extern int g_DebugPathfindCounter; +#endif //-------------------------------------------------------------------------------------------------------------- diff --git a/game/server/nav_pathfind.h b/game/server/nav_pathfind.h index 47f6c80e..4a4c8798 100644 --- a/game/server/nav_pathfind.h +++ b/game/server/nav_pathfind.h @@ -16,7 +16,9 @@ #include "mathlib/ssemath.h" #include "nav_area.h" +#ifdef STAGING_ONLY extern int g_DebugPathfindCounter; +#endif //------------------------------------------------------------------------------------------------------------------- @@ -108,7 +110,9 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go *closestArea = startArea; } +#ifdef STAGING_ONLY bool isDebug = ( g_DebugPathfindCounter-- > 0 ); +#endif if (startArea == NULL) return false; @@ -154,10 +158,12 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go // get next area to check CNavArea *area = CNavArea::PopOpenList(); +#ifdef STAGING_ONLY if ( isDebug ) { area->DrawFilled( 0, 255, 0, 128, 30.0f ); } +#endif // don't consider blocked areas if ( area->IsBlocked( teamID, ignoreNavBlockers ) ) @@ -339,7 +345,13 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go continue; float newCostSoFar = costFunc( newArea, area, ladder, elevator, length ); - + + // NaNs really mess this function up causing tough to track down hangs. If + // we get inf back, clamp it down to a really high number. + DebuggerBreakOnNaN_StagingOnly( newCostSoFar ); + if ( IS_NAN( newCostSoFar ) ) + newCostSoFar = 1e30f; + // check if cost functor says this area is a dead-end if ( newCostSoFar < 0.0f ) continue; @@ -352,7 +364,7 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go // Make sure that any jump to a new area incurs some pathfinsing // cost, to avoid us spinning our wheels over insignificant cost // benefit, floating point precision bug, or busted cost functor. - float minNewCostSoFar = area->GetCostSoFar() * 1.00001 + 0.00001; + float minNewCostSoFar = area->GetCostSoFar() * 1.00001f + 0.00001f; newCostSoFar = Max( newCostSoFar, minNewCostSoFar ); // stop if path length limit reached diff --git a/game/server/networkstringtable_gamedll.h b/game/server/networkstringtable_gamedll.h index d135e815..e94ab5b0 100644 --- a/game/server/networkstringtable_gamedll.h +++ b/game/server/networkstringtable_gamedll.h @@ -24,7 +24,7 @@ class CStringTableSaveRestoreOps; #define MAX_MATERIAL_STRINGS ( 1 << MAX_MATERIAL_STRING_BITS ) #define OVERLAY_MATERIAL_INVALID_STRING ( MAX_MATERIAL_STRINGS - 1 ) -#define MAX_CHOREO_SCENES_STRING_BITS 12 +#define MAX_CHOREO_SCENES_STRING_BITS 13 #define MAX_CHOREO_SCENES_STRINGS ( 1 << MAX_CHOREO_SCENES_STRING_BITS ) #define CHOREO_SCENES_INVALID_STRING ( MAX_CHOREO_SCENES_STRINGS - 1 ) diff --git a/game/server/physics_main.cpp b/game/server/physics_main.cpp index 41d5625b..d27fe437 100644 --- a/game/server/physics_main.cpp +++ b/game/server/physics_main.cpp @@ -742,7 +742,9 @@ void CPhysicsPushedEntities::GenerateBlockingEntityListAddBox( const Vector &vec } } - +#ifdef TF_DLL +#include "tf_logic_robot_destruction.h" +#endif //----------------------------------------------------------------------------- // Purpose: Gets a list of all entities hierarchically attached to the root //----------------------------------------------------------------------------- @@ -1841,7 +1843,9 @@ void CBaseEntity::PhysicsStepRunTimestep( float timestep ) { bool wasonground; bool inwater; +#if 0 bool hitsound = false; +#endif float speed, newspeed, control; float friction; @@ -1862,10 +1866,12 @@ void CBaseEntity::PhysicsStepRunTimestep( float timestep ) { if ( !( ( GetFlags() & FL_SWIM ) && ( GetWaterLevel() > 0 ) ) ) { +#if 0 if ( GetAbsVelocity()[2] < ( GetCurrentGravity() * -0.1 ) ) { hitsound = true; } +#endif if ( !inwater ) { diff --git a/game/server/player.cpp b/game/server/player.cpp index cdfca3a4..19d583fd 100644 --- a/game/server/player.cpp +++ b/game/server/player.cpp @@ -635,6 +635,8 @@ CBasePlayer::CBasePlayer( ) m_flLastUserCommandTime = 0.f; m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; + + m_flLastObjectiveTime = -1.f; } CBasePlayer::~CBasePlayer( ) @@ -2473,6 +2475,7 @@ void CBasePlayer::ValidateCurrentObserverTarget( void ) } else { +#if !defined( TF_DLL ) // couldn't find new target, switch to temporary mode if ( mp_forcecamera.GetInt() == OBS_ALLOW_ALL ) { @@ -2480,10 +2483,11 @@ void CBasePlayer::ValidateCurrentObserverTarget( void ) ForceObserverMode( OBS_MODE_ROAMING ); } else +#endif { // fix player view right where it is ForceObserverMode( OBS_MODE_FIXED ); - m_hObserverTarget.Set( NULL ); // no traget to follow + m_hObserverTarget.Set( NULL ); // no target to follow } } } @@ -7379,7 +7383,7 @@ void CBasePlayer::EquipWearable( CEconWearable *pItem ) pItem->Equip( this ); } -#ifdef DEBUG +#ifdef DBGFLAG_ASSERT // Double check list integrity. for ( int i = m_hMyWearables.Count()-1; i >= 0; --i ) { @@ -7409,9 +7413,16 @@ void CBasePlayer::RemoveWearable( CEconWearable *pItem ) m_hMyWearables.Remove( i ); break; } + + // Integrety is failing, remove NULLs + if ( !pWearable ) + { + m_hMyWearables.Remove( i ); + break; + } } -#ifdef DEBUG +#ifdef DBGFLAG_ASSERT // Double check list integrity. for ( int i = m_hMyWearables.Count()-1; i >= 0; --i ) { @@ -8846,6 +8857,8 @@ void CBasePlayer::SetPlayerName( const char *name ) Assert( strlen(name) > 0 ); Q_strncpy( m_szNetname, name, sizeof(m_szNetname) ); + // Be extra thorough + Q_RemoveAllEvilCharacters( m_szNetname ); } } @@ -8940,8 +8953,27 @@ void CBasePlayer::HandleAnimEvent( animevent_t *pEvent ) BaseClass::HandleAnimEvent( pEvent ); } + //----------------------------------------------------------------------------- -// CPlayerInfo functions (simple passthroughts to get around the CBasePlayer multiple inheritence limitation) +// Purpose: +//----------------------------------------------------------------------------- +bool CBasePlayer::ShouldAnnounceAchievement( void ) +{ + m_flAchievementTimes.AddToTail( gpGlobals->curtime ); + if ( m_flAchievementTimes.Count() > 3 ) + { + m_flAchievementTimes.Remove( 0 ); + if ( m_flAchievementTimes.Tail() - m_flAchievementTimes.Head() <= 60.0 ) + { + return false; + } + } + + return true; +} + +//----------------------------------------------------------------------------- +// CPlayerInfo functions (simple pass-through to get around the CBasePlayer multiple inheritance limitation) //----------------------------------------------------------------------------- const char *CPlayerInfo::GetName() { diff --git a/game/server/player.h b/game/server/player.h index e4ec0e1e..046c0dad 100644 --- a/game/server/player.h +++ b/game/server/player.h @@ -612,7 +612,7 @@ public: virtual void HandleAnimEvent( animevent_t *pEvent ); - virtual bool ShouldAnnounceAchievement( void ){ return true; } + virtual bool ShouldAnnounceAchievement( void ); #if defined USES_ECON_ITEMS // Wearables @@ -820,7 +820,9 @@ private: public: - + // How long since this player last interacted with something the game considers an objective/target/goal + float GetTimeSinceLastObjective( void ) const { return ( m_flLastObjectiveTime == -1.f ) ? 999.f : gpGlobals->curtime - m_flLastObjectiveTime; } + void SetLastObjectiveTime( float flTime ) { m_flLastObjectiveTime = flTime; } // Used by gamemovement to check if the entity is stuck. int m_StuckLast; @@ -895,6 +897,7 @@ public: private: Activity m_Activity; + float m_flLastObjectiveTime; // Last curtime player touched/killed something the gamemode considers an objective protected: @@ -1210,6 +1213,9 @@ private: // Store the last time we successfully processed a usercommand float m_flLastUserCommandTime; + // used to prevent achievement announcement spam + CUtlVector< float > m_flAchievementTimes; + public: virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set diff --git a/game/server/player_lagcompensation.cpp b/game/server/player_lagcompensation.cpp index 8dd4c756..92e6f2a7 100644 --- a/game/server/player_lagcompensation.cpp +++ b/game/server/player_lagcompensation.cpp @@ -172,6 +172,7 @@ class CLagCompensationManager : public CAutoGameSystemPerFrame, public ILagCompe public: CLagCompensationManager( char const *name ) : CAutoGameSystemPerFrame( name ), m_flTeleportDistanceSqr( 64 *64 ) { + m_isCurrentlyDoingCompensation = false; } // IServerSystem stuff @@ -194,6 +195,8 @@ public: void StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ); void FinishLagCompensation( CBasePlayer *player ); + bool IsCurrentlyDoingLagCompensation() const OVERRIDE { return m_isCurrentlyDoingCompensation; } + private: void BacktrackPlayer( CBasePlayer *player, float flTargetTime ); @@ -216,6 +219,8 @@ private: CBasePlayer *m_pCurrentPlayer; // The player we are doing lag compensation for float m_flTeleportDistanceSqr; + + bool m_isCurrentlyDoingCompensation; // Sentinel to prevent calling StartLagCompensation a second time before a Finish. }; static CLagCompensationManager g_LagCompensationManager( "CLagCompensationManager" ); @@ -322,6 +327,8 @@ void CLagCompensationManager::FrameUpdatePostEntityThink() // Called during player movement to set up/restore after lag compensation void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ) { + Assert( !m_isCurrentlyDoingCompensation ); + //DONT LAG COMP AGAIN THIS FRAME IF THERES ALREADY ONE IN PROGRESS //IF YOU'RE HITTING THIS THEN IT MEANS THERES A CODE BUG if ( m_pCurrentPlayer ) @@ -350,6 +357,8 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCm Q_memset( m_RestoreData, 0, sizeof( m_RestoreData ) ); Q_memset( m_ChangeData, 0, sizeof( m_ChangeData ) ); + m_isCurrentlyDoingCompensation = true; + // Get true latency // correct is the amout of time we have to correct game time @@ -734,7 +743,10 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player ) m_pCurrentPlayer = NULL; if ( !m_bNeedToRestore ) + { + m_isCurrentlyDoingCompensation = false; return; // no player was changed at all + } // Iterate all active players for ( int i = 1; i <= gpGlobals->maxClients; i++ ) @@ -828,6 +840,8 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player ) pPlayer->SetSimulationTime( restore->m_flSimulationTime ); } } + + m_isCurrentlyDoingCompensation = false; } diff --git a/game/server/props.cpp b/game/server/props.cpp index d20756f3..08b44141 100644 --- a/game/server/props.cpp +++ b/game/server/props.cpp @@ -1517,7 +1517,7 @@ void CBreakableProp::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Rea SetPhysicsAttacker( pPhysGunUser, gpGlobals->curtime ); - if( Reason == PUNTED_BY_CANNON ) + if( (int)Reason == (int)PUNTED_BY_CANNON ) { PlayPuntSound(); } diff --git a/game/server/recipientfilter.cpp b/game/server/recipientfilter.cpp index fa814735..d6d927ec 100644 --- a/game/server/recipientfilter.cpp +++ b/game/server/recipientfilter.cpp @@ -98,7 +98,7 @@ void CRecipientFilter::AddAllPlayers( void ) } } -void CRecipientFilter::AddRecipient( CBasePlayer *player ) +void CRecipientFilter::AddRecipient( const CBasePlayer *player ) { Assert( player ); diff --git a/game/server/recipientfilter.h b/game/server/recipientfilter.h index f935f878..2b00a231 100644 --- a/game/server/recipientfilter.h +++ b/game/server/recipientfilter.h @@ -46,7 +46,7 @@ public: void AddRecipientsByPVS( const Vector& origin ); void RemoveRecipientsByPVS( const Vector& origin ); void AddRecipientsByPAS( const Vector& origin ); - void AddRecipient( CBasePlayer *player ); + void AddRecipient( const CBasePlayer *player ); void RemoveAllRecipients( void ); void RemoveRecipient( CBasePlayer *player ); void RemoveRecipientByPlayerIndex( int playerindex ); @@ -82,7 +82,7 @@ private: class CSingleUserRecipientFilter : public CRecipientFilter { public: - CSingleUserRecipientFilter( CBasePlayer *player ) + CSingleUserRecipientFilter( const CBasePlayer *player ) { AddRecipient( player ); } diff --git a/game/server/sceneentity.cpp b/game/server/sceneentity.cpp index 69fd2f95..0b51da00 100644 --- a/game/server/sceneentity.cpp +++ b/game/server/sceneentity.cpp @@ -2163,11 +2163,6 @@ void CSceneEntity::InputTriggerEvent( inputdata_t &inputdata ) } } -struct NPCInterjection -{ - AI_Response *response; - CAI_BaseActor *npc; -}; //----------------------------------------------------------------------------- // Purpose: // Input : &inputdata - @@ -2176,93 +2171,62 @@ void CSceneEntity::InputInterjectResponse( inputdata_t &inputdata ) { // Not currently playing a scene if ( !m_pScene ) - { return; - } - CUtlVector< CAI_BaseActor * > candidates; - int i; - for ( i = 0 ; i < m_pScene->GetNumActors(); i++ ) + CUtlVector candidates; + + for ( int i = 0 ; i < m_pScene->GetNumActors(); i++ ) { CBaseFlex *pTestActor = FindNamedActor( i ); if ( !pTestActor ) continue; - CAI_BaseActor *pBaseActor = dynamic_cast(pTestActor); - if ( !pBaseActor ) - continue; - - if ( !pBaseActor->IsAlive() ) + CAI_BaseActor *pBaseActor = dynamic_cast(pTestActor); + if ( !pBaseActor || !pBaseActor->IsAlive() ) continue; candidates.AddToTail( pBaseActor ); } int c = candidates.Count(); - if ( !c ) - { return; - } - - int useIndex = 0; + if ( !m_bIsPlayingBack ) { // Use any actor if not playing a scene - useIndex = RandomInt( 0, c - 1 ); + // int useIndex = RandomInt( 0, c - 1 ); + Assert( !"m_bIsPlayBack is false and this code does nothing. Should it?"); } else { - CUtlVector< NPCInterjection > validResponses; + CUtlString modifiers("scene:"); + modifiers += STRING( GetEntityName() ); - char modifiers[ 512 ]; - Q_snprintf( modifiers, sizeof( modifiers ), "scene:%s", STRING( GetEntityName() ) ); - - for ( int i = 0; i < c; i++ ) + while (candidates.Count() > 0) { - CAI_BaseActor *npc = candidates[ i ]; - Assert( npc ); + // Pick a random slot in the candidates array. + int slot = RandomInt( 0, candidates.Count() - 1 ); - AI_Response *response = npc->SpeakFindResponse( inputdata.value.String(), modifiers ); - if ( !response ) - continue; + CAI_BaseActor *npc = candidates[ slot ]; - float duration = npc->GetResponseDuration( response ); - // Couldn't look it up - if ( duration <= 0.0f ) - continue; - - if ( !npc->PermitResponse( duration ) ) + // Try to find the response for this slot. + AI_Response response; + bool result = npc->SpeakFindResponse( response, inputdata.value.String(), modifiers.Get() ); + if ( result ) { - delete response; - continue; - } + float duration = npc->GetResponseDuration( response ); - // - NPCInterjection inter; - inter.response = response; - inter.npc = npc; - - validResponses.AddToTail( inter ); - } - - int rcount = validResponses.Count(); - if ( rcount >= 1 ) - { - int slot = RandomInt( 0, rcount - 1 ); - - for ( int i = 0; i < rcount; i++ ) - { - NPCInterjection *pInterjection = &validResponses[ i ]; - if ( i == slot ) + if ( ( duration > 0.0f ) && npc->PermitResponse( duration ) ) { - pInterjection->npc->SpeakDispatchResponse( inputdata.value.String(), pInterjection->response ); - } - else - { - delete pInterjection->response; + // If we could look it up, dispatch it and bail. + npc->SpeakDispatchResponse( inputdata.value.String(), response ); + return; } } + + // Remove this entry and look for another one. + candidates.FastRemove(slot); } } } @@ -2783,12 +2747,12 @@ void CSceneEntity::QueueResumePlayback( void ) CAI_BaseActor *pBaseActor = dynamic_cast(pActor); if ( pBaseActor ) { - AI_Response *result = pBaseActor->SpeakFindResponse( STRING(m_iszResumeSceneFile), NULL ); + AI_Response response; + bool result = pBaseActor->SpeakFindResponse( response, STRING(m_iszResumeSceneFile), NULL ); if ( result ) { - char response[ 256 ]; - result->GetResponse( response, sizeof( response ) ); - bStartedScene = InstancedScriptedScene( NULL, response, &m_hWaitingForThisResumeScene, 0, false ) != 0; + const char *szResponse = response.GetResponsePtr(); + bStartedScene = InstancedScriptedScene( NULL, szResponse, &m_hWaitingForThisResumeScene, 0, false ) != 0; } } } diff --git a/game/server/sendproxy.cpp b/game/server/sendproxy.cpp index 0f38f95d..e6226aef 100644 --- a/game/server/sendproxy.cpp +++ b/game/server/sendproxy.cpp @@ -27,7 +27,7 @@ void SendProxy_EHandleToInt( const SendProp *pProp, const void *pStruct, const v if ( pHandle && pHandle->Get() ) { - int iSerialNum = pHandle->GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1; + int iSerialNum = pHandle->GetSerialNumber() & ( (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1 ); pOut->m_Int = pHandle->GetEntryIndex() | (iSerialNum << MAX_EDICT_BITS); } else @@ -106,6 +106,7 @@ REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_OnlyToTeam ); #define TIME_BITS 24 // This table encodes edict data. +#if 0 static void SendProxy_Time( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID ) { float clock_base = floor( gpGlobals->curtime ); @@ -119,6 +120,7 @@ static void SendProxy_Time( const SendProp *pProp, const void *pStruct, const vo pOut->m_Int = addt; } +#endif //----------------------------------------------------------------------------- // Purpose: diff --git a/game/server/sound.cpp b/game/server/sound.cpp index 99ee86ff..657596d5 100644 --- a/game/server/sound.cpp +++ b/game/server/sound.cpp @@ -1187,7 +1187,7 @@ int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, name[0] = 0; ipick = engine->SentenceGroupPick( isentenceg, name, sizeof( name ) ); - if (ipick > 0 && name) + if ( ( ipick > 0 ) && name[0] ) { int sentenceIndex = SENTENCEG_Lookup( name ); CPASAttenuationFilter filter( GetContainingEntity( entity ), soundlevel ); diff --git a/game/server/team_control_point_master.cpp b/game/server/team_control_point_master.cpp index ea04c9dc..ae2b0040 100644 --- a/game/server/team_control_point_master.cpp +++ b/game/server/team_control_point_master.cpp @@ -1267,7 +1267,7 @@ float CTeamControlPointMaster::GetPartialCapturePointRate( void ) return m_flPartialCapturePointsRate; } -/* +#ifdef STAGING_ONLY //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1344,4 +1344,4 @@ void cc_PlayRound( const CCommand& args ) } static ConCommand playround( "playround", cc_PlayRound, "Play the selected round\n\tArgument: {round name given by \"listrounds\" command}", FCVAR_CHEAT ); -*/ \ No newline at end of file +#endif \ No newline at end of file diff --git a/game/server/team_control_point_master.h b/game/server/team_control_point_master.h index 64b1e9b5..4fc417c0 100644 --- a/game/server/team_control_point_master.h +++ b/game/server/team_control_point_master.h @@ -121,14 +121,18 @@ public: bool ShouldScorePerCapture( void ){ return m_bScorePerCapture; } bool ShouldPlayAllControlPointRounds( void ){ return m_bPlayAllRounds; } int NumPlayableControlPointRounds( void ); // checks to see if there are any more rounds to play (but doesn't actually "get" one to play) - -// void ListRounds( void ); + +#ifdef STAGING_ONLY + void ListRounds( void ); +#endif float GetPartialCapturePointRate( void ); void SetLastOwnershipChangeTime( float m_flTime ) { m_flLastOwnershipChangeTime = m_flTime; } float GetLastOwnershipChangeTime( void ) { return m_flLastOwnershipChangeTime; } + int GetCurrentRoundIndex() { return m_iCurrentRoundIndex; } + private: void EXPORT CPMThink( void ); diff --git a/game/server/team_train_watcher.cpp b/game/server/team_train_watcher.cpp index 1660df7a..fdb03693 100644 --- a/game/server/team_train_watcher.cpp +++ b/game/server/team_train_watcher.cpp @@ -73,6 +73,7 @@ BEGIN_DATADESC( CTeamTrainWatcher ) DEFINE_INPUTFUNC( FIELD_FLOAT, "SetSpeedForwardModifier", InputSetSpeedForwardModifier ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTrainRecedeTime", InputSetTrainRecedeTime ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetTrainCanRecede", InputSetTrainCanRecede ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTrainRecedeTimeAndUpdate", InputSetTrainRecedeTimeAndUpdate ), // Outputs DEFINE_OUTPUT( m_OnTrainStartRecede, "OnTrainStartRecede" ), @@ -714,6 +715,24 @@ void CTeamTrainWatcher::InputSetTrainRecedeTime( inputdata_t &inputdata ) } } +void CTeamTrainWatcher::InputSetTrainRecedeTimeAndUpdate(inputdata_t &inputdata) +{ + InputSetTrainRecedeTime( inputdata ); + + // update our time if we're already counting down + if ( m_flRecedeTime > 0 ) + { + m_flRecedeTotalTime = tf_escort_recede_time.GetFloat(); + if ( m_nTrainRecedeTime > 0 ) + { + m_flRecedeTotalTime = m_nTrainRecedeTime; + } + + m_flRecedeStartTime = gpGlobals->curtime; + m_flRecedeTime = m_flRecedeStartTime + m_flRecedeTotalTime; + } +} + void CTeamTrainWatcher::InputSetTrainCanRecede( inputdata_t &inputdata ) { m_bTrainCanRecede = inputdata.value.Bool(); diff --git a/game/server/team_train_watcher.h b/game/server/team_train_watcher.h index 0cfd6ffd..b5bb3fe0 100644 --- a/game/server/team_train_watcher.h +++ b/game/server/team_train_watcher.h @@ -58,6 +58,7 @@ public: void InputSetSpeedForwardModifier( inputdata_t &inputdata ); void InputSetTrainRecedeTime( inputdata_t &inputdata ); void InputSetTrainCanRecede( inputdata_t &inputdata ); + void InputSetTrainRecedeTimeAndUpdate( inputdata_t &inputdata ); // ========================================================== // given a start node and a list of goal nodes @@ -94,6 +95,8 @@ public: void DumpStats( void ); #endif // STAGING_ONLY && TF_DLL + float GetTrainProgress() { return m_flTotalProgress; } + private: void StartCaptureAlarm( CTeamControlPoint *pPoint ); diff --git a/game/server/trigger_area_capture.cpp b/game/server/trigger_area_capture.cpp index bdc2d2cf..b8b8352c 100644 --- a/game/server/trigger_area_capture.cpp +++ b/game/server/trigger_area_capture.cpp @@ -366,6 +366,7 @@ void CTriggerAreaCapture::CaptureThink( void ) } iNumBlockablePlayers[iTeam] += TeamplayGameRules()->GetCaptureValueForPlayer( pPlayer ); + pPlayer->SetLastObjectiveTime( gpGlobals->curtime ); } continue; } @@ -378,6 +379,7 @@ void CTriggerAreaCapture::CaptureThink( void ) } iNumPlayers[iTeam] += TeamplayGameRules()->GetCaptureValueForPlayer( pPlayer ); + pPlayer->SetLastObjectiveTime( gpGlobals->curtime ); } } } diff --git a/game/server/triggers.cpp b/game/server/triggers.cpp index 25102b40..3d9dbaff 100644 --- a/game/server/triggers.cpp +++ b/game/server/triggers.cpp @@ -33,6 +33,7 @@ #include "ai_behavior_follow.h" #include "ai_behavior_lead.h" #include "gameinterface.h" +#include "ilagcompensationmanager.h" #ifdef HL2_DLL #include "hl2_player.h" @@ -2269,7 +2270,7 @@ void CTriggerPush::Touch( CBaseEntity *pOther ) #endif Vector vecPush = (m_flPushSpeed * vecAbsDir); - if ( pOther->GetFlags() & FL_BASEVELOCITY ) + if ( ( pOther->GetFlags() & FL_BASEVELOCITY ) && !lagcompensation->IsCurrentlyDoingLagCompensation() ) { vecPush = vecPush + pOther->GetBaseVelocity(); } diff --git a/game/server/util.cpp b/game/server/util.cpp index 7ed3fc4a..b7bba73e 100644 --- a/game/server/util.cpp +++ b/game/server/util.cpp @@ -200,7 +200,7 @@ void CEntityFactoryDictionary::ReportEntitySizes() { for ( int i = m_Factories.First(); i != m_Factories.InvalidIndex(); i = m_Factories.Next( i ) ) { - Msg( " %s: %d", m_Factories.GetElementName( i ), m_Factories[i]->GetEntitySize() ); + Msg( " %s: %llu", m_Factories.GetElementName( i ), (uint64)(m_Factories[i]->GetEntitySize()) ); } } @@ -1348,7 +1348,7 @@ void UTIL_SnapDirectionToAxis( Vector &direction, float epsilon ) } } -char *UTIL_VarArgs( const char *format, ... ) +const char *UTIL_VarArgs( const char *format, ... ) { va_list argptr; static char string[1024]; diff --git a/game/server/util.h b/game/server/util.h index 37d53eff..5dfc1670 100644 --- a/game/server/util.h +++ b/game/server/util.h @@ -365,7 +365,7 @@ void UTIL_Beam( Vector &Start, Vector &End, int nModelIndex, int nHaloIndex, un float Life, unsigned char Width, unsigned char EndWidth, unsigned char FadeLength, unsigned char Noise, unsigned char Red, unsigned char Green, unsigned char Blue, unsigned char Brightness, unsigned char Speed); -char *UTIL_VarArgs( PRINTF_FORMAT_STRING const char *format, ... ); +const char *UTIL_VarArgs( PRINTF_FORMAT_STRING const char *format, ... ) FMTFUNCTION( 1, 2 ); bool UTIL_IsValidEntity( CBaseEntity *pEnt ); bool UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ); @@ -475,7 +475,7 @@ void UTIL_HudMessage( CBasePlayer *pToPlayer, const hudtextparms_t &textparms, void UTIL_HudHintText( CBaseEntity *pEntity, const char *pMessage ); // Writes message to console with timestamp and FragLog header. -void UTIL_LogPrintf( PRINTF_FORMAT_STRING const char *fmt, ... ); +void UTIL_LogPrintf( PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 1, 2 ); // Sorta like FInViewCone, but for nonNPCs. float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); diff --git a/game/server/vote_controller.cpp b/game/server/vote_controller.cpp index ea49ecdd..02f93590 100644 --- a/game/server/vote_controller.cpp +++ b/game/server/vote_controller.cpp @@ -10,6 +10,7 @@ #include "eiface.h" #include "team.h" #include "gameinterface.h" +#include "fmtstr.h" #ifdef TF_DLL #include "tf/tf_gamerules.h" @@ -39,15 +40,105 @@ CVoteController *g_voteController = NULL; ConVar sv_vote_timer_duration("sv_vote_timer_duration", "15", FCVAR_DEVELOPMENTONLY, "How long to allow voting on an issue"); ConVar sv_vote_command_delay("sv_vote_command_delay", "2", FCVAR_DEVELOPMENTONLY, "How long after a vote passes until the action happens", false, 0, true, 4.5); -ConVar sv_allow_votes("sv_allow_votes", "1", 0, "Allow voting?"); -ConVar sv_vote_failure_timer("sv_vote_failure_timer", "300", 0, "A vote that fails cannot be re-submitted for this long"); +ConVar sv_allow_votes("sv_allow_votes", "1", FCVAR_NONE, "Allow voting?"); +ConVar sv_vote_failure_timer( "sv_vote_failure_timer", "300", FCVAR_NONE, "A vote that fails cannot be re-submitted for this long" ); #ifdef TF_DLL -ConVar sv_vote_failure_timer_mvm( "sv_vote_failure_timer_mvm", "120", 0, "A vote that fails in MvM cannot be re-submitted for this long" ); +ConVar sv_vote_failure_timer_mvm( "sv_vote_failure_timer_mvm", "120", FCVAR_NONE, "A vote that fails in MvM cannot be re-submitted for this long" ); #endif // TF_DLL ConVar sv_vote_creation_timer("sv_vote_creation_timer", "120", FCVAR_DEVELOPMENTONLY, "How often someone can individually call a vote."); -ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", 1, "The minimum ratio of players needed to vote on an issue to resolve it.", true, 0.1, true, 1.0 ); -ConVar sv_vote_allow_spectators( "sv_vote_allow_spectators", "0", 0, "Allow spectators to vote?" ); -ConVar sv_vote_ui_hide_disabled_issues( "sv_vote_ui_hide_disabled_issues", "1", 0, "Suppress listing of disabled issues in the vote setup screen." ); +ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", FCVAR_HIDDEN, "The minimum ratio of players needed to vote on an issue to resolve it.", true, 0.1, true, 1.0 ); +ConVar sv_vote_allow_spectators( "sv_vote_allow_spectators", "0", FCVAR_NONE, "Allow spectators to vote?" ); +ConVar sv_vote_ui_hide_disabled_issues( "sv_vote_ui_hide_disabled_issues", "1", FCVAR_NONE, "Suppress listing of disabled issues in the vote setup screen." ); + +static const int k_nKickWatchListMaxDuration = 300; + +//----------------------------------------------------------------------------- +// Purpose: Game system to detect maps without cameras in them, and move on +//----------------------------------------------------------------------------- +class CVoteControllerSystem : public CAutoGameSystemPerFrame +{ +public: + CVoteControllerSystem( char const *name ) : CAutoGameSystemPerFrame( name ) + { + SetDefLessFunc( m_mapKickWatchList ); + m_flNextKickCheckTime = 0.f; + } + + virtual void LevelInitPreEntity() + { + } + + virtual void FrameUpdatePostEntityThink( void ) + { + // Executing the vote controller command needs to happen in the PostEntityThink as it can restart levels and + // blast entities, etc. If you're doing this during a regular think, this can cause entities thinking after + // you in Physics_RunThinkFunctions() to get grumpy and crash. + if ( g_voteController ) + { + // Vote passed - execute the command + if ( g_voteController->m_executeCommandTimer.HasStarted() && g_voteController->m_executeCommandTimer.IsElapsed() ) + { + g_voteController->m_executeCommandTimer.Invalidate(); + g_voteController->m_potentialIssues[g_voteController->m_iActiveIssueIndex]->ExecuteCommand(); + } + + // Kick watch + if ( m_flNextKickCheckTime < gpGlobals->curtime ) + { + FOR_EACH_MAP( m_mapKickWatchList, i ) + { + if ( gpGlobals->curtime > m_mapKickWatchList[i] ) + { + m_mapKickWatchList.RemoveAt( i ); + break; // Constantly called code - resume on next pass + } + + CBasePlayer *pTarget = NULL; + CSteamID steamIDPlayer; + for ( int j = 1; j <= gpGlobals->maxClients; j++ ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( j ); + if ( !pPlayer ) + continue; + + if ( pPlayer->GetSteamID( &steamIDPlayer ) == false ) + continue; + + if ( steamIDPlayer == m_mapKickWatchList.Key( i ) ) + { + pTarget = pPlayer; + break; + } + } + + if ( pTarget ) + { + // Welcome back + engine->ServerCommand( CFmtStr( "kickid %d %s;", pTarget->GetUserID(), "Kicked by server." ) ); + } + } + + m_flNextKickCheckTime = gpGlobals->curtime + 0.2f; + } + } + } + + void AddPlayerToKickWatchList( CSteamID steamID, float flDuration ) + { + flDuration = clamp( flDuration, 1.f, (float)k_nKickWatchListMaxDuration ); + if ( m_mapKickWatchList.Find( steamID ) == m_mapKickWatchList.InvalidIndex() ) + { + m_mapKickWatchList.Insert( steamID, ( gpGlobals->curtime + flDuration ) ); + } + } + +private: + + CUtlMap< CSteamID, float > m_mapKickWatchList; + float m_flNextKickCheckTime; +}; + +CVoteControllerSystem VoteControllerSystem( "CVoteControllerSystem" ); //----------------------------------------------------------------------------- // Purpose: @@ -101,7 +192,7 @@ CON_COMMAND( callvote, "Start a vote on an issue." ) { if ( pVoteCaller->GetTeamNumber() == TEAM_SPECTATOR ) { - g_voteController->SendVoteFailedMessage( VOTE_FAILED_SPECTATOR, pVoteCaller ); + g_voteController->SendVoteCreationFailedMessage( VOTE_FAILED_SPECTATOR, pVoteCaller ); return; } } @@ -111,7 +202,7 @@ CON_COMMAND( callvote, "Start a vote on an issue." ) int nCooldown = 0; if ( !g_voteController->CanEntityCallVote( pVoteCaller, nCooldown ) ) { - g_voteController->SendVoteFailedMessage( VOTE_FAILED_RATE_EXCEEDED, pVoteCaller, nCooldown ); + g_voteController->SendVoteCreationFailedMessage( VOTE_FAILED_RATE_EXCEEDED, pVoteCaller, nCooldown ); return; } #endif @@ -381,7 +472,7 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons { if ( !bDedicatedServer ) { - SendVoteFailedMessage( nErrorCode, pVoteCaller, nTime ); + SendVoteCreationFailedMessage( nErrorCode, pVoteCaller, nTime ); } } } @@ -391,35 +482,43 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons } //----------------------------------------------------------------------------- -// Purpose: Sent to everyone, unless we pass a player pointer +// Purpose: The vote failed to start - let the caller know why //----------------------------------------------------------------------------- -void CVoteController::SendVoteFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime ) +void CVoteController::SendVoteCreationFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime /*= -1*/ ) { - // driller: need to merge all failure case stuff into a single path - if ( pVoteCaller ) - { - CSingleUserRecipientFilter user( pVoteCaller ); - user.MakeReliable(); + Assert( pVoteCaller ); + if ( !pVoteCaller ) + return; - UserMessageBegin( user, "CallVoteFailed" ); - WRITE_BYTE( nReason ); - WRITE_SHORT( nTime ); - MessageEnd(); - } - else - { - UTIL_LogPrintf("Vote failed \"%s %s\" \n", - m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), - m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() ); + CSingleUserRecipientFilter user( pVoteCaller ); + user.MakeReliable(); - CBroadcastRecipientFilter filter; - filter.MakeReliable(); + UserMessageBegin( user, "CallVoteFailed" ); + WRITE_BYTE( nReason ); + WRITE_SHORT( nTime ); + MessageEnd(); +} - UserMessageBegin( filter, "VoteFailed" ); - WRITE_BYTE( m_iOnlyTeamToVote ); - WRITE_BYTE( nReason ); - MessageEnd(); - } +//----------------------------------------------------------------------------- +// Purpose: The vote was called, but failed to pass - let everyone know why +//----------------------------------------------------------------------------- +void CVoteController::SendVoteFailedToPassMessage( vote_create_failed_t nReason ) +{ + Assert( m_potentialIssues[m_iActiveIssueIndex] ); + + // See if we have a player target. + CBasePlayer *pVoteTarget = m_potentialIssues[m_iActiveIssueIndex]->m_hPlayerTarget; + bool bFakeClient = ( pVoteTarget && ( pVoteTarget->IsFakeClient() || pVoteTarget->IsHLTV() || pVoteTarget->IsReplay() ) ); + + UTIL_LogPrintf( "Vote failed \"%s %s\" with code %i (proxy: %i) \n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), (int)nReason, bFakeClient ); + + CBroadcastRecipientFilter filter; + filter.MakeReliable(); + + UserMessageBegin( filter, "VoteFailed" ); + WRITE_BYTE( m_iOnlyTeamToVote ); + WRITE_BYTE( nReason ); + MessageEnd(); } //----------------------------------------------------------------------------- @@ -577,7 +676,7 @@ void CVoteController::VoteControllerThink( void ) // Option1 is Yes if ( nWinningVoteOption != VOTE_OPTION1 ) { - SendVoteFailedMessage( VOTE_FAILED_YES_MUST_EXCEED_NO ); + SendVoteFailedToPassMessage( VOTE_FAILED_YES_MUST_EXCEED_NO ); bVotePassed = false; } } @@ -592,7 +691,7 @@ void CVoteController::VoteControllerThink( void ) } else { - SendVoteFailedMessage( VOTE_FAILED_QUORUM_FAILURE ); + SendVoteFailedToPassMessage( VOTE_FAILED_QUORUM_FAILURE ); bVotePassed = false; } @@ -601,9 +700,11 @@ void CVoteController::VoteControllerThink( void ) m_executeCommandTimer.Start( sv_vote_command_delay.GetFloat() ); m_resetVoteTimer.Start( 5.0 ); - UTIL_LogPrintf("Vote succeeded \"%s %s\"\n", - m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), - m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() ); + // Target is not always a player (changelevel, etc) + CBasePlayer *pVoteTarget = m_potentialIssues[m_iActiveIssueIndex]->m_hPlayerTarget; + bool bFakeClient = ( pVoteTarget && ( pVoteTarget->IsFakeClient() || pVoteTarget->IsHLTV() || pVoteTarget->IsReplay() ) ); + + UTIL_LogPrintf( "Vote succeeded \"%s %s\" (proxy: %i) \n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), bFakeClient ); CBroadcastRecipientFilter filter; filter.MakeReliable(); @@ -821,6 +922,14 @@ bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown ) return true; }; +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteController::AddPlayerToKickWatchList( CSteamID steamID, float flDuration ) +{ + VoteControllerSystem.AddPlayerToKickWatchList( steamID, flDuration ); +} + //----------------------------------------------------------------------------- // Purpose: BaseIssue //----------------------------------------------------------------------------- @@ -831,6 +940,7 @@ CBaseIssue::CBaseIssue( const char *pszTypeString ) m_iNumYesVotes = 0; m_iNumNoVotes = 0; m_iNumPotentialVotes = 0; + m_flNextCallTime = -1.f; ASSERT( g_voteController ); g_voteController->RegisterIssue( this ); @@ -943,9 +1053,18 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create return true; // Bogus player - if( iEntIndex == -1 ) + if ( iEntIndex == -1 ) return false; + // Note: Issue timers reset on level change because the class is created/destroyed during transitions. + // It'd be nice to refactor the basic framework of the system to get rid of side-effects like this. + if ( m_flNextCallTime != -1.f && gpGlobals->curtime < m_flNextCallTime ) + { + nFailCode = VOTE_FAILED_ON_COOLDOWN; + nTime = m_flNextCallTime - gpGlobals->curtime; + return false; + } + #ifdef TF_DLL if ( TFGameRules() && TFGameRules()->IsInWaitingForPlayers() && !TFGameRules()->IsInTournamentMode() ) { @@ -955,14 +1074,14 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create #endif // TF_DLL CBaseEntity *pVoteCaller = UTIL_EntityByIndex( iEntIndex ); - if( pVoteCaller && !CanTeamCallVote( GetVoterTeam( pVoteCaller ) ) ) + if ( pVoteCaller && !CanTeamCallVote( GetVoterTeam( pVoteCaller ) ) ) { nFailCode = VOTE_FAILED_TEAM_CANT_CALL; return false; } // Did this fail recently? - for( int iIndex = 0; iIndex < m_FailedVotes.Count(); iIndex++ ) + for ( int iIndex = 0; iIndex < m_FailedVotes.Count(); iIndex++ ) { FailedVote *pCurrentFailure = m_FailedVotes[iIndex]; int nTimeRemaining = pCurrentFailure->flLockoutTime - gpGlobals->curtime; @@ -988,7 +1107,7 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create if ( bFailed ) { - nFailCode = VOTE_FAILED_FAILED_RECENTLY; + nFailCode = VOTE_FAILED_ON_COOLDOWN; nTime = nTimeRemaining; return false; } @@ -1065,36 +1184,4 @@ bool CBaseIssue::GetVoteOptions( CUtlVector &vecNames ) return true; } -//----------------------------------------------------------------------------- -// Purpose: Game system to detect maps without cameras in them, and move on -//----------------------------------------------------------------------------- -class CVoteControllerSystem : public CAutoGameSystemPerFrame -{ -public: - CVoteControllerSystem( char const *name ) : CAutoGameSystemPerFrame( name ) - { - } - - virtual void LevelInitPreEntity() - { - } - - virtual void FrameUpdatePostEntityThink( void ) - { - // Executing the vote controller command needs to happen in the PostEntityThink as it can restart levels and - // blast entities, etc. If you're doing this during a regular think, this can cause entities thinking after - // you in Physics_RunThinkFunctions() to get grumpy and crash. - if( g_voteController ) - { - // Vote passed - execute the command - if( g_voteController->m_executeCommandTimer.HasStarted() && g_voteController->m_executeCommandTimer.IsElapsed() ) - { - g_voteController->m_executeCommandTimer.Invalidate(); - g_voteController->m_potentialIssues[ g_voteController->m_iActiveIssueIndex ]->ExecuteCommand(); - } - } - } -}; - -CVoteControllerSystem VoteControllerSystem( "CVoteControllerSystem" ); diff --git a/game/server/vote_controller.h b/game/server/vote_controller.h index 4d4b78b2..9a8fa253 100644 --- a/game/server/vote_controller.h +++ b/game/server/vote_controller.h @@ -17,7 +17,7 @@ #define MAX_COMMAND_LENGTH 64 #define MAX_CREATE_ERROR_STRING 96 -class CBaseIssue // Abstract base class for all things-that-can-be-voted-on. +class CBaseIssue // Base class concept for vote issues (i.e. Kick Player). Created per level-load and destroyed by CVoteController's dtor. { public: CBaseIssue(const char *typeString); @@ -41,6 +41,9 @@ public: virtual void SetYesNoVoteCount( int iNumYesVotes, int iNumNoVotes, int iNumPotentialVotes ); virtual bool GetVoteOptions( CUtlVector &vecNames ); // We use this to generate options for voting virtual bool BRecordVoteFailureEventForEntity( int iVoteCallingEntityIndex ) const { return iVoteCallingEntityIndex != DEDICATED_SERVER; } + void SetIssueCooldownDuration( float flDuration ) { m_flNextCallTime = gpGlobals->curtime + flDuration; } // The issue can not be raised again for this period of time (in seconds) + + CHandle< CBasePlayer > m_hPlayerTarget; // If the target of the issue is a player, we should store them here protected: static void ListStandardNoArgCommand( CBasePlayer *forWhom, const char *issueString ); // List a Yes vote command @@ -59,6 +62,7 @@ protected: int m_iNumYesVotes; int m_iNumNoVotes; int m_iNumPotentialVotes; + float m_flNextCallTime; }; class CVoteController : public CBaseEntity @@ -93,7 +97,8 @@ public: void ListIssues( CBasePlayer *pForWhom ); bool IsValidVoter( CBasePlayer *pWhom ); bool CanTeamCastVote( int iTeam ) const; - void SendVoteFailedMessage( vote_create_failed_t nReason = VOTE_FAILED_GENERIC, CBasePlayer *pVoteCaller = NULL, int nTime = -1 ); + void SendVoteCreationFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime = -1 ); + void SendVoteFailedToPassMessage( vote_create_failed_t nReason ); void VoteChoice_Increment( int nVoteChoice ); void VoteChoice_Decrement( int nVoteChoice ); int GetWinningVoteOption( void ); @@ -101,6 +106,8 @@ public: bool CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown ); bool IsVoteActive( void ) { return m_iActiveIssueIndex != INVALID_ISSUE; } + void AddPlayerToKickWatchList( CSteamID steamID, float flDuration ); + protected: void ResetData( void ); void VoteControllerThink( void ); diff --git a/game/shared/GameStats.cpp b/game/shared/GameStats.cpp index e81eaed6..c4d7a222 100644 --- a/game/shared/GameStats.cpp +++ b/game/shared/GameStats.cpp @@ -1199,6 +1199,7 @@ void CBaseGameStats_Driver::ResetData() pKV->SetInt( "Height", dest_height ); const MaterialSystem_Config_t &config = materials->GetCurrentConfigForVideoCard(); pKV->SetInt( "Windowed", config.Windowed() == true ); + pKV->SetInt( "MaxDxLevel", g_pMaterialSystemHardwareConfig->GetMaxDXSupportLevel() ); engine->SetGamestatsData( m_pGamestatsData ); #endif diff --git a/game/shared/Multiplayer/multiplayer_animstate.cpp b/game/shared/Multiplayer/multiplayer_animstate.cpp index 135234d7..0bea2319 100644 --- a/game/shared/Multiplayer/multiplayer_animstate.cpp +++ b/game/shared/Multiplayer/multiplayer_animstate.cpp @@ -358,16 +358,21 @@ void CMultiPlayerAnimState::PlayFlinchGesture( Activity iActivity ) //----------------------------------------------------------------------------- bool CMultiPlayerAnimState::InitGestureSlots( void ) { - // Get the base player. - CBasePlayer *pPlayer = GetBasePlayer(); - if( pPlayer ) + // Setup the number of gesture slots. + m_aGestureSlots.AddMultipleToTail( GESTURE_SLOT_COUNT ); + + // Assign all of the the CAnimationLayer pointers to null early in case we bail. + for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture ) { - // Set the number of animation overlays we will use. - pPlayer->SetNumAnimOverlays( GESTURE_SLOT_COUNT ); + m_aGestureSlots[iGesture].m_pAnimLayer = NULL; } - // Setup the number of gesture slots. - m_aGestureSlots.AddMultipleToTail( GESTURE_SLOT_COUNT ); + // Get the base player. + CBasePlayer *pPlayer = GetBasePlayer(); + + // Set the number of animation overlays we will use. + pPlayer->SetNumAnimOverlays( GESTURE_SLOT_COUNT ); + for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture ) { m_aGestureSlots[iGesture].m_pAnimLayer = pPlayer->GetAnimOverlay( iGesture ); @@ -409,6 +414,9 @@ void CMultiPlayerAnimState::ResetGestureSlot( int iGestureSlot ) // Sanity Check Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT ); + if ( !VerifyAnimLayerInSlot( iGestureSlot ) ) + return; + GestureSlot_t *pGestureSlot = &m_aGestureSlots[iGestureSlot]; if ( pGestureSlot ) { @@ -486,6 +494,36 @@ bool CMultiPlayerAnimState::IsGestureSlotActive( int iGestureSlot ) return m_aGestureSlots[iGestureSlot].m_bActive; } + +//----------------------------------------------------------------------------- +// Purpose: Track down a crash +//----------------------------------------------------------------------------- +bool CMultiPlayerAnimState::VerifyAnimLayerInSlot( int iGestureSlot ) +{ + if ( iGestureSlot < 0 || iGestureSlot >= GESTURE_SLOT_COUNT ) + { + return false; + } + + if ( GetBasePlayer()->GetNumAnimOverlays() < iGestureSlot + 1 ) + { + AssertMsg2( false, "Player %d doesn't have gesture slot %d any more.", GetBasePlayer()->entindex(), iGestureSlot ); + Msg( "Player %d doesn't have gesture slot %d any more.\n", GetBasePlayer()->entindex(), iGestureSlot ); + m_aGestureSlots[iGestureSlot].m_pAnimLayer = NULL; + return false; + } + + CAnimationLayer *pExpected = GetBasePlayer()->GetAnimOverlay( iGestureSlot ); + if ( m_aGestureSlots[iGestureSlot].m_pAnimLayer != pExpected ) + { + AssertMsg3( false, "Gesture slot %d pointing to wrong address %p. Updating to new address %p.", iGestureSlot, m_aGestureSlots[iGestureSlot].m_pAnimLayer, pExpected ); + Msg( "Gesture slot %d pointing to wrong address %p. Updating to new address %p.\n", iGestureSlot, m_aGestureSlots[iGestureSlot].m_pAnimLayer, pExpected ); + m_aGestureSlots[iGestureSlot].m_pAnimLayer = pExpected; + } + + return true; +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -509,6 +547,9 @@ void CMultiPlayerAnimState::RestartGesture( int iGestureSlot, Activity iGestureA // Sanity Check Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT ); + if ( !VerifyAnimLayerInSlot( iGestureSlot ) ) + return; + if ( !IsGestureSlotPlaying( iGestureSlot, iGestureActivity ) ) { #ifdef CLIENT_DLL @@ -549,6 +590,9 @@ void CMultiPlayerAnimState::AddToGestureSlot( int iGestureSlot, Activity iGestur if ( !m_aGestureSlots[iGestureSlot].m_pAnimLayer ) return; + if ( !VerifyAnimLayerInSlot( iGestureSlot ) ) + return; + // Get the sequence. int iGestureSequence = pPlayer->SelectWeightedSequence( iGestureActivity ); if ( iGestureSequence <= 0 ) @@ -623,6 +667,9 @@ void CMultiPlayerAnimState::AddVCDSequenceToGestureSlot( int iGestureSlot, int i if ( !m_aGestureSlots[iGestureSlot].m_pAnimLayer ) return; + if ( !VerifyAnimLayerInSlot( iGestureSlot ) ) + return; + // Set the activity. Activity iGestureActivity = ACT_MP_VCD; @@ -1154,6 +1201,9 @@ void CMultiPlayerAnimState::ComputeGestureSequence( CStudioHdr *pStudioHdr ) if ( !m_aGestureSlots[iGesture].m_bActive ) continue; + if ( !VerifyAnimLayerInSlot( iGesture ) ) + continue; + UpdateGestureLayer( pStudioHdr, &m_aGestureSlots[iGesture] ); } } diff --git a/game/shared/Multiplayer/multiplayer_animstate.h b/game/shared/Multiplayer/multiplayer_animstate.h index 44866c24..49450acf 100644 --- a/game/shared/Multiplayer/multiplayer_animstate.h +++ b/game/shared/Multiplayer/multiplayer_animstate.h @@ -200,6 +200,7 @@ public: void AddVCDSequenceToGestureSlot( int iGestureSlot, int iGestureSequence, float flCycle = 0.0f, bool bAutoKill = true ); CAnimationLayer* GetGestureSlotLayer( int iGestureSlot ); bool IsGestureSlotActive( int iGestureSlot ); + bool VerifyAnimLayerInSlot( int iGestureSlot ); // Feet. bool m_bForceAimYaw; diff --git a/game/shared/SoundEmitterSystem.cpp b/game/shared/SoundEmitterSystem.cpp index 2b665654..08f74ad0 100644 --- a/game/shared/SoundEmitterSystem.cpp +++ b/game/shared/SoundEmitterSystem.cpp @@ -465,7 +465,6 @@ public: { return; } -#endif // STAGING_ONLY if ( !Q_strncasecmp( params.soundname, "vo", 2 ) && !( params.channel == CHAN_STREAM || @@ -475,6 +474,7 @@ public: DevMsg( "EmitSound: Voice wave file %s doesn't specify CHAN_VOICE, CHAN_VOICE2 or CHAN_STREAM for sound %s\n", params.soundname, ep.m_pSoundName ); } +#endif // STAGING_ONLY // handle SND_CHANGEPITCH/SND_CHANGEVOL and other sound flags.etc. if( ep.m_nFlags & SND_CHANGE_PITCH ) diff --git a/game/shared/activitylist.cpp b/game/shared/activitylist.cpp index 3f91e76c..172fd5f3 100644 --- a/game/shared/activitylist.cpp +++ b/game/shared/activitylist.cpp @@ -2275,6 +2275,35 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_ARM ); REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_FIRE ); + REGISTER_SHARED_ACTIVITY( ACT_BREADSAPPER_VM_DRAW ); + REGISTER_SHARED_ACTIVITY( ACT_BREADSAPPER_VM_IDLE ); + + REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_HITLEFT ); + REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_HITRIGHT ); + REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_SWINGHARD ); + REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_IDLE ); + REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_DRAW ); + + REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_IDLE ); + REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_HITRIGHT ); + REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_HITUP ); + + REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_DRAW ); + REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_IDLE ); + REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_PRIMARYATTACK ); + + REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_DEPLOY ); + REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_DEPLOY_IDLE ); + REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_RETRACT ); + REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_RETRACT_IDLE ); + + REGISTER_SHARED_ACTIVITY( ACT_BOT_SPAWN ); + REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC ); + REGISTER_SHARED_ACTIVITY( ACT_BOT_PRIMARY_MOVEMENT ); + REGISTER_SHARED_ACTIVITY( ACT_BOT_GESTURE_FLINCH ); + REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_START ); + REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_END ); + AssertMsg( g_HighestActivity == LAST_SHARED_ACTIVITY - 1, "Not all activities from ai_activity.h registered in activitylist.cpp" ); } diff --git a/game/shared/ai_activity.h b/game/shared/ai_activity.h index d0b513df..a81dc003 100644 --- a/game/shared/ai_activity.h +++ b/game/shared/ai_activity.h @@ -2107,6 +2107,37 @@ typedef enum ACT_SPELL_VM_ARM, ACT_SPELL_VM_FIRE, + // Bread Monster Sapper + ACT_BREADSAPPER_VM_DRAW, + ACT_BREADSAPPER_VM_IDLE, + + // Bread Gloves + ACT_BREADGLOVES_VM_HITLEFT, + ACT_BREADGLOVES_VM_HITRIGHT, + ACT_BREADGLOVES_VM_SWINGHARD, + ACT_BREADGLOVES_VM_IDLE, + ACT_BREADGLOVES_VM_DRAW, + + ACT_BREADMONSTER_GLOVES_IDLE, + ACT_BREADMONSTER_GLOVES_HITRIGHT, + ACT_BREADMONSTER_GLOVES_HITUP, + + ACT_BREADMONSTER_VM_DRAW, + ACT_BREADMONSTER_VM_IDLE, + ACT_BREADMONSTER_VM_PRIMARYATTACK, + + ACT_PARACHUTE_DEPLOY, + ACT_PARACHUTE_DEPLOY_IDLE, + ACT_PARACHUTE_RETRACT, + ACT_PARACHUTE_RETRACT_IDLE, + + ACT_BOT_SPAWN, + ACT_BOT_PANIC, + ACT_BOT_PRIMARY_MOVEMENT, + ACT_BOT_GESTURE_FLINCH, + ACT_BOT_PANIC_START, + ACT_BOT_PANIC_END, + // this is the end of the global activities, private per-monster activities start here. LAST_SHARED_ACTIVITY, } Activity; diff --git a/game/shared/apparent_velocity_helper.h b/game/shared/apparent_velocity_helper.h index ac785c13..5a2ae9e7 100644 --- a/game/shared/apparent_velocity_helper.h +++ b/game/shared/apparent_velocity_helper.h @@ -46,9 +46,10 @@ template< class T, class Functor=CDefaultCalcDistance > class CApparentVelocity { public: - CApparentVelocity() + CApparentVelocity(const T& t0) { m_LastTime = -1; + m_LastValue = t0; } float AddSample( float time, T value ) diff --git a/game/shared/base_playeranimstate.cpp b/game/shared/base_playeranimstate.cpp index 411d764f..9de4e916 100644 --- a/game/shared/base_playeranimstate.cpp +++ b/game/shared/base_playeranimstate.cpp @@ -65,7 +65,7 @@ CBasePlayerAnimState::CBasePlayerAnimState() m_flEyePitch = 0.0f; m_bCurrentFeetYawInitialized = false; m_flCurrentTorsoYaw = 0.0f; - m_flCurrentTorsoYaw = TURN_NONE; + m_nTurningInPlace = TURN_NONE; m_flMaxGroundSpeed = 0.0f; m_flStoredCycle = 0.0f; diff --git a/game/shared/baseachievement.cpp b/game/shared/baseachievement.cpp index 82db3c32..5fb4e9ab 100644 --- a/game/shared/baseachievement.cpp +++ b/game/shared/baseachievement.cpp @@ -427,13 +427,7 @@ void CBaseAchievement::EnsureComponentBitSetAndEvaluate( int iBitNumber ) // new component, set the bit and increment the count SetComponentBits( m_iComponentBits | iBitMask ); - Assert( m_iCount <= m_iGoal ); - if ( m_iCount == m_iGoal ) - { - // all components found, award the achievement (and save state) - AwardAchievement(); - } - else + if ( m_iCount != m_iGoal ) { // save our state at the next good opportunity m_pAchievementMgr->SetDirty( true ); @@ -453,6 +447,15 @@ void CBaseAchievement::EnsureComponentBitSetAndEvaluate( int iBitNumber ) Msg( "Component %d for achievement %s found, but already had that component\n", iBitNumber, GetName() ); } } + + // Check to see if we've achieved our goal even if the bit is already set + // (this fixes some older achievements that are stuck in the 9/9 state and could never be evaluated) + Assert( m_iCount <= m_iGoal ); + if ( m_iCount == m_iGoal ) + { + // all components found, award the achievement (and save state) + AwardAchievement(); + } } //----------------------------------------------------------------------------- diff --git a/game/shared/baseachievement.h b/game/shared/baseachievement.h index 18c56ce6..e5119c37 100644 --- a/game/shared/baseachievement.h +++ b/game/shared/baseachievement.h @@ -105,6 +105,9 @@ public: virtual void Think( void ) { return; } + const char *GetMapNameFilter( void ){ return m_pMapNameFilter; } + CAchievementMgr *GetAchievementMgr( void ){ return m_pAchievementMgr; } + protected: virtual void FireGameEvent( IGameEvent *event ); virtual void FireGameEvent_Internal( IGameEvent *event ) {}; diff --git a/game/shared/basecombatweapon_shared.cpp b/game/shared/basecombatweapon_shared.cpp index 28c98bf5..57fb3133 100644 --- a/game/shared/basecombatweapon_shared.cpp +++ b/game/shared/basecombatweapon_shared.cpp @@ -38,6 +38,8 @@ #endif +#include "vprof.h" + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -164,8 +166,20 @@ void CBaseCombatWeapon::GiveDefaultAmmo( void ) //----------------------------------------------------------------------------- void CBaseCombatWeapon::Spawn( void ) { + bool bPrecacheAllowed = CBaseEntity::IsPrecacheAllowed(); + if (!bPrecacheAllowed) + { + tmEnter( TELEMETRY_LEVEL1, TMZF_NONE, "LateWeaponPrecache" ); + } + Precache(); + if (!bPrecacheAllowed) + { + tmLeave( TELEMETRY_LEVEL1 ); + } + + BaseClass::Spawn(); SetSolid( SOLID_BBOX ); @@ -1643,6 +1657,11 @@ void CBaseCombatWeapon::ItemPreFrame( void ) #endif } +bool CBaseCombatWeapon::CanPerformSecondaryAttack() const +{ + return m_flNextSecondaryAttack <= gpGlobals->curtime; +} + //==================================================================================== // WEAPON BEHAVIOUR //==================================================================================== @@ -1667,7 +1686,7 @@ void CBaseCombatWeapon::ItemPostFrame( void ) bool bFired = false; // Secondary attack has priority - if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime)) + if ((pOwner->m_nButtons & IN_ATTACK2) && CanPerformSecondaryAttack() ) { if (UsesSecondaryAmmo() && pOwner->GetAmmoCount(m_iSecondaryAmmoType)<=0 ) { diff --git a/game/shared/basecombatweapon_shared.h b/game/shared/basecombatweapon_shared.h index 75e1063a..0c0e2ac8 100644 --- a/game/shared/basecombatweapon_shared.h +++ b/game/shared/basecombatweapon_shared.h @@ -247,6 +247,7 @@ public: virtual void HandleFireOnEmpty(); // Called when they have the attack button down // but they are out of ammo. The default implementation // either reloads, switches weapons, or plays an empty sound. + virtual bool CanPerformSecondaryAttack() const; virtual bool ShouldBlockPrimaryFire() { return false; } diff --git a/game/shared/baseentity_shared.cpp b/game/shared/baseentity_shared.cpp index 949143b1..3e8620f7 100644 --- a/game/shared/baseentity_shared.cpp +++ b/game/shared/baseentity_shared.cpp @@ -2250,6 +2250,15 @@ int CBaseEntity::GetTracerAttachment( void ) return iAttachment; } +float CBaseEntity::HealthFraction() const +{ + if ( GetMaxHealth() == 0 ) + return 1.0f; + + float flFraction = ( float )GetHealth() / ( float )GetMaxHealth(); + flFraction = clamp( flFraction, 0.0f, 1.0f ); + return flFraction; +} int CBaseEntity::BloodColor() { diff --git a/game/shared/baseprojectile.cpp b/game/shared/baseprojectile.cpp index 3d08598b..12ebe500 100644 --- a/game/shared/baseprojectile.cpp +++ b/game/shared/baseprojectile.cpp @@ -12,6 +12,11 @@ IMPLEMENT_NETWORKCLASS_ALIASED( BaseProjectile, DT_BaseProjectile ) BEGIN_NETWORK_TABLE( CBaseProjectile, DT_BaseProjectile ) +#if !defined( CLIENT_DLL ) + SendPropEHandle( SENDINFO( m_hOriginalLauncher ) ), +#else + RecvPropEHandle( RECVINFO( m_hOriginalLauncher ) ), +#endif // CLIENT_DLL END_NETWORK_TABLE() @@ -22,5 +27,63 @@ CBaseProjectile::CBaseProjectile() { #ifdef GAME_DLL m_iDestroyableHitCount = 0; + + m_bCanCollideWithTeammates = false; #endif + m_hOriginalLauncher = NULL; } + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseProjectile::SetLauncher( CBaseEntity *pLauncher ) +{ + if ( m_hOriginalLauncher == NULL ) + { + m_hOriginalLauncher = pLauncher; + } + +#ifdef GAME_DLL + ResetCollideWithTeammates(); +#endif // GAME_DLL +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseProjectile::Spawn() +{ + BaseClass::Spawn(); + +#ifdef GAME_DLL + ResetCollideWithTeammates(); +#endif // GAME_DLL +} + + +#ifdef GAME_DLL + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseProjectile::CollideWithTeammatesThink() +{ + m_bCanCollideWithTeammates = true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseProjectile::ResetCollideWithTeammates() +{ + // Don't collide with players on the owner's team for the first bit of our life + m_bCanCollideWithTeammates = false; + + SetContextThink( &CBaseProjectile::CollideWithTeammatesThink, gpGlobals->curtime + GetCollideWithTeammatesDelay(), "CollideWithTeammates" ); +} + +#endif // GAME_DLL + diff --git a/game/shared/baseprojectile.h b/game/shared/baseprojectile.h index 76a93d97..af052a8b 100644 --- a/game/shared/baseprojectile.h +++ b/game/shared/baseprojectile.h @@ -36,18 +36,37 @@ public: CBaseProjectile(); + virtual void Spawn(); + #ifdef GAME_DLL virtual int GetDestroyableHitCount( void ) const { return m_iDestroyableHitCount; } void IncrementDestroyableHitCount( void ) { ++m_iDestroyableHitCount; } + + bool CanCollideWithTeammates() const { return m_bCanCollideWithTeammates; } + virtual float GetCollideWithTeammatesDelay() const { return 0.25f; } #endif // GAME_DLL virtual bool IsDestroyable( void ) { return false; } virtual void Destroy( bool bBlinkOut = true, bool bBreakRocket = false ) {} + virtual void SetLauncher( CBaseEntity *pLauncher ); + CBaseEntity *GetOriginalLauncher() const { return m_hOriginalLauncher; } protected: #ifdef GAME_DLL + void CollideWithTeammatesThink(); + int m_iDestroyableHitCount; #endif // GAME_DLL + +private: + +#ifdef GAME_DLL + void ResetCollideWithTeammates(); + + bool m_bCanCollideWithTeammates; +#endif // GAME_DLL + + CNetworkHandle( CBaseEntity, m_hOriginalLauncher ); }; #endif // BASEPROJECTILE_H diff --git a/game/shared/choreoevent.cpp b/game/shared/choreoevent.cpp index ef9058c8..40dc24da 100644 --- a/game/shared/choreoevent.cpp +++ b/game/shared/choreoevent.cpp @@ -2076,8 +2076,8 @@ public: { if ( ARRAYSIZE( g_NameMap ) != CChoreoEvent::NUM_TYPES ) { - Error( "g_NameMap contains %i entries, CChoreoEvent::NUM_TYPES == %i!", - ARRAYSIZE( g_NameMap ), CChoreoEvent::NUM_TYPES ); + Error( "g_NameMap contains %llu entries, CChoreoEvent::NUM_TYPES == %i!", + (uint64)(ARRAYSIZE( g_NameMap )), CChoreoEvent::NUM_TYPES ); } for ( int i = 0; i < CChoreoEvent::NUM_TYPES; ++i ) { @@ -2158,8 +2158,8 @@ public: { if ( ARRAYSIZE( g_CCNameMap ) != CChoreoEvent::NUM_CC_TYPES ) { - Error( "g_CCNameMap contains %i entries, CChoreoEvent::NUM_CC_TYPES == %i!", - ARRAYSIZE( g_CCNameMap ), CChoreoEvent::NUM_CC_TYPES ); + Error( "g_CCNameMap contains %llu entries, CChoreoEvent::NUM_CC_TYPES == %i!", + (uint64)(ARRAYSIZE( g_CCNameMap )), CChoreoEvent::NUM_CC_TYPES ); } for ( int i = 0; i < CChoreoEvent::NUM_CC_TYPES; ++i ) { diff --git a/game/shared/choreoscene.cpp b/game/shared/choreoscene.cpp index 3930c1d0..15b58785 100644 --- a/game/shared/choreoscene.cpp +++ b/game/shared/choreoscene.cpp @@ -158,6 +158,7 @@ CChoreoScene& CChoreoScene::operator=( const CChoreoScene& src ) m_pTokenizer = src.m_pTokenizer; m_flCurrentTime = src.m_flCurrentTime; + m_flStartLoopTime = src.m_flStartLoopTime; m_flStartTime = src.m_flStartTime; m_flEndTime = src.m_flEndTime; m_flSoundSystemLatency = src.m_flSoundSystemLatency; @@ -236,6 +237,7 @@ void CChoreoScene::Init( IChoreoEventCallback *callback ) m_szMapname[ 0 ] = 0; m_flCurrentTime = 0.0f; + m_flStartLoopTime = -1.f; m_flStartTime = 0.0f; m_flEndTime = 0.0f; m_flSoundSystemLatency = 0.0f; @@ -2314,6 +2316,8 @@ void CChoreoScene::ResetSimulation( bool forward /*= true*/, float starttime /*= m_flCurrentTime = forward ? m_flEarliestTime : m_flLatestTime; + m_flStartLoopTime = -1.f; + // choreoprintf( 0, "Start time %f\n", m_flCurrentTime ); m_flLastActiveTime = 0.0f; @@ -2475,6 +2479,15 @@ int CChoreoScene::EventThink( CChoreoEvent *e, float frame_start_time, float fra } } */ + + if ( !suppressed ) + { + // if this SPEAK event starts before the beginning of the current loop, don't play the SPEAK event again in the loop + if ( m_flStartLoopTime >= 0.f && starttime < m_flStartLoopTime ) + { + return iret; + } + } } break; case CChoreoEvent::SUBSCENE: @@ -2838,6 +2851,8 @@ void CChoreoScene::SetTime( float t ) void CChoreoScene::LoopToTime( float t ) { m_flCurrentTime = t; + + m_flStartLoopTime = t; } //----------------------------------------------------------------------------- diff --git a/game/shared/choreoscene.h b/game/shared/choreoscene.h index 1e8db53e..81e87b0c 100644 --- a/game/shared/choreoscene.h +++ b/game/shared/choreoscene.h @@ -326,6 +326,8 @@ private: // Current simulation time float m_flCurrentTime; + float m_flStartLoopTime; + float m_flStartTime; float m_flEndTime; diff --git a/game/shared/effect_color_tables.h b/game/shared/effect_color_tables.h index 59afe210..8cc5cf6c 100644 --- a/game/shared/effect_color_tables.h +++ b/game/shared/effect_color_tables.h @@ -33,10 +33,10 @@ enum // Commander mode table static colorentry_t commandercolors[] = { - { COMMAND_POINT_RED, 1.0, 0.0, 0.0 }, - { COMMAND_POINT_BLUE, 0.0, 0.0, 1.0 }, - { COMMAND_POINT_GREEN, 0.0, 1.0, 0.0 }, - { COMMAND_POINT_YELLOW, 1.0, 1.0, 0.0 }, + { COMMAND_POINT_RED, 1, 0, 0 }, + { COMMAND_POINT_BLUE, 0, 0, 1 }, + { COMMAND_POINT_GREEN, 0, 1, 0 }, + { COMMAND_POINT_YELLOW, 1, 1, 0 }, }; static colorentry_t bloodcolors[] = diff --git a/game/shared/eventlist.cpp b/game/shared/eventlist.cpp index fdb66524..5bea0215 100644 --- a/game/shared/eventlist.cpp +++ b/game/shared/eventlist.cpp @@ -248,4 +248,5 @@ void EventList_RegisterSharedEvents( void ) REGISTER_SHARED_ANIMEVENT( AE_WPN_UNHIDE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_PLAYWPNSOUND, AE_TYPE_CLIENT | AE_TYPE_SERVER ); + REGISTER_SHARED_ANIMEVENT( AE_RD_ROBOT_POP_PANELS_OFF, AE_TYPE_CLIENT | AE_TYPE_SERVER ); } \ No newline at end of file diff --git a/game/shared/eventlist.h b/game/shared/eventlist.h index 2cc9ac25..6fec5bd6 100644 --- a/game/shared/eventlist.h +++ b/game/shared/eventlist.h @@ -85,6 +85,8 @@ typedef enum AE_WPN_PLAYWPNSOUND, // Play a weapon sound from the weapon script file + AE_RD_ROBOT_POP_PANELS_OFF, + LAST_SHARED_ANIMEVENT, } Animevent; diff --git a/game/shared/gamemovement.cpp b/game/shared/gamemovement.cpp index 8291ae5a..c1564e93 100644 --- a/game/shared/gamemovement.cpp +++ b/game/shared/gamemovement.cpp @@ -518,7 +518,7 @@ void CGameMovement::DiffPrint( char const *fmt, ... ) #endif // !PREDICTION_ERROR_CHECK_LEVEL #ifndef _XBOX -void COM_Log( char *pszFile, const char *fmt, ...) +void COM_Log( const char *pszFile, const char *fmt, ...) { va_list argptr; char string[1024]; diff --git a/game/shared/gamerules.h b/game/shared/gamerules.h index 23da2415..d94454b0 100644 --- a/game/shared/gamerules.h +++ b/game/shared/gamerules.h @@ -205,6 +205,8 @@ public: #else + virtual void Status( void (*print) (const char *fmt, ...) ) {} + virtual void GetTaggedConVarList( KeyValues *pCvarTagList ) {} // NVNT see if the client of the player entered is using a haptic device. diff --git a/game/shared/mapentities_shared.cpp b/game/shared/mapentities_shared.cpp index 1e757870..9a6c92b2 100644 --- a/game/shared/mapentities_shared.cpp +++ b/game/shared/mapentities_shared.cpp @@ -125,7 +125,7 @@ const char *MapEntity_ParseToken( const char *data, char *newToken ) for ( const char *c = s_BraceChars; *c; c++ ) { - s_BraceCharacters[*c] = true; + s_BraceCharacters[(unsigned)*c] = true; } } diff --git a/game/shared/mp_shareddefs.cpp b/game/shared/mp_shareddefs.cpp index f764540d..74be8a82 100644 --- a/game/shared/mp_shareddefs.cpp +++ b/game/shared/mp_shareddefs.cpp @@ -185,6 +185,10 @@ const char *g_pszMPConcepts[] = "TLK_MVM_LOOT_RARE", // MP_CONCEPT_MVM_LOOT_RARE "TLK_MVM_LOOT_ULTRARARE", // MP_CONCEPT_MVM_LOOT_ULTRARARE "TLK_MEDIC_HEAL_SHIELD", // MP_CONCEPT_MEDIC_HEAL_SHIELD + + "TLK_TAUNT_EUREKA_EFFECT", // MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT + + "TLK_COMBO_KILLED", // MP_CONCEPT_COMBO_KILLED }; COMPILE_TIME_ASSERT( ARRAYSIZE( g_pszMPConcepts ) == MP_TF_CONCEPT_COUNT ); diff --git a/game/shared/mp_shareddefs.h b/game/shared/mp_shareddefs.h index 0dc05d54..d8d613f6 100644 --- a/game/shared/mp_shareddefs.h +++ b/game/shared/mp_shareddefs.h @@ -195,6 +195,10 @@ enum MP_CONCEPT_MVM_LOOT_ULTRARARE, // "TLK_MVM_LOOT_ULTRARARE" MP_CONCEPT_MEDIC_HEAL_SHIELD, // "TLK_MEDIC_HEAL_SHIELD" + MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT,// "TLK_TAUNT_EUREKA_EFFECT" + + MP_CONCEPT_COMBO_KILLED, // "TLK_COMBO_KILLED" + MP_TF_CONCEPT_COUNT // Other MP_CONCEPT_* start he using MP_TF_CONCEPT_COUNT + 1 as start. diff --git a/game/shared/multiplay_gamerules.cpp b/game/shared/multiplay_gamerules.cpp index 760b94a4..a70b2a94 100644 --- a/game/shared/multiplay_gamerules.cpp +++ b/game/shared/multiplay_gamerules.cpp @@ -857,9 +857,9 @@ ConVarRef suitcharger( "sk_suitcharger" ); { killer_weapon_name += 7; } - else if ( strncmp( killer_weapon_name, "NPC_", 8 ) == 0 ) + else if ( strncmp( killer_weapon_name, "NPC_", 4 ) == 0 ) { - killer_weapon_name += 8; + killer_weapon_name += 4; } else if ( strncmp( killer_weapon_name, "func_", 5 ) == 0 ) { @@ -1149,14 +1149,17 @@ ConVarRef suitcharger( "sk_suitcharger" ); } } - void StripChar(char *szBuffer, const char cWhiteSpace ) + // Strip ' ' and '\n' characters from string. + static void StripWhitespaceChars( char *szBuffer ) { + char *szOut = szBuffer; - while ( char *pSpace = strchr( szBuffer, cWhiteSpace ) ) + for ( char *szIn = szOut; *szIn; szIn++ ) { - char *pNextChar = pSpace + sizeof(char); - V_strcpy( pSpace, pNextChar ); + if ( *szIn != ' ' && *szIn != '\r' ) + *szOut++ = *szIn; } + *szOut = '\0'; } void CMultiplayRules::GetNextLevelName( char *pszNextMap, int bufsize, bool bRandom /* = false */ ) @@ -1283,9 +1286,8 @@ ConVarRef suitcharger( "sk_suitcharger" ); { bool bIgnore = false; - // Strip out the spaces in the name - StripChar( mapList[i] , '\r'); - StripChar( mapList[i] , ' '); + // Strip out ' ' and '\r' chars. + StripWhitespaceChars( mapList[i] ); if ( !Q_strncmp( mapList[i], "//", 2 ) || mapList[i][0] == '\0' ) { diff --git a/game/shared/particle_parse.cpp b/game/shared/particle_parse.cpp index e3fc5b62..e4703936 100644 --- a/game/shared/particle_parse.cpp +++ b/game/shared/particle_parse.cpp @@ -309,7 +309,7 @@ void DispatchParticleEffect( const char *pszParticleName, ParticleAttachment_t i if ( ( data.m_fFlags & PARTICLE_DISPATCH_FROM_ENTITY ) != 0 && ( iAttachType == PATTACH_ABSORIGIN_FOLLOW || iAttachType == PATTACH_POINT_FOLLOW || iAttachType == PATTACH_ROOTBONE_FOLLOW ) ) { - CReliableBroadcastRecipientFilter filter; + CBroadcastRecipientFilter filter; DispatchEffect( "ParticleEffect", data, filter ); } else diff --git a/game/shared/particle_property.cpp b/game/shared/particle_property.cpp index 11ff29ac..83fca8ca 100644 --- a/game/shared/particle_property.cpp +++ b/game/shared/particle_property.cpp @@ -200,8 +200,23 @@ void CParticleProperty::AddControlPoint( int iEffectIndex, int iPoint, C_BaseEnt ParticleEffectList_t *pEffect = &m_ParticleEffects[iEffectIndex]; Assert( pEffect->pControlPoints.Count() < MAX_PARTICLE_CONTROL_POINTS ); - int iIndex = pEffect->pControlPoints.AddToTail(); - ParticleControlPoint_t *pNewPoint = &pEffect->pControlPoints[iIndex]; + // If the control point is already used, override it + ParticleControlPoint_t *pNewPoint = NULL; + int iIndex = iPoint; + FOR_EACH_VEC( pEffect->pControlPoints, i ) + { + if ( pEffect->pControlPoints[i].iControlPoint == iPoint ) + { + pNewPoint = &pEffect->pControlPoints[i]; + } + } + + if ( !pNewPoint ) + { + iIndex = pEffect->pControlPoints.AddToTail(); + pNewPoint = &pEffect->pControlPoints[iIndex]; + } + pNewPoint->iControlPoint = iPoint; pNewPoint->hEntity = pEntity; pNewPoint->iAttachType = iAttachType; @@ -350,7 +365,7 @@ void CParticleProperty::StopParticlesInvolving( CBaseEntity *pEntity ) // Purpose: Stop all effects that were created using the given definition // name. //----------------------------------------------------------------------------- -void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly /* =false */ ) +void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly /* =false */, bool bInverse /*= false*/ ) { CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName ); AssertMsg1(pDef, "Could not find particle definition %s", pszEffectName ); @@ -369,13 +384,15 @@ void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bFor { // for each effect... CNewParticleEffect *pParticleEffect = m_ParticleEffects[i].pParticleEffect.GetObject(); - if (pParticleEffect->m_pDef() == pDef) + bool bMatches = pParticleEffect->m_pDef() == pDef; + if ( bMatches == !bInverse ) { pParticleEffect->StopEmission( false, bRemoveInstantly ); } } } + void CParticleProperty::StopParticlesWithNameAndAttachment( const char *pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly /* =false */ ) { CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName ); @@ -547,13 +564,13 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i #ifdef TF_CLIENT_DLL CBaseEntity *pWearable = (CBaseEntity*) pPoint->hEntity.Get(); - if ( pWearable && dynamic_cast( pWearable ) && !pWearable->IsPlayer() ) + if ( pWearable && GetAttribInterface( pWearable ) && !pWearable->IsPlayer() ) { C_BaseAnimating *pAnimating = pPoint->hEntity->GetBaseAnimating(); if ( pAnimating ) { int bUseHeadOrigin = 0; - CALL_ATTRIB_HOOK_INT_ON_OTHER( pPoint->hEntity.Get(), bUseHeadOrigin, particle_effect_use_head_origin ); + CALL_ATTRIB_HOOK_INT_ON_OTHER( pAnimating, bUseHeadOrigin, particle_effect_use_head_origin ); if ( bUseHeadOrigin > 0 ) { int iBone = Studio_BoneIndexByName( pAnimating->GetModelPtr(), "bip_head" ); @@ -565,15 +582,17 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i iBone = Studio_BoneIndexByName( pAnimating->GetModelPtr(), "prp_hat" ); } } - if ( iBone >= 0 ) + if ( iBone < 0 ) { - bUsingHeadOrigin = true; - const matrix3x4_t headBone = pAnimating->GetBone( iBone ); - MatrixVectors( headBone, &vecForward, &vecRight, &vecUp ); - MatrixPosition( headBone, vecOrigin ); - - CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pPoint->hEntity.Get(), flOffset, particle_effect_vertical_offset ); + iBone = 0; } + + bUsingHeadOrigin = true; + const matrix3x4_t headBone = pAnimating->GetBone( iBone ); + MatrixVectors( headBone, &vecForward, &vecRight, &vecUp ); + MatrixPosition( headBone, vecOrigin ); + + CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pAnimating, flOffset, particle_effect_vertical_offset ); } } } diff --git a/game/shared/particle_property.h b/game/shared/particle_property.h index 441b73cc..f0185378 100644 --- a/game/shared/particle_property.h +++ b/game/shared/particle_property.h @@ -90,7 +90,7 @@ public: // kill all particle systems involving a given entity for their control points void StopParticlesInvolving( CBaseEntity *pEntity ); - void StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly = false ); ///< kills all particles using the given definition name + void StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly = false, bool bInverse = false ); ///< kills all particles using the given definition name void StopParticlesWithNameAndAttachment( const char *pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly = false ); ///< kills all particles using the given definition name // Particle System hooks diff --git a/game/shared/particlesystemquery.cpp b/game/shared/particlesystemquery.cpp index f6eeb258..77966994 100644 --- a/game/shared/particlesystemquery.cpp +++ b/game/shared/particlesystemquery.cpp @@ -231,7 +231,7 @@ void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox( { bSucesss = true; - Vector vecWorldPosition; + Vector vecWorldPosition(0, 0, 0); float u = 0, v = 0, w = 0; int nHitbox = 0; int nNumIters = nNumTrysToGetAPointInsideTheModel; @@ -308,7 +308,7 @@ void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox( - Vector vecWorldPosition; + Vector vecWorldPosition(0, 0, 0); float u = 0, v = 0, w = 0; int nHitbox = 0; int nNumIters = nNumTrysToGetAPointInsideTheModel; diff --git a/game/shared/predictioncopy.cpp b/game/shared/predictioncopy.cpp index 2855147a..13199705 100644 --- a/game/shared/predictioncopy.cpp +++ b/game/shared/predictioncopy.cpp @@ -514,7 +514,7 @@ void CPredictionCopy::DescribeQuaternion( difftype_t dt, Quaternion* outValue, c for ( int j = 0; j < 4; j++ ) { - delta[i] = outValue[i][j] - inValue[i][j]; + delta[j] = outValue[i][j] - inValue[i][j]; } ReportFieldsDiffer( "quaternion[] differs (1st diff) (net %f %f %f %f - pred %f %f %f %f) delta(%f %f %f %f)\n", @@ -933,7 +933,7 @@ CPredictionCopy::difftype_t CPredictionCopy::CompareQuaternion( Quaternion* outV for ( int j = 0; j < 4; j++ ) { - delta[i] = outValue[i][j] - inValue[i][j]; + delta[j] = outValue[i][j] - inValue[i][j]; } if ( tolerance > 0.0f ) diff --git a/game/shared/props_shared.cpp b/game/shared/props_shared.cpp index 107740a6..16cb19aa 100644 --- a/game/shared/props_shared.cpp +++ b/game/shared/props_shared.cpp @@ -600,6 +600,10 @@ public: pModel->mpBreakMode = MULTIPLAYER_BREAK_CLIENTSIDE; } } + else if ( !strcmpi( pKey, "velocity" ) ) + { + UTIL_StringToVector( pModel->velocity.Base(), pValue ); + } } virtual void SetDefaults( void *pData ) { @@ -617,6 +621,7 @@ public: pModel->placementName[0] = 0; pModel->placementIsBone = false; pModel->mpBreakMode = MULTIPLAYER_BREAK_DEFAULT; + pModel->velocity = vec3_origin; m_wroteCollisionGroup = false; } @@ -626,7 +631,7 @@ private: bool m_wroteCollisionGroup; }; -void BreakModelList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ) +void BuildPropList( const char *pszBlockName, CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ) { vcollide_t *pCollide = modelinfo->GetVCollide( modelindex ); if ( !pCollide ) @@ -638,7 +643,7 @@ void BreakModelList( CUtlVector &list, int modelindex, float defBu CBreakParser breakParser( defBurstScale, defCollisionGroup ); const char *pBlock = pParse->GetCurrentBlockName(); - if ( !strcmpi( pBlock, "break" ) ) + if ( !strcmpi( pBlock, pszBlockName ) ) { int index = list.AddToTail(); breakmodel_t &breakModel = list[index]; @@ -652,6 +657,11 @@ void BreakModelList( CUtlVector &list, int modelindex, float defBu physcollision->VPhysicsKeyParserDestroy( pParse ); } +void BreakModelList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ) +{ + BuildPropList( "break", list, modelindex, defBurstScale, defCollisionGroup ); +} + #if !defined(_STATIC_LINKED) || defined(CLIENT_DLL) int GetAutoMultiplayerPhysicsMode( Vector size, float mass ) { @@ -1226,9 +1236,8 @@ void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const Vec // Purpose: // Input : modelindex - //----------------------------------------------------------------------------- -void PrecacheGibsForModel( int iModel ) +void PrecachePropsForModel( int iModel, const char *pszBlockName ) { - VPROF_BUDGET( "PrecacheGibsForModel", VPROF_BUDGETGROUP_PLAYER ); vcollide_t *pCollide = modelinfo->GetVCollide( iModel ); if ( !pCollide ) return; @@ -1241,7 +1250,7 @@ void PrecacheGibsForModel( int iModel ) while ( !pParse->Finished() ) { const char *pBlock = pParse->GetCurrentBlockName(); - if ( !strcmpi( pBlock, "break" ) ) + if ( !strcmpi( pBlock, pszBlockName ) ) { breakmodel_t breakModel; pParse->ParseCustom( &breakModel, &breakParser ); @@ -1257,6 +1266,12 @@ void PrecacheGibsForModel( int iModel ) physcollision->VPhysicsKeyParserDestroy( pParse ); } +void PrecacheGibsForModel( int iModel ) +{ + VPROF_BUDGET( "PrecacheGibsForModel", VPROF_BUDGETGROUP_PLAYER ); + PrecachePropsForModel( iModel, "break" ); +} + //----------------------------------------------------------------------------- // Purpose: // Input : &list - @@ -1448,12 +1463,21 @@ CBaseEntity *CreateGibsFromList( CUtlVector &list, int modelindex, } Vector objectVelocity = params.velocity; - float flScale = VectorNormalize( objectVelocity ); - objectVelocity.x += RandomFloat( -1.f, 1.0f ); - objectVelocity.y += RandomFloat( -1.0f, 1.0f ); - objectVelocity.z += RandomFloat( 0.0f, 1.0f ); - VectorNormalize( objectVelocity ); - objectVelocity *= flScale; + Vector gibVelocity = vec3_origin; + if ( !list[i].velocity.IsZero() ) + { + VectorRotate( list[i].velocity, matrix, gibVelocity ); + objectVelocity = gibVelocity; + } + else + { + float flScale = VectorNormalize( objectVelocity ); + objectVelocity.x += RandomFloat( -1.f, 1.0f ); + objectVelocity.y += RandomFloat( -1.0f, 1.0f ); + objectVelocity.z += RandomFloat( 0.0f, 1.0f ); + VectorNormalize( objectVelocity ); + objectVelocity *= flScale; + } if (pPhysics) { diff --git a/game/shared/props_shared.h b/game/shared/props_shared.h index 7377b178..4063e171 100644 --- a/game/shared/props_shared.h +++ b/game/shared/props_shared.h @@ -217,6 +217,7 @@ struct breakmodel_t bool placementIsBone; bool isMotionDisabled; mp_break_t mpBreakMode; + Vector velocity; }; struct breakablepropparams_t @@ -242,11 +243,13 @@ struct breakablepropparams_t const char *GetMassEquivalent(float flMass); int GetAutoMultiplayerPhysicsMode( Vector size, float mass ); +void BuildPropList( const char *pszBlockName, CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ); void BreakModelList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ); void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t ¶ms, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true ); void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const Vector &origin, const QAngle &angles, const Vector &velocity, const AngularImpulse &angularVelocity, float impactEnergyScale, float burstScale, int collisionGroup, CBaseEntity *pEntity = NULL, bool defaultLocation = true ); // Player gibs. +void PrecachePropsForModel( int iModel, const char *pszBlockName ); void PrecacheGibsForModel( int iModel ); void BuildGibList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ); CBaseEntity *CreateGibsFromList( CUtlVector &list, int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t ¶ms, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true, CUtlVector *pGibList = NULL, bool bBurning = false ); diff --git a/game/shared/sceneimage.cpp b/game/shared/sceneimage.cpp index 66d5e37d..e8c36ce1 100644 --- a/game/shared/sceneimage.cpp +++ b/game/shared/sceneimage.cpp @@ -368,7 +368,7 @@ bool CSceneImage::CreateSceneImageFile( CUtlBuffer &targetBuffer, char const *pc if ( !bQuiet ) { - Msg( "Scenes: String Table: %d bytes\n", stringOffsets.Count() * sizeof( int ) ); + Msg( "Scenes: String Table: %llu bytes\n", (uint64)(stringOffsets.Count() * sizeof( int )) ); Msg( "Scenes: String Pool: %d bytes\n", stringPool.TellMaxPut() ); } diff --git a/game/shared/shareddefs.h b/game/shared/shareddefs.h index 3d8a97db..2b7729cd 100644 --- a/game/shared/shareddefs.h +++ b/game/shared/shareddefs.h @@ -140,7 +140,7 @@ typedef enum VOTE_FAILED_ISSUE_DISABLED, VOTE_FAILED_MAP_NOT_FOUND, VOTE_FAILED_MAP_NAME_REQUIRED, - VOTE_FAILED_FAILED_RECENTLY, + VOTE_FAILED_ON_COOLDOWN, VOTE_FAILED_TEAM_CANT_CALL, VOTE_FAILED_WAITINGFORPLAYERS, VOTE_FAILED_PLAYERNOTFOUND, diff --git a/game/shared/takedamageinfo.h b/game/shared/takedamageinfo.h index e149922e..ebcaba64 100644 --- a/game/shared/takedamageinfo.h +++ b/game/shared/takedamageinfo.h @@ -55,7 +55,8 @@ public: void AddDamage( float flAddAmount ); void SubtractDamage( float flSubtractAmount ); float GetDamageBonus() const; - void SetDamageBonus( float flBonus ); + CBaseEntity *GetDamageBonusProvider() const; + void SetDamageBonus( float flBonus, CBaseEntity *pProvider = NULL ); float GetBaseDamage() const; bool BaseDamageIsValid() const; @@ -125,6 +126,7 @@ protected: int m_iDamagedOtherPlayers; int m_iPlayerPenetrationCount; float m_flDamageBonus; // Anything that increases damage (crit) - store the delta + EHANDLE m_hDamageBonusProvider; // Who gave us the ability to do extra damage? bool m_bForceFriendlyFire; // Ideally this would be a dmg type, but we can't add more DECLARE_SIMPLE_DATADESC(); @@ -247,9 +249,15 @@ inline float CTakeDamageInfo::GetDamageBonus() const return m_flDamageBonus; } -inline void CTakeDamageInfo::SetDamageBonus( float flBonus ) +inline CBaseEntity *CTakeDamageInfo::GetDamageBonusProvider() const +{ + return m_hDamageBonusProvider; +} + +inline void CTakeDamageInfo::SetDamageBonus( float flBonus, CBaseEntity *pProvider /*= NULL*/ ) { m_flDamageBonus = flBonus; + m_hDamageBonusProvider = pProvider; } inline float CTakeDamageInfo::GetBaseDamage() const diff --git a/game/shared/teamplay_round_timer.cpp b/game/shared/teamplay_round_timer.cpp index f786f73e..413cf9a9 100644 --- a/game/shared/teamplay_round_timer.cpp +++ b/game/shared/teamplay_round_timer.cpp @@ -245,6 +245,7 @@ CTeamRoundTimer::CTeamRoundTimer( void ) m_bResetTimeOnRoundStart = false; m_nTimeToUseAfterSetupFinished = 0; m_flNextOvertimeNag = 0; + m_flLastTime = 0.f; #endif } @@ -781,6 +782,9 @@ void CTeamRoundTimer::SetTimerThink( int nType ) //----------------------------------------------------------------------------- void CTeamRoundTimer::RoundTimerSetupThink( void ) { + float flLastTime = m_flLastTime; + m_flLastTime = GetTimeRemaining(); + if ( TeamplayRoundBasedRules()->IsInPreMatch() == true && IsDisabled() == false ) { inputdata_t data; @@ -797,6 +801,22 @@ void CTeamRoundTimer::RoundTimerSetupThink( void ) float flTime = GetTimeRemaining(); TeamplayRoundBasedRules()->SetOvertime( false ); + if ( m_flLastTime > 0.f ) + { + int nLastSecond = floor( flLastTime ); + int nThisSecond = floor( flTime ); + + if ( nLastSecond != nThisSecond ) + { + IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_pre_round_time_left" ); + if ( event ) + { + event->SetInt( "time", nThisSecond ); + gameeventmanager->FireEvent( event ); + } + } + } + if ( flTime <= 0.0f && m_bFireFinished ) { IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_setup_finished" ); @@ -1291,14 +1311,14 @@ void CTeamRoundTimer::InputAddTeamTime( inputdata_t &input ) // get the team p = nexttoken( token, p, ' ' ); - if ( token ) + if ( token[0] ) { nTeam = Q_atoi( token ); } // get the time p = nexttoken( token, p, ' ' ); - if ( token ) + if ( token[0] ) { nSeconds = Q_atoi( token ); } diff --git a/game/shared/teamplay_round_timer.h b/game/shared/teamplay_round_timer.h index 470a5f16..dbf7566b 100644 --- a/game/shared/teamplay_round_timer.h +++ b/game/shared/teamplay_round_timer.h @@ -158,6 +158,7 @@ private: COutputEvent m_OnSetupFinished; float m_flNextOvertimeNag; + float m_flLastTime; DECLARE_DATADESC(); diff --git a/game/shared/teamplayroundbased_gamerules.cpp b/game/shared/teamplayroundbased_gamerules.cpp index f565f3e7..2f9d46d2 100644 --- a/game/shared/teamplayroundbased_gamerules.cpp +++ b/game/shared/teamplayroundbased_gamerules.cpp @@ -90,6 +90,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CTeamplayRoundBasedRules, DT_TeamplayRoundBasedRules RecvPropBool( RECVINFO( m_bStopWatch ) ), RecvPropBool( RECVINFO( m_bMultipleTrains ) ), RecvPropArray3( RECVINFO_ARRAY(m_bPlayerReady), RecvPropBool( RECVINFO(m_bPlayerReady[0]) ) ), + RecvPropBool( RECVINFO( m_bCheatsEnabledDuringLevel ) ), #else SendPropInt( SENDINFO( m_iRoundState ), 5 ), @@ -107,6 +108,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CTeamplayRoundBasedRules, DT_TeamplayRoundBasedRules SendPropBool( SENDINFO( m_bStopWatch ) ), SendPropBool( SENDINFO( m_bMultipleTrains ) ), SendPropArray3( SENDINFO_ARRAY3(m_bPlayerReady), SendPropBool( SENDINFO_ARRAY(m_bPlayerReady) ) ), + SendPropBool( SENDINFO( m_bCheatsEnabledDuringLevel ) ), #endif END_NETWORK_TABLE() @@ -184,7 +186,7 @@ ConVar tf_arena_round_time( "tf_arena_round_time", "0", FCVAR_NOTIFY | FCVAR_REP ConVar tf_arena_max_streak( "tf_arena_max_streak", "3", FCVAR_NOTIFY | FCVAR_REPLICATED, "Teams will be scrambled if one team reaches this streak" ); ConVar tf_arena_use_queue( "tf_arena_use_queue", "1", FCVAR_REPLICATED | FCVAR_NOTIFY, "Enables the spectator queue system for Arena." ); -ConVar mp_teams_unbalance_limit( "mp_teams_unbalance_limit", "1", FCVAR_REPLICATED | FCVAR_NOTIFY, +ConVar mp_teams_unbalance_limit( "mp_teams_unbalance_limit", "1", FCVAR_REPLICATED, "Teams are unbalanced when one team has this many more players than the other team. (0 disables check)", true, 0, // min value true, 30 // max value @@ -421,6 +423,7 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void ) m_nAutoBalanceQueuePlayerScore = -1; SetDefLessFunc( m_GameTeams ); + m_bCheatsEnabledDuringLevel = false; #endif } @@ -551,6 +554,18 @@ float CTeamplayRoundBasedRules::GetMinTimeWhenPlayerMaySpawn( CBasePlayer *pPlay return pPlayer->GetDeathTime() + fMinDelay; } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTeamplayRoundBasedRules::LevelInitPostEntity( void ) +{ + BaseClass::LevelInitPostEntity(); + +#ifdef GAME_DLL + m_bCheatsEnabledDuringLevel = sv_cheats && sv_cheats->GetBool(); +#endif // GAME_DLL +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -631,6 +646,12 @@ void CTeamplayRoundBasedRules::Think( void ) m_flNextPeriodicThink = gpGlobals->curtime + 1.0; } + // Watch dog for cheats ever being enabled during a level + if ( !m_bCheatsEnabledDuringLevel && sv_cheats && sv_cheats->GetBool() ) + { + m_bCheatsEnabledDuringLevel = true; + } + // Bypass teamplay think. CGameRules::Think(); } @@ -954,7 +975,11 @@ void CTeamplayRoundBasedRules::CheckRestartRound( void ) int iDelayMax = 60; #if defined(TF_CLIENT_DLL) || defined(TF_DLL) +#ifdef STAGING_ONLY + if ( TFGameRules() && ( TFGameRules()->IsMannVsMachineMode() || TFGameRules()->IsRatedTournamentMode() ) ) +#else if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) +#endif // STAGING_ONLY { iDelayMax = 180; } @@ -1415,6 +1440,12 @@ void CTeamplayRoundBasedRules::State_Enter_PREROUND( void ) State_Transition( GR_STATE_BETWEEN_RNDS ); TFObjectiveResource()->SetMannVsMachineBetweenWaves( true ); } +#ifdef STAGING_ONLY + else if ( TFGameRules() && TFGameRules()->IsRatedTournamentMode() ) + { + State_Transition( GR_STATE_BETWEEN_RNDS ); + } +#endif // STAGING_ONLY #endif // #if defined(TF_CLIENT_DLL) || defined(TF_DLL) else { @@ -1501,14 +1532,23 @@ void CTeamplayRoundBasedRules::CheckReadyRestart( void ) m_flRestartRoundTime = -1; #ifdef TF_DLL - if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager ) + if ( TFGameRules() ) { - if ( TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() ) + if ( TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager ) { - g_pPopulationManager->StartCurrentWave(); + if ( TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() ) + { + g_pPopulationManager->StartCurrentWave(); + return; + } } - - return; +#ifdef STAGING_ONLY + else if ( TFGameRules()->IsRatedTournamentMode() ) + { + TFGameRules()->StartRatedTournamentMatch(); + return; + } +#endif // STAGING_ONLY } #endif // TF_DLL @@ -1703,6 +1743,19 @@ void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void ) InternalHandleTeamWin( m_iWinningTeam ); SendWinPanelInfo(); + +#ifdef STAGING_ONLY +#ifdef TF_DLL + if ( TFGameRules() && TFGameRules()->IsRatedTournamentMode() ) + { + // Do this now, so players don't leave before the usual CheckWinLimit() call happens + if ( CheckWinLimit() ) + { + TFGameRules()->SkillRating_CalculateAdjustmentForTeams( m_iWinningTeam ); + } + } +#endif // TF_DLL +#endif // STAGING_ONLY } //----------------------------------------------------------------------------- @@ -1710,8 +1763,16 @@ void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void ) //----------------------------------------------------------------------------- void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void ) { - if( gpGlobals->curtime > m_flStateTransitionTime ) + if ( gpGlobals->curtime > m_flStateTransitionTime ) { +#ifdef TF_DLL + IGameEvent *event = gameeventmanager->CreateEvent( "scorestats_accumulated_update" ); + if ( event ) + { + gameeventmanager->FireEvent( event ); + } +#endif // TF_DLL + bool bDone = !(!CheckTimeLimit() && !CheckWinLimit() && !CheckMaxRounds() && !CheckNextLevelCvar()); // check the win limit, max rounds, time limit and nextlevel cvar before starting the next round @@ -2632,6 +2693,10 @@ void CTeamplayRoundBasedRules::RoundRespawn( void ) } #endif + // Free any edicts that were marked deleted. This should hopefully clear some out + // so the below function can use the now freed ones. + engine->AllowImmediateEdictReuse(); + RespawnPlayers( true ); // reset per-round scores for each player @@ -3020,6 +3085,14 @@ void CTeamplayRoundBasedRules::ResetScores( void ) m_bResetPlayerScores = true; m_bResetRoundsPlayed = true; //m_flStopWatchTime = -1.0f; + +#ifdef TF_DLL + IGameEvent *event = gameeventmanager->CreateEvent( "scorestats_accumulated_reset" ); + if ( event ) + { + gameeventmanager->FireEvent( event ); + } +#endif // TF_DLL } //----------------------------------------------------------------------------- diff --git a/game/shared/teamplayroundbased_gamerules.h b/game/shared/teamplayroundbased_gamerules.h index f878260b..9f4c0519 100644 --- a/game/shared/teamplayroundbased_gamerules.h +++ b/game/shared/teamplayroundbased_gamerules.h @@ -88,6 +88,11 @@ enum { WINREASON_TIMELIMIT, WINREASON_WINLIMIT, WINREASON_WINDIFFLIMIT, +#if defined(TF_CLIENT_DLL) || defined(TF_DLL) + WINREASON_RD_REACTOR_CAPTURED, + WINREASON_RD_CORES_COLLECTED, + WINREASON_RD_REACTOR_RETURNED, +#endif }; enum stalemate_reasons_t @@ -183,6 +188,7 @@ public: virtual float GetNextRespawnWave( int iTeam, CBasePlayer *pPlayer ); virtual bool HasPassedMinRespawnTime( CBasePlayer *pPlayer ); + virtual void LevelInitPostEntity( void ); virtual float GetRespawnTimeScalar( int iTeam ); virtual float GetRespawnWaveMaxLength( int iTeam, bool bScaleWithNumPlayers = true ); virtual bool ShouldRespawnQuickly( CBasePlayer *pPlayer ) { return false; } @@ -541,6 +547,7 @@ private: public: bool WouldChangeUnbalanceTeams( int iNewTeam, int iCurrentTeam ); bool AreTeamsUnbalanced( int &iHeaviestTeam, int &iLightestTeam ); + virtual bool HaveCheatsBeenEnabledDuringLevel( void ) { return m_bCheatsEnabledDuringLevel; } protected: CNetworkVar( gamerules_roundstate_t, m_iRoundState ); @@ -557,10 +564,11 @@ protected: CNetworkVar( float, m_flMapResetTime ); // Time that the map was reset CNetworkArray( float, m_flNextRespawnWave, MAX_TEAMS ); // Minor waste, but cleaner code CNetworkArray( bool, m_bTeamReady, MAX_TEAMS ); - CNetworkVar( bool, m_bStopWatch ); - CNetworkVar( bool, m_bMultipleTrains ); // two trains in this map? + CNetworkVar( bool, m_bStopWatch ); + CNetworkVar( bool, m_bMultipleTrains ); // two trains in this map? CNetworkArray( bool, m_bPlayerReady, MAX_PLAYERS ); - + CNetworkVar( bool, m_bCheatsEnabledDuringLevel ); + public: CNetworkArray( float, m_TeamRespawnWaveTimes, MAX_TEAMS ); // Time between each team's respawn wave diff --git a/game/shared/voice_gamemgr.cpp b/game/shared/voice_gamemgr.cpp index 31da0dae..c06ed17b 100644 --- a/game/shared/voice_gamemgr.cpp +++ b/game/shared/voice_gamemgr.cpp @@ -48,6 +48,7 @@ CVoiceGameMgr g_VoiceGameMgr; // ------------------------------------------------------------------------ // // Find a player with a case-insensitive name search. +#if 0 static CBasePlayer* FindPlayerByName(const char *pTestName) { for(int i=1; i <= gpGlobals->maxClients; i++) @@ -69,6 +70,7 @@ static CBasePlayer* FindPlayerByName(const char *pTestName) return NULL; } +#endif static void VoiceServerDebug( const char *pFmt, ... ) { diff --git a/lib/public/appframework.lib b/lib/public/appframework.lib index 91edb5ab..99b139fb 100644 Binary files a/lib/public/appframework.lib and b/lib/public/appframework.lib differ diff --git a/lib/public/bitmap.lib b/lib/public/bitmap.lib index a7b09953..8c26ea0c 100644 Binary files a/lib/public/bitmap.lib and b/lib/public/bitmap.lib differ diff --git a/lib/public/choreoobjects.lib b/lib/public/choreoobjects.lib index 7aaab186..b3d18d06 100644 Binary files a/lib/public/choreoobjects.lib and b/lib/public/choreoobjects.lib differ diff --git a/lib/public/dmxloader.lib b/lib/public/dmxloader.lib index fa36c08d..c2ca709a 100644 Binary files a/lib/public/dmxloader.lib and b/lib/public/dmxloader.lib differ diff --git a/lib/public/fgdlib.lib b/lib/public/fgdlib.lib index e2127279..29e44c49 100644 Binary files a/lib/public/fgdlib.lib and b/lib/public/fgdlib.lib differ diff --git a/lib/public/libz.lib b/lib/public/libz.lib index 41afc354..6f69f170 100644 Binary files a/lib/public/libz.lib and b/lib/public/libz.lib differ diff --git a/lib/public/linux32/bitmap.a b/lib/public/linux32/bitmap.a index 82ae893c..c08b921f 100644 Binary files a/lib/public/linux32/bitmap.a and b/lib/public/linux32/bitmap.a differ diff --git a/lib/public/linux32/choreoobjects.a b/lib/public/linux32/choreoobjects.a index 91d9c90c..322c6341 100644 Binary files a/lib/public/linux32/choreoobjects.a and b/lib/public/linux32/choreoobjects.a differ diff --git a/lib/public/linux32/dmxloader.a b/lib/public/linux32/dmxloader.a index 889405c9..34fc5797 100644 Binary files a/lib/public/linux32/dmxloader.a and b/lib/public/linux32/dmxloader.a differ diff --git a/lib/public/linux32/libSDL2-2.0.so.0 b/lib/public/linux32/libSDL2-2.0.so.0 index 4cb32b6a..4e8ca343 100644 Binary files a/lib/public/linux32/libSDL2-2.0.so.0 and b/lib/public/linux32/libSDL2-2.0.so.0 differ diff --git a/lib/public/linux32/libsteam_api.so b/lib/public/linux32/libsteam_api.so index 6238c83e..cb4ee649 100644 Binary files a/lib/public/linux32/libsteam_api.so and b/lib/public/linux32/libsteam_api.so differ diff --git a/lib/public/linux32/libtier0.so b/lib/public/linux32/libtier0.so index 574e0a88..3de9e585 100644 Binary files a/lib/public/linux32/libtier0.so and b/lib/public/linux32/libtier0.so differ diff --git a/lib/public/linux32/libvstdlib.so b/lib/public/linux32/libvstdlib.so index 0a460bb5..d1cd4453 100644 Binary files a/lib/public/linux32/libvstdlib.so and b/lib/public/linux32/libvstdlib.so differ diff --git a/lib/public/linux32/matsys_controls.a b/lib/public/linux32/matsys_controls.a index 9ae25dd0..9b769f99 100644 Binary files a/lib/public/linux32/matsys_controls.a and b/lib/public/linux32/matsys_controls.a differ diff --git a/lib/public/linux32/particles.a b/lib/public/linux32/particles.a index 6d1a8f91..aab4a4ec 100644 Binary files a/lib/public/linux32/particles.a and b/lib/public/linux32/particles.a differ diff --git a/lib/public/linux32/shaderlib.a b/lib/public/linux32/shaderlib.a index 327f13be..9e9dad9b 100644 Binary files a/lib/public/linux32/shaderlib.a and b/lib/public/linux32/shaderlib.a differ diff --git a/lib/public/linux32/tier2.a b/lib/public/linux32/tier2.a index 1ac5c0c5..69f52a3b 100644 Binary files a/lib/public/linux32/tier2.a and b/lib/public/linux32/tier2.a differ diff --git a/lib/public/linux32/tier3.a b/lib/public/linux32/tier3.a index 9bc1bf1f..3777a2cf 100644 Binary files a/lib/public/linux32/tier3.a and b/lib/public/linux32/tier3.a differ diff --git a/lib/public/linux32/vtf.a b/lib/public/linux32/vtf.a index 30858deb..1a085f0d 100644 Binary files a/lib/public/linux32/vtf.a and b/lib/public/linux32/vtf.a differ diff --git a/lib/public/mathlib.lib b/lib/public/mathlib.lib index b87ad33d..09a025cf 100644 Binary files a/lib/public/mathlib.lib and b/lib/public/mathlib.lib differ diff --git a/lib/public/matsys_controls.lib b/lib/public/matsys_controls.lib index 6663600a..e37e25a4 100644 Binary files a/lib/public/matsys_controls.lib and b/lib/public/matsys_controls.lib differ diff --git a/lib/public/nvtristrip.lib b/lib/public/nvtristrip.lib index ed2478a8..59c948fa 100644 Binary files a/lib/public/nvtristrip.lib and b/lib/public/nvtristrip.lib differ diff --git a/lib/public/osx32/bitmap.a b/lib/public/osx32/bitmap.a index ffc0a58c..2841ae0a 100644 Binary files a/lib/public/osx32/bitmap.a and b/lib/public/osx32/bitmap.a differ diff --git a/lib/public/osx32/choreoobjects.a b/lib/public/osx32/choreoobjects.a index 58fb4a96..a69eed34 100644 Binary files a/lib/public/osx32/choreoobjects.a and b/lib/public/osx32/choreoobjects.a differ diff --git a/lib/public/osx32/dmxloader.a b/lib/public/osx32/dmxloader.a index 53748abc..3d3496a5 100644 Binary files a/lib/public/osx32/dmxloader.a and b/lib/public/osx32/dmxloader.a differ diff --git a/lib/public/osx32/libSDL2-2.0.0.dylib b/lib/public/osx32/libSDL2-2.0.0.dylib index c8dcd704..45278b23 100644 Binary files a/lib/public/osx32/libSDL2-2.0.0.dylib and b/lib/public/osx32/libSDL2-2.0.0.dylib differ diff --git a/lib/public/osx32/libsteam_api.dylib b/lib/public/osx32/libsteam_api.dylib index 3eed40fe..80dc4752 100644 Binary files a/lib/public/osx32/libsteam_api.dylib and b/lib/public/osx32/libsteam_api.dylib differ diff --git a/lib/public/osx32/libtier0.dylib b/lib/public/osx32/libtier0.dylib index b56e4889..ccc08ecf 100644 Binary files a/lib/public/osx32/libtier0.dylib and b/lib/public/osx32/libtier0.dylib differ diff --git a/lib/public/osx32/libvstdlib.dylib b/lib/public/osx32/libvstdlib.dylib index fcd2a9f7..abcccb4e 100644 Binary files a/lib/public/osx32/libvstdlib.dylib and b/lib/public/osx32/libvstdlib.dylib differ diff --git a/lib/public/osx32/matsys_controls.a b/lib/public/osx32/matsys_controls.a index 26d42570..70b91aba 100644 Binary files a/lib/public/osx32/matsys_controls.a and b/lib/public/osx32/matsys_controls.a differ diff --git a/lib/public/osx32/particles.a b/lib/public/osx32/particles.a index 3745aab4..4ba2a91a 100644 Binary files a/lib/public/osx32/particles.a and b/lib/public/osx32/particles.a differ diff --git a/lib/public/osx32/shaderlib.a b/lib/public/osx32/shaderlib.a index a9507a01..ee0d2a1c 100644 Binary files a/lib/public/osx32/shaderlib.a and b/lib/public/osx32/shaderlib.a differ diff --git a/lib/public/osx32/tier1.a b/lib/public/osx32/tier1.a index 2f78704c..81093003 100644 Binary files a/lib/public/osx32/tier1.a and b/lib/public/osx32/tier1.a differ diff --git a/lib/public/osx32/tier2.a b/lib/public/osx32/tier2.a index ccbbb325..538e7fd7 100644 Binary files a/lib/public/osx32/tier2.a and b/lib/public/osx32/tier2.a differ diff --git a/lib/public/osx32/tier3.a b/lib/public/osx32/tier3.a index a3a76ccd..77558463 100644 Binary files a/lib/public/osx32/tier3.a and b/lib/public/osx32/tier3.a differ diff --git a/lib/public/osx32/vtf.a b/lib/public/osx32/vtf.a index 74130122..65b29f05 100644 Binary files a/lib/public/osx32/vtf.a and b/lib/public/osx32/vtf.a differ diff --git a/lib/public/particles.lib b/lib/public/particles.lib index 2e6f9359..aebb8da9 100644 Binary files a/lib/public/particles.lib and b/lib/public/particles.lib differ diff --git a/lib/public/raytrace.lib b/lib/public/raytrace.lib index 507ced28..eb389a29 100644 Binary files a/lib/public/raytrace.lib and b/lib/public/raytrace.lib differ diff --git a/lib/public/shaderlib.lib b/lib/public/shaderlib.lib index ee4b05f6..2ae660a4 100644 Binary files a/lib/public/shaderlib.lib and b/lib/public/shaderlib.lib differ diff --git a/lib/public/steam_api.lib b/lib/public/steam_api.lib index 2d77e960..3b9c60b6 100644 Binary files a/lib/public/steam_api.lib and b/lib/public/steam_api.lib differ diff --git a/lib/public/tier0.lib b/lib/public/tier0.lib index 4b3b77d5..f95b5dc1 100644 Binary files a/lib/public/tier0.lib and b/lib/public/tier0.lib differ diff --git a/lib/public/tier1.lib b/lib/public/tier1.lib index 26e720b5..c795b838 100644 Binary files a/lib/public/tier1.lib and b/lib/public/tier1.lib differ diff --git a/lib/public/tier2.lib b/lib/public/tier2.lib index b7cfafbb..8173cb5b 100644 Binary files a/lib/public/tier2.lib and b/lib/public/tier2.lib differ diff --git a/lib/public/tier3.lib b/lib/public/tier3.lib index ecf4544c..b0e04004 100644 Binary files a/lib/public/tier3.lib and b/lib/public/tier3.lib differ diff --git a/lib/public/vgui_controls.lib b/lib/public/vgui_controls.lib index c216271e..071e6220 100644 Binary files a/lib/public/vgui_controls.lib and b/lib/public/vgui_controls.lib differ diff --git a/lib/public/vmpi.lib b/lib/public/vmpi.lib index e9012f2f..d620dc24 100644 Binary files a/lib/public/vmpi.lib and b/lib/public/vmpi.lib differ diff --git a/lib/public/vstdlib.lib b/lib/public/vstdlib.lib index f0789a8d..6709dabe 100644 Binary files a/lib/public/vstdlib.lib and b/lib/public/vstdlib.lib differ diff --git a/lib/public/vtf.lib b/lib/public/vtf.lib index c7bf352c..f2359f9b 100644 Binary files a/lib/public/vtf.lib and b/lib/public/vtf.lib differ diff --git a/materialsystem/stdshaders/BaseVSShader.cpp b/materialsystem/stdshaders/BaseVSShader.cpp index ba1f6e15..2761c3ea 100644 --- a/materialsystem/stdshaders/BaseVSShader.cpp +++ b/materialsystem/stdshaders/BaseVSShader.cpp @@ -852,14 +852,14 @@ void CBaseVSShader::SetHWMorphVertexShaderState( int nDimConst, int nSubrectCons s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR ); int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT ); - float pMorphAccumSize[4] = { nMorphWidth, nMorphHeight, nDim, 0.0f }; + float pMorphAccumSize[4] = { (float)nMorphWidth, (float)nMorphHeight, (float)nDim, 0.0f }; s_pShaderAPI->SetVertexShaderConstant( nDimConst, pMorphAccumSize ); int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET ); int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET ); int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH ); int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT ); - float pMorphAccumSubrect[4] = { nXOffset, nYOffset, nWidth, nHeight }; + float pMorphAccumSubrect[4] = { (float)nXOffset, (float)nYOffset, (float)nWidth, (float)nHeight }; s_pShaderAPI->SetVertexShaderConstant( nSubrectConst, pMorphAccumSubrect ); s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR ); diff --git a/materialsystem/stdshaders/debugluxel.cpp b/materialsystem/stdshaders/debugluxel.cpp index fa734599..3f509e6b 100644 --- a/materialsystem/stdshaders/debugluxel.cpp +++ b/materialsystem/stdshaders/debugluxel.cpp @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -6,18 +6,11 @@ // $NoKeywords: $ //===========================================================================// -#include "shaderlib/cshader.h" - -#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. - -#ifdef USE_NEW_SHADER - -#include "unlitgeneric_vs20.inc" -#include "unlitgeneric_ps20.inc" -#include "unlitgeneric_ps20b.inc" - -#endif +#include "shaderlib/CShader.h" +#include "debugluxel_ps20b.inc" +#include "debugluxel_ps20.inc" +#include "debugluxel_vs20.inc" // memdbgon must be the last include file in a .cpp file!!! @@ -34,107 +27,71 @@ BEGIN_SHADER_FLAGS( DebugLuxels, "Help for DebugLuxels", SHADER_NOT_EDITABLE ) SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); -#ifdef USE_NEW_SHADER if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) { SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); } -#endif -} - -SHADER_INIT -{ - LoadTexture( BASETEXTURE ); -} - -SHADER_DRAW -{ - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - if (IS_FLAG_SET(MATERIAL_VAR_TRANSLUCENT)) - { - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - - if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); - else - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); -#ifdef USE_NEW_SHADER - if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) - { - bool bVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); - - DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bVertexColor ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); - SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); - SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); - } - } -#endif } - DYNAMIC_STATE + + SHADER_INIT { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + LoadTexture( BASETEXTURE ); + } - int texCoordScaleX = 1, texCoordScaleY = 1; - if (!params[NOSCALE]->GetIntValue()) + SHADER_DRAW + { + SHADOW_STATE { - pShaderAPI->GetLightmapDimensions( &texCoordScaleX, &texCoordScaleY ); - } + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); -#ifdef USE_NEW_SHADER - if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) - { - float vVertexColor[4] = { IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) ? 1.0f : 0.0f, 0.0f, 0.0f, 0.0f }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vVertexColor, 1 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + DECLARE_STATIC_VERTEX_SHADER( debugluxel_vs20 ); + SET_STATIC_VERTEX_SHADER( debugluxel_vs20 ); if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { - DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + DECLARE_STATIC_PIXEL_SHADER( debugluxel_ps20b ); + SET_STATIC_PIXEL_SHADER( debugluxel_ps20b ); } else { - DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + DECLARE_STATIC_PIXEL_SHADER( debugluxel_ps20 ); + SET_STATIC_PIXEL_SHADER( debugluxel_ps20 ); + } + + SetDefaultBlendingShadowState( BASETEXTURE ); + DisableFog(); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, NULL, 0 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + int texCoordScaleX = 1, texCoordScaleY = 1; + if (!params[NOSCALE]->GetIntValue()) + { + pShaderAPI->GetLightmapDimensions( &texCoordScaleX, &texCoordScaleY ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( debugluxel_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( debugluxel_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugluxel_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( debugluxel_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugluxel_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( debugluxel_ps20 ); } //texture scale transform Vector4D transformation[2]; - transformation[0].Init( (float)texCoordScaleX, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, (float)texCoordScaleY, 0.0f, 0.0f ); + transformation[0].Init( texCoordScaleX, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, texCoordScaleY, 0.0f, 0.0f ); s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, transformation[0].Base(), 2 ); } - else -#endif - { - if (!params[NOSCALE]->GetIntValue()) - { - pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); - pShaderAPI->LoadIdentity( ); - pShaderAPI->ScaleXY( texCoordScaleX, texCoordScaleY ); - } - } + Draw(); } - Draw(); -} END_SHADER diff --git a/materialsystem/stdshaders/eye_refract_helper.cpp b/materialsystem/stdshaders/eye_refract_helper.cpp index 6d819956..2f4bdf80 100644 --- a/materialsystem/stdshaders/eye_refract_helper.cpp +++ b/materialsystem/stdshaders/eye_refract_helper.cpp @@ -288,7 +288,7 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); @@ -302,7 +302,7 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); diff --git a/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp b/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp index 96873f3e..9b37ee90 100644 --- a/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp +++ b/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp @@ -421,7 +421,7 @@ static void DrawUsingVertexShader( bool bDX9, CBaseVSShader *pShader, IMaterialV SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER( eyes_vs20 ); @@ -435,7 +435,7 @@ static void DrawUsingVertexShader( bool bDX9, CBaseVSShader *pShader, IMaterialV SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( eyes_vs30 ); diff --git a/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp b/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp index 8905d7a0..95c200cb 100644 --- a/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp +++ b/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp @@ -228,7 +228,7 @@ void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); diff --git a/materialsystem/stdshaders/sky_hdr_dx9.cpp b/materialsystem/stdshaders/sky_hdr_dx9.cpp index 9bb929d1..8bc44f74 100644 --- a/materialsystem/stdshaders/sky_hdr_dx9.cpp +++ b/materialsystem/stdshaders/sky_hdr_dx9.cpp @@ -220,7 +220,7 @@ BEGIN_VS_SHADER( Sky_HDR_DX9, "Help for Sky_HDR_DX9 shader" ) float w=txtr->GetActualWidth(); float h=txtr->GetActualHeight(); float FUDGE=0.01/max(w,h); // per ATI - float c1[4]={0.5/w-FUDGE, 0.5/h-FUDGE, w, h }; + float c1[4]={(float)(0.5/w-FUDGE), (float)(0.5/h-FUDGE), w, h }; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE, FRAME ); diff --git a/materialsystem/stdshaders/spritecard.cpp b/materialsystem/stdshaders/spritecard.cpp index 6299d905..f84767cb 100644 --- a/materialsystem/stdshaders/spritecard.cpp +++ b/materialsystem/stdshaders/spritecard.cpp @@ -417,7 +417,7 @@ SHADER_DRAW if ( bZoomSeq2 ) { float flZScale=1.0/(params[ZOOMANIMATESEQ2]->GetFloatValue()); - float C0[4]={ 0.5*(1.0+flZScale), flZScale, 0, 0 }; + float C0[4]={ (float)(0.5*(1.0+flZScale)), flZScale, 0, 0 }; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, C0, ARRAYSIZE(C0)/4 ); } @@ -428,7 +428,7 @@ SHADER_DRAW float VC0[8]={ params[MINSIZE]->GetFloatValue(), params[MAXSIZE]->GetFloatValue(), params[STARTFADESIZE]->GetFloatValue(), params[ENDFADESIZE]->GetFloatValue(), - flStartFade, 1.0/(flMaxDistance-flStartFade), + flStartFade, (float)(1.0/(flMaxDistance-flStartFade)), 0,0 }; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, VC0, ARRAYSIZE(VC0)/4 ); diff --git a/materialsystem/stdshaders/teeth.cpp b/materialsystem/stdshaders/teeth.cpp index df01c154..249b49ce 100644 --- a/materialsystem/stdshaders/teeth.cpp +++ b/materialsystem/stdshaders/teeth.cpp @@ -236,7 +236,7 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); @@ -273,7 +273,7 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); @@ -306,7 +306,7 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER( teeth_vs20 ); @@ -334,7 +334,7 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( teeth_vs30 ); diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc index 70f4cefc..c4d036ae 100644 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc +++ b/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc @@ -31,6 +31,9 @@ // DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] +// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..1" [ps20b] [ps30] +// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..0" [ps20] +// DYNAMIC: "DEBUG_LUXELS" "0..1" [ps20b] [ps30] // detail blend mode 6 = ps20b only // SKIP: $DETAIL_BLEND_MODE == 6 [ps20] @@ -71,6 +74,9 @@ // SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) +// Debugging luxels only makes sense if we have lightmaps on this geometry. +// SKIP: ($STATIC_LIGHT_LIGHTMAP == 0) && ($DEBUG_LUXELS == 1) + #include "common_flashlight_fxc.h" #include "common_vertexlitgeneric_dx9.h" @@ -105,6 +111,7 @@ sampler FlashlightSampler : register( s7 ); sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending sampler SelfIllumMaskSampler : register( s11 ); // selfillummask +sampler LightMapSampler : register( s12 ); struct PS_INPUT { @@ -167,6 +174,10 @@ const float4 g_OutlineParams : register( c9 ); const float3 g_DetailTint : register( c10 ); #endif +#if DEBUG_LUXELS +const float4 g_LuxelScale : register( c11 ); +#endif + // Calculate unified fog float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) @@ -331,11 +342,23 @@ float4 main( PS_INPUT i ) : COLOR } float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); - if( bDiffuseLighting || bVertexColor && !( bVertexColor && bDiffuseLighting ) ) + if( bDiffuseLighting || bVertexColor ) { diffuseLighting = i.color.rgb; } +#if STATIC_LIGHT_LIGHTMAP + // This matches the behavior of vertex lighting, which multiplies by cOverbright (which is not accessible here) + // And converts from Gamma space to Linear space before being used. + float2 lightmapTexCoords = i.baseTexCoord.xy; + #if DEBUG_LUXELS + lightmapTexCoords.xy *= g_LuxelScale.xy; + #endif + float3 f3LightmapColor = GammaToLinear( 2.0f * tex2D( LightMapSampler, lightmapTexCoords ).rgb ); + diffuseLighting = f3LightmapColor; +#endif + + float3 albedo = baseColor; if (bBlendTintByBaseAlpha) { diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc index 4b937e0a..1b5502de 100644 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc +++ b/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc @@ -12,7 +12,8 @@ // STATIC: "DONT_GAMMA_CONVERT_VERTEX_COLOR" "0..1" // DYNAMIC: "COMPRESSED_VERTS" "0..1" // DYNAMIC: "DYNAMIC_LIGHT" "0..1" -// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT_VERTEX" "0..1" +// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..1" // DYNAMIC: "DOWATERFOG" "0..1" // DYNAMIC: "SKINNING" "0..1" // DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] @@ -125,7 +126,7 @@ VS_OUTPUT main( const VS_INPUT v ) VS_OUTPUT o = ( VS_OUTPUT )0; bool bDynamicLight = DYNAMIC_LIGHT ? true : false; - bool bStaticLight = STATIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT_VERTEX ? true : false; bool bDoLighting = !g_bVertexColor && (bDynamicLight || bStaticLight); float4 vPosition = v.vPos; diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp b/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp index c51ba984..ed17d0d1 100644 --- a/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp +++ b/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp @@ -41,6 +41,7 @@ BEGIN_VS_SHADER( VertexLitGeneric, "Help for VertexLitGeneric" ) SHADER_PARAM( SELFILLUMFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC4, "0", "Self illum fresnel min, max, exp" ) SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) SHADER_PARAM( FLASHLIGHTNOLAMBERT, SHADER_PARAM_TYPE_BOOL, "0", "Flashlight pass sets N.L=1.0" ) + SHADER_PARAM( LIGHTMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "lightmap texture--will be bound by the engine") // Debugging term for visualizing ambient data on its own SHADER_PARAM( AMBIENTONLY, SHADER_PARAM_TYPE_INTEGER, "0", "Control drawing of non-ambient light ()" ) @@ -163,6 +164,7 @@ BEGIN_VS_SHADER( VertexLitGeneric, "Help for VertexLitGeneric" ) info.m_nEnvmapSaturation = ENVMAPSATURATION; info.m_nAlphaTestReference = ALPHATESTREFERENCE; info.m_nFlashlightNoLambert = FLASHLIGHTNOLAMBERT; + info.m_nLightmap = LIGHTMAP; info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp b/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp index f4e2e84f..7866282e 100644 --- a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp +++ b/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp @@ -32,6 +32,7 @@ static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT ); +static ConVar mat_luxels( "mat_luxels", "0", FCVAR_CHEAT ); static inline bool WantsSkinShader( IMaterialVar** params, const VertexLitGeneric_DX9_Vars_t &info ) @@ -382,7 +383,8 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; bool bHasDiffuseWarp = (!bHasFlashlight || IsX360() ) && hasDiffuseLighting && (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); - + bool bHasLightmapTexture = IsTextureSet( info.m_nLightmap, params ); + bool bHasMatLuxel = bHasLightmapTexture && mat_luxels.GetBool(); //bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL ); bool bFlashlightNoLambert = false; @@ -622,6 +624,11 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // self illum mask } + + // Always enable this sampler, used for lightmaps depending on the dynamic combo. + // Lightmaps are generated in gamma space, but not sRGB, so leave that disabled. Conversion is done in the shader. + pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); + bool bSRGBWrite = true; if( (info.m_nLinearWrite != -1) && (params[info.m_nLinearWrite]->GetIntValue() == 1) ) { @@ -1188,12 +1195,33 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial // Set up light combo state - LightState_t lightState = {0, false, false}; + LightState_t lightState = { 0, false, false, false }; if ( bVertexLitGeneric && (!bHasFlashlight || IsX360() ) ) { pShaderAPI->GetDX9LightState( &lightState ); } + // Override the lighting desired if we have a lightmap set! + if ( bHasLightmapTexture ) + { + lightState.m_bStaticLightVertex = false; + lightState.m_bStaticLightTexel = true; + + // Usual case, not debugging. + if (!bHasMatLuxel) + { + pShader->BindTexture(SHADER_SAMPLER12, info.m_nLightmap); + } + else + { + float dimensions[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_DEBUG_LUXELS ); + pShader->GetTextureDimensions( &dimensions[0], &dimensions[1], info.m_nLightmap ); + DynamicCmdsOut.SetPixelShaderConstant( 11, dimensions, 1 ); + } + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; int numBones = pShaderAPI->GetCurrentNumBones(); @@ -1277,7 +1305,7 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial if ( bAmbientOnly ) // Override selected light combo to be ambient only { lightState.m_bAmbientLight = true; - lightState.m_bStaticLight = false; + lightState.m_bStaticLightVertex = false; lightState.m_nNumLights = 0; } @@ -1289,7 +1317,8 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_VERTEX, lightState.m_bStaticLightVertex ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0); SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( @@ -1306,6 +1335,8 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial // SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( DEBUG_LUXELS, bHasMatLuxel ? 1 : 0 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); @@ -1315,6 +1346,7 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial { DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); @@ -1328,7 +1360,8 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_VERTEX, lightState.m_bStaticLightVertex ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, @@ -1340,6 +1373,8 @@ static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterial DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 ); // SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( DEBUG_LUXELS, bHasMatLuxel ? 1 : 0 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps30 ); diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h b/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h index 6f9c987a..00bf48c8 100644 --- a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h +++ b/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h @@ -54,6 +54,7 @@ struct VertexLitGeneric_DX9_Vars_t int m_nFlashlightNoLambert; int m_nFlashlightTexture; int m_nFlashlightTextureFrame; + int m_nLightmap; int m_nSelfIllumTint; int m_nSelfIllumFresnel; diff --git a/materialsystem/stdshaders/water.cpp b/materialsystem/stdshaders/water.cpp index 8b1f566e..4967361f 100644 --- a/materialsystem/stdshaders/water.cpp +++ b/materialsystem/stdshaders/water.cpp @@ -488,9 +488,9 @@ BEGIN_VS_SHADER( Water_DX90, float cheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); float cheapWaterParams[4] = { - cheapWaterStartDistance * VSHADER_VECT_SCALE, - cheapWaterEndDistance * VSHADER_VECT_SCALE, - PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance ), + (float)(cheapWaterStartDistance * VSHADER_VECT_SCALE), + (float)(cheapWaterEndDistance * VSHADER_VECT_SCALE), + (float)(PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance )), cheapWaterStartDistance / ( cheapWaterEndDistance - cheapWaterStartDistance ), }; pShaderAPI->SetPixelShaderConstant( 1, cheapWaterParams ); diff --git a/mathlib/3dnow.cpp b/mathlib/3dnow.cpp index 3bfb0176..71657044 100644 --- a/mathlib/3dnow.cpp +++ b/mathlib/3dnow.cpp @@ -16,7 +16,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -#if !defined(COMPILER_MSVC64) && !defined(POSIX) +#if !defined(COMPILER_MSVC64) && !defined(LINUX) // Implement for 64-bit Windows if needed. // Clang hits "fatal error: error in backend:" and other errors when trying // to compile the inline assembly below. 3DNow support is highly unlikely to diff --git a/mathlib/IceKey.cpp b/mathlib/IceKey.cpp index 76126880..19f10e3d 100644 --- a/mathlib/IceKey.cpp +++ b/mathlib/IceKey.cpp @@ -63,11 +63,11 @@ static const int ice_keyrot[16] = { static unsigned int gf_mult ( - register unsigned int a, - register unsigned int b, - register unsigned int m + unsigned int a, + unsigned int b, + unsigned int m ) { - register unsigned int res = 0; + unsigned int res = 0; while (b) { if (b & 1) @@ -91,10 +91,10 @@ gf_mult ( static unsigned long gf_exp7 ( - register unsigned int b, + unsigned int b, unsigned int m ) { - register unsigned int x; + unsigned int x; if (b == 0) return (0); @@ -112,10 +112,10 @@ gf_exp7 ( static unsigned long ice_perm32 ( - register unsigned long x + unsigned long x ) { - register unsigned long res = 0; - register const unsigned long *pbox = ice_pbox; + unsigned long res = 0; + const unsigned long *pbox = ice_pbox; while (x) { if (x & 1) @@ -136,7 +136,7 @@ ice_perm32 ( static void ice_sboxes_init (void) { - register int i; + int i; for (i=0; i<1024; i++) { int col = (i >> 1) & 0xff; @@ -205,7 +205,7 @@ IceKey::~IceKey () static unsigned long ice_f ( - register unsigned long p, + unsigned long p, const IceSubkey *sk ) { unsigned long tl, tr; /* Expanded 40-bit values */ @@ -243,8 +243,8 @@ IceKey::encrypt ( unsigned char *ctext ) const { - register int i; - register unsigned long l, r; + int i; + unsigned long l, r; l = (((unsigned long) ptext[0]) << 24) | (((unsigned long) ptext[1]) << 16) @@ -278,8 +278,8 @@ IceKey::decrypt ( unsigned char *ptext ) const { - register int i; - register unsigned long l, r; + int i; + unsigned long l, r; l = (((unsigned long) ctext[0]) << 24) | (((unsigned long) ctext[1]) << 16) @@ -316,20 +316,20 @@ IceKey::scheduleBuild ( int i; for (i=0; i<8; i++) { - register int j; - register int kr = keyrot[i]; + int j; + int kr = keyrot[i]; IceSubkey *isk = &_keysched[n + i]; for (j=0; j<3; j++) isk->val[j] = 0; for (j=0; j<15; j++) { - register int k; + int k; unsigned long *curr_sk = &isk->val[j % 3]; for (k=0; k<4; k++) { unsigned short *curr_kb = &kb[(kr + k) & 3]; - register int bit = *curr_kb & 1; + int bit = *curr_kb & 1; *curr_sk = (*curr_sk << 1) | bit; *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15); diff --git a/mathlib/color_conversion.cpp b/mathlib/color_conversion.cpp index 7e41de43..99c38b57 100644 --- a/mathlib/color_conversion.cpp +++ b/mathlib/color_conversion.cpp @@ -613,10 +613,10 @@ void VectorToColorRGBExp32( const Vector& vin, ColorRGBExp32 &c ) scalar = *reinterpret_cast(&fbits); } - // we should never need to clamp: - Assert(vin.x * scalar <= 255.0f && - vin.y * scalar <= 255.0f && - vin.z * scalar <= 255.0f); + // We can totally wind up above 255 and that's okay--but above 256 would be right out. + Assert(vin.x * scalar < 256.0f && + vin.y * scalar < 256.0f && + vin.z * scalar < 256.0f); // This awful construction is necessary to prevent VC2005 from using the // fldcw/fnstcw control words around every float-to-unsigned-char operation. diff --git a/mathlib/mathlib_base.cpp b/mathlib/mathlib_base.cpp index 07f4ceba..a3b96562 100644 --- a/mathlib/mathlib_base.cpp +++ b/mathlib/mathlib_base.cpp @@ -3390,7 +3390,7 @@ void MathLib_Init( float gamma, float texGamma, float brightness, int overbright { s_bSSE2Enabled = false; } -#endif +#endif // !_X360 s_bMathlibInitialized = true; diff --git a/mathlib/sse.cpp b/mathlib/sse.cpp index e372b902..92e24309 100644 --- a/mathlib/sse.cpp +++ b/mathlib/sse.cpp @@ -204,7 +204,9 @@ float FASTCALL _SSE_VectorNormalize (Vector& vec) #endif float *v = &vec[0]; +#ifdef _WIN32 float *r = &result[0]; +#endif float radius = 0.f; // Blah, get rid of these comparisons ... in reality, if you have all 3 as zero, it shouldn't @@ -740,6 +742,7 @@ float _SSE_cos( float x ) //----------------------------------------------------------------------------- // SSE2 implementations of optimized routines: //----------------------------------------------------------------------------- +#ifdef PLATFORM_WINDOWS_PC32 void _SSE2_SinCos(float x, float* s, float* c) // any x { #ifdef _WIN32 @@ -825,7 +828,9 @@ void _SSE2_SinCos(float x, float* s, float* c) // any x #error "Not Implemented" #endif } +#endif // PLATFORM_WINDOWS_PC32 +#ifdef PLATFORM_WINDOWS_PC32 float _SSE2_cos(float x) { #ifdef _WIN32 @@ -883,7 +888,9 @@ float _SSE2_cos(float x) return x; } +#endif // PLATFORM_WINDOWS_PC32 +#if 0 // SSE Version of VectorTransform void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1) { @@ -941,7 +948,9 @@ void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1) #error "Not Implemented" #endif } +#endif +#if 0 void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ) { Assert( s_bMathlibInitialized ); @@ -995,6 +1004,7 @@ void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ) #error "Not Implemented" #endif } +#endif #ifdef _WIN32 void _declspec(naked) _SSE_VectorMA( const float *start, float scale, const float *direction, float *dest ) diff --git a/mathlib/sse.h b/mathlib/sse.h index f0da3b06..d71502d5 100644 --- a/mathlib/sse.h +++ b/mathlib/sse.h @@ -15,9 +15,13 @@ void FASTCALL _SSE_VectorNormalizeFast(Vector& vec); float _SSE_InvRSquared(const float* v); void _SSE_SinCos(float x, float* s, float* c); float _SSE_cos( float x); +#ifdef PLATFORM_WINDOWS_PC32 void _SSE2_SinCos(float x, float* s, float* c); float _SSE2_cos(float x); +#endif +#if 0 void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1); void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ); +#endif #endif // _SSE_H diff --git a/mathlib/ssenoise.cpp b/mathlib/ssenoise.cpp index 60c2eb82..eb3bb308 100644 --- a/mathlib/ssenoise.cpp +++ b/mathlib/ssenoise.cpp @@ -30,6 +30,10 @@ static ALIGN16 int32 idx_mask[4]= {0xffff, 0xffff, 0xffff, 0xffff}; // returns 0..1 static inline float GetLatticePointValue( int idx_x, int idx_y, int idx_z ) { + NOTE_UNUSED(perm_d); + NOTE_UNUSED(impulse_ycoords); + NOTE_UNUSED(impulse_zcoords); + int ret_idx = perm_a[idx_x & 0xff]; ret_idx = perm_b[( idx_y + ret_idx ) & 0xff]; ret_idx = perm_c[( idx_z + ret_idx ) & 0xff]; diff --git a/mathlib/vmatrix.cpp b/mathlib/vmatrix.cpp index d0921190..46ab80ac 100644 --- a/mathlib/vmatrix.cpp +++ b/mathlib/vmatrix.cpp @@ -957,7 +957,7 @@ void MatrixBuildTranslation( VMatrix& dst, const Vector &translation ) //----------------------------------------------------------------------------- void MatrixBuildRotationAboutAxis( VMatrix &dst, const Vector &vAxisOfRot, float angleDegrees ) { - MatrixBuildRotationAboutAxis( vAxisOfRot, angleDegrees, dst.As3x4() ); + MatrixBuildRotationAboutAxis( vAxisOfRot, angleDegrees, const_cast< matrix3x4_t &> ( dst.As3x4() ) ); dst[3][0] = 0; dst[3][1] = 0; dst[3][2] = 0; diff --git a/public/VGuiMatSurface/IMatSystemSurface.h b/public/VGuiMatSurface/IMatSystemSurface.h index 03dbe531..b0186d0b 100644 --- a/public/VGuiMatSurface/IMatSystemSurface.h +++ b/public/VGuiMatSurface/IMatSystemSurface.h @@ -106,9 +106,8 @@ public: // Gets a material bound to a surface texture ID virtual IMaterial *DrawGetTextureMaterial( int id ) = 0; - // The matching method is in ISurface, but we can't add anything there and remain mod-compatible. - // So this goes here instead. virtual void GetFullscreenViewportAndRenderTarget( int & x, int & y, int & w, int & h, ITexture **ppRenderTarget ) = 0; + virtual void SetFullscreenViewportAndRenderTarget( int x, int y, int w, int h, ITexture *pRenderTarget ) = 0; }; diff --git a/public/XUnzip.cpp b/public/XUnzip.cpp index 46167935..98e042b0 100644 --- a/public/XUnzip.cpp +++ b/public/XUnzip.cpp @@ -1812,16 +1812,16 @@ uInt *v) // working area: values in order of bit length uInt f; // i repeats in table every f entries int g; // maximum code length int h; // table level - register uInt i; // counter, current code - register uInt j; // counter - register int k; // number of bits in current code + uInt i; // counter, current code + uInt j; // counter + int k; // number of bits in current code int l; // bits per table (returned in m) uInt mask; // (1 << w) - 1, to avoid cc -O bug on HP - register uInt *p; // pointer into c[], b[], or v[] + uInt *p; // pointer into c[], b[], or v[] inflate_huft *q; // points to current table struct inflate_huft_s r; // table entry for structure assignment inflate_huft *u[BMAX]; // table stack - register int w; // bits before this table == (l * h) + int w; // bits before this table == (l * h) uInt x[BMAX+1]; // bit offsets, then code stack uInt *xp; // pointer into x int y; // number of dummy codes added @@ -4077,7 +4077,8 @@ ZRESULT TUnzip::Find(const TCHAR *name, bool ic, int *index, ZIPENTRY *ze) return ZR_NOTFOUND; } if (currentfile!=-1) - unzCloseCurrentFile(uf); currentfile=-1; + unzCloseCurrentFile(uf); + currentfile=-1; int i = (int)uf->num_file; if (index!=NULL) *index=i; diff --git a/public/XZip.cpp b/public/XZip.cpp index 291ad96f..94f4c325 100644 --- a/public/XZip.cpp +++ b/public/XZip.cpp @@ -1470,7 +1470,7 @@ void send_bits(TState &state,int value, int length) */ unsigned bi_reverse(unsigned code, int len) { - register unsigned res = 0; + unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; @@ -1571,7 +1571,7 @@ int longest_match (TState &state,IPos cur_match); */ void lm_init (TState &state, int pack_level, ush *flags) { - register unsigned j; + unsigned j; Assert(state,pack_level>=1 && pack_level<=8,"bad pack level"); @@ -1642,9 +1642,9 @@ void lm_init (TState &state, int pack_level, ush *flags) int longest_match(TState &state,IPos cur_match) { unsigned chain_length = state.ds.max_chain_length; /* max hash chain length */ - register uch far *scan = state.ds.window + state.ds.strstart; /* current string */ - register uch far *match; /* matched string */ - register int len; /* length of current match */ + uch far *scan = state.ds.window + state.ds.strstart; /* current string */ + uch far *match; /* matched string */ + int len; /* length of current match */ int best_len = state.ds.prev_length; /* best match length so far */ IPos limit = state.ds.strstart > (IPos)MAX_DIST ? state.ds.strstart - (IPos)MAX_DIST : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, @@ -1657,9 +1657,9 @@ int longest_match(TState &state,IPos cur_match) - register uch far *strend = state.ds.window + state.ds.strstart + MAX_MATCH; - register uch scan_end1 = scan[best_len-1]; - register uch scan_end = scan[best_len]; + uch far *strend = state.ds.window + state.ds.strstart + MAX_MATCH; + uch scan_end1 = scan[best_len-1]; + uch scan_end = scan[best_len]; /* Do not waste too much time if we already have a good match: */ if (state.ds.prev_length >= state.ds.good_match) { @@ -1747,7 +1747,7 @@ int longest_match(TState &state,IPos cur_match) */ void fill_window(TState &state) { - register unsigned n, m; + unsigned n, m; unsigned more; /* Amount of free space at the end of the window. */ do { @@ -1916,7 +1916,7 @@ ulg deflate(TState &state) IPos prev_match; /* previous match */ int flush; /* set if current block must be flushed */ int match_available = 0; /* set if previous match exists */ - register unsigned match_length = MIN_MATCH-1; /* length of best match */ + unsigned match_length = MIN_MATCH-1; /* length of best match */ if (state.level <= 3) return deflate_fast(state); /* optimized for speed */ @@ -2705,7 +2705,8 @@ ZRESULT TZip::Add(const char *odstzn, void *src,unsigned int len, DWORD flags) while (*d != 0) { if (*d == '\\') - *d = '/'; d++; + *d = '/'; + d++; } bool isdir = (flags==ZIP_FOLDER); bool needs_trailing_slash = (isdir && dstzn[strlen(dstzn)-1]!='/'); diff --git a/public/bitmap/imageformat.h b/public/bitmap/imageformat.h index 1a749c27..34d268e8 100644 --- a/public/bitmap/imageformat.h +++ b/public/bitmap/imageformat.h @@ -376,7 +376,7 @@ namespace ImageLoader struct ResampleInfo_t { - ResampleInfo_t() : m_nSrcDepth(1), m_nDestDepth(1), m_flAlphaThreshhold(0.4f), m_flAlphaHiFreqThreshhold(0.4f), m_nFlags(0) + 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; diff --git a/public/bone_setup.cpp b/public/bone_setup.cpp index 21ed238d..95fef067 100644 --- a/public/bone_setup.cpp +++ b/public/bone_setup.cpp @@ -5895,28 +5895,32 @@ int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAtta int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName ) { - // binary search for the bone matching pName - int start = 0, end = pStudioHdr->numbones()-1; - const byte *pBoneTable = pStudioHdr->GetBoneTableSortedByName(); - mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); - while (start <= end) + if ( pStudioHdr ) { - int mid = (start + end) >> 1; - int cmp = Q_stricmp( pbones[pBoneTable[mid]].pszName(), pName ); + // binary search for the bone matching pName + int start = 0, end = pStudioHdr->numbones()-1; + const byte *pBoneTable = pStudioHdr->GetBoneTableSortedByName(); + mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); + while (start <= end) + { + int mid = (start + end) >> 1; + int cmp = Q_stricmp( pbones[pBoneTable[mid]].pszName(), pName ); - if ( cmp < 0 ) - { - start = mid + 1; - } - else if ( cmp > 0 ) - { - end = mid - 1; - } - else - { - return pBoneTable[mid]; + if ( cmp < 0 ) + { + start = mid + 1; + } + else if ( cmp > 0 ) + { + end = mid - 1; + } + else + { + return pBoneTable[mid]; + } } } + return -1; } @@ -5969,3 +5973,81 @@ bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence ) // Everything for this sequence is resident? return !pendingload; } + + +//----------------------------------------------------------------------------- +// Purpose: Drive a flex controller from a component of a bone +//----------------------------------------------------------------------------- +void Studio_RunBoneFlexDrivers( float *pflFlexControllerWeights, const CStudioHdr *pStudioHdr, const Vector *pvPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld ) +{ + bool bRootToWorldInvComputed = false; + matrix3x4_t mRootToWorldInv; + matrix3x4_t mParentInv; + matrix3x4_t mBoneLocal; + + const int nBoneFlexDriverCount = pStudioHdr->BoneFlexDriverCount(); + + for ( int i = 0; i < nBoneFlexDriverCount; ++i ) + { + const mstudioboneflexdriver_t *pBoneFlexDriver = pStudioHdr->BoneFlexDriver( i ); + const mstudiobone_t *pStudioBone = pStudioHdr->pBone( pBoneFlexDriver->m_nBoneIndex ); + + const int nControllerCount = pBoneFlexDriver->m_nControlCount; + + if ( pStudioBone->flags & BONE_USED_BY_BONE_MERGE ) + { + // The local space version of the bone is not available if this is a bonemerged bone + // so do the slow computation of the local version of the bone from boneToWorld + + if ( pStudioBone->parent < 0 ) + { + if ( !bRootToWorldInvComputed ) + { + MatrixInvert( mRootToWorld, mRootToWorldInv ); + bRootToWorldInvComputed = true; + } + + MatrixMultiply( mRootToWorldInv, pBoneToWorld[ pBoneFlexDriver->m_nBoneIndex ], mBoneLocal ); + } + else + { + MatrixInvert( pBoneToWorld[ pStudioBone->parent ], mParentInv ); + MatrixMultiply( mParentInv, pBoneToWorld[ pBoneFlexDriver->m_nBoneIndex ], mBoneLocal ); + } + + for ( int j = 0; j < nControllerCount; ++j ) + { + const mstudioboneflexdrivercontrol_t *pController = pBoneFlexDriver->pBoneFlexDriverControl( j ); + const mstudioflexcontroller_t *pFlexController = pStudioHdr->pFlexcontroller( static_cast< LocalFlexController_t >( pController->m_nFlexControllerIndex ) ); + + if ( pFlexController->localToGlobal < 0 ) + continue; + + Assert( pController->m_nFlexControllerIndex >= 0 && pController->m_nFlexControllerIndex < pStudioHdr->numflexcontrollers() ); + Assert( pController->m_nBoneComponent >= 0 && pController->m_nBoneComponent <= 2 ); + pflFlexControllerWeights[pFlexController->localToGlobal] = + RemapValClamped( mBoneLocal[pController->m_nBoneComponent][3], pController->m_flMin, pController->m_flMax, 0.0f, 1.0f ); + } + } + else + { + // Use the local space version of the bone directly for non-bonemerged bones + + const Vector &position = pvPositions[ pBoneFlexDriver->m_nBoneIndex ]; + + for ( int j = 0; j < nControllerCount; ++j ) + { + const mstudioboneflexdrivercontrol_t *pController = pBoneFlexDriver->pBoneFlexDriverControl( j ); + const mstudioflexcontroller_t *pFlexController = pStudioHdr->pFlexcontroller( static_cast< LocalFlexController_t >( pController->m_nFlexControllerIndex ) ); + + if ( pFlexController->localToGlobal < 0 ) + continue; + + Assert( pController->m_nFlexControllerIndex >= 0 && pController->m_nFlexControllerIndex < pStudioHdr->numflexcontrollers() ); + Assert( pController->m_nBoneComponent >= 0 && pController->m_nBoneComponent <= 2 ); + pflFlexControllerWeights[pFlexController->localToGlobal] = + RemapValClamped( position[pController->m_nBoneComponent], pController->m_flMin, pController->m_flMax, 0.0f, 1.0f ); + } + } + } +} diff --git a/public/const.h b/public/const.h index 46c54751..f343e50a 100644 --- a/public/const.h +++ b/public/const.h @@ -51,7 +51,7 @@ // BUGBUG: Reconcile with or derive this from the engine's internal definition! // FIXME: I added an extra bit because I needed to make it signed -#define SP_MODEL_INDEX_BITS 12 +#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 diff --git a/public/datamodel/dmattribute.h b/public/datamodel/dmattribute.h index 5bf016f0..2ad4953f 100644 --- a/public/datamodel/dmattribute.h +++ b/public/datamodel/dmattribute.h @@ -357,7 +357,7 @@ inline void CDmAttribute::SetValue( char *pValue ) inline void CDmAttribute::SetValue( const void *pValue, size_t nSize ) { - CUtlBinaryBlock buf( pValue, nSize ); + CUtlBinaryBlock buf( pValue, (int)nSize ); return SetValue( buf ); } @@ -599,7 +599,7 @@ inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, char *pVa inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const void *pValue, size_t nSize ) { - CUtlBinaryBlock buf( pValue, nSize ); + CUtlBinaryBlock buf( pValue, (int)nSize ); return SetValue( pAttributeName, buf ); } diff --git a/public/datamodel/dmattributetypes.h b/public/datamodel/dmattributetypes.h index 27880c28..b0ffc840 100644 --- a/public/datamodel/dmattributetypes.h +++ b/public/datamodel/dmattributetypes.h @@ -11,6 +11,7 @@ #endif #include "tier1/utlvector.h" +#include "tier1/utlbinaryblock.h" #include "tier1/utlstring.h" #include "tier1/uniqueid.h" #include "Color.h" diff --git a/public/edict.h b/public/edict.h index b43ba042..042f1dc3 100644 --- a/public/edict.h +++ b/public/edict.h @@ -343,6 +343,8 @@ inline void CBaseEdict::SetFree() m_fStateFlags |= FL_EDICT_FREE; } +// WARNING: Make sure you don't really want to call ED_ClearFreeFlag which will also +// remove this edict from the g_FreeEdicts bitset. inline void CBaseEdict::ClearFree() { m_fStateFlags &= ~FL_EDICT_FREE; diff --git a/public/eiface.h b/public/eiface.h index 821df8d6..874774fe 100644 --- a/public/eiface.h +++ b/public/eiface.h @@ -59,6 +59,7 @@ class CGamestatsData; class CSteamID; class IReplayFactory; class IReplaySystem; +class IServer; typedef struct player_info_s player_info_t; @@ -72,7 +73,9 @@ typedef struct player_info_s player_info_t; #define DLLEXPORT /* */ #endif -#define INTERFACEVERSION_VENGINESERVER "VEngineServer021" +#define INTERFACEVERSION_VENGINESERVER_VERSION_21 "VEngineServer021" +#define INTERFACEVERSION_VENGINESERVER "VEngineServer022" +#define INTERFACEVERSION_VENGINESERVER_INT 22 struct bbox_t { @@ -410,8 +413,13 @@ public: // Get sv.GetTime() virtual float GetServerTime() const = 0; + + // Exposed for server plugin authors + virtual IServer *GetIServer() = 0; }; +typedef IVEngineServer IVEngineServer021; + #define INTERFACEVERSION_SERVERGAMEDLL_VERSION_8 "ServerGameDLL008" #define INTERFACEVERSION_SERVERGAMEDLL "ServerGameDLL009" @@ -543,6 +551,9 @@ public: // Get gamedata string to send to the master serer updater. virtual const char *GetServerBrowserGameData() = 0; + + // Called to add output to the status command + virtual void Status( void (*print) (const char *fmt, ...) ) = 0; }; typedef IServerGameDLL IServerGameDLL008; diff --git a/public/engine/IEngineSound.h b/public/engine/IEngineSound.h index 9b13532a..60d4d688 100644 --- a/public/engine/IEngineSound.h +++ b/public/engine/IEngineSound.h @@ -43,7 +43,7 @@ class Vector; #define SNDLEVEL_FROM_COMPATIBILITY_MODE( x ) ((soundlevel_t)(int)( (x) - 256 )) // Tells if the given sndlevel is marked as compatibility mode. -#define SNDLEVEL_IS_COMPATIBILITY_MODE( x ) ( (x) >= 256 ) +#define SNDLEVEL_IS_COMPATIBILITY_MODE( x ) ( (x) >= soundlevel_t(256) ) diff --git a/public/filesystem.h b/public/filesystem.h index 961942cd..8ec50993 100644 --- a/public/filesystem.h +++ b/public/filesystem.h @@ -5,6 +5,10 @@ // $NoKeywords: $ //===========================================================================// +#ifndef FILESYSTEM_H +#define FILESYSTEM_H +#pragma once + #include #include "tier0/threadtools.h" @@ -17,9 +21,6 @@ #include "tier1/checksum_md5.h" #include "tier1/refcount.h" -#ifndef FILESYSTEM_H -#define FILESYSTEM_H - #ifdef _WIN32 #pragma once #endif @@ -581,10 +582,20 @@ public: virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly ) = 0; // converts a partial path into a full path - virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) = 0; + // Prefer using the RelativePathToFullPath_safe template wrapper to calling this directly + virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) = 0; + template const char *RelativePathToFullPath_safe( const char *pFileName, const char *pPathID, OUT_Z_ARRAY char (&pDest)[maxLenInChars], PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) + { + return RelativePathToFullPath( pFileName, pPathID, pDest, (int)maxLenInChars, pathFilter, pPathType ); + } // Returns the search path, each path is separated by ;s. Returns the length of the string returned - virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) = 0; + // Prefer using the GetSearchPath_safe template wrapper to calling this directly + virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; + template int GetSearchPath_safe( const char *pathID, bool bGetPackFiles, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) + { + return GetSearchPath( pathID, bGetPackFiles, pDest, (int)maxLenInChars ); + } // interface for custom pack files > 4Gb virtual bool AddPackFile( const char *fullpath, const char *pathID ) = 0; @@ -651,11 +662,21 @@ public: // FIXME: This method is obsolete! Use RelativePathToFullPath instead! // converts a partial path into a full path - virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0; + // Prefer using the GetLocalPath_safe template wrapper to calling this directly + virtual const char *GetLocalPath( const char *pFileName, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; + template const char *GetLocalPath_safe( const char *pFileName, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) + { + return GetLocalPath( pFileName, pDest, (int)maxLenInChars ); + } // Returns true on success ( based on current list of search paths, otherwise false if // it can't be resolved ) - virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) = 0; + // Prefer using the FullPathToRelativePath_safe template wrapper to calling this directly + virtual bool FullPathToRelativePath( const char *pFullpath, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; + template bool FullPathToRelativePath_safe( const char *pFullpath, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) + { + return FullPathToRelativePath( pFullpath, pDest, (int)maxLenInChars ); + } // Gets the current working directory virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) = 0; @@ -815,7 +836,12 @@ public: virtual void EndMapAccess() = 0; // Returns true on success, otherwise false if it can't be resolved - virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, char *pRelative, int maxlen ) = 0; + // Prefer using the FullPathToRelativePathEx_safe template wrapper to calling this directly + virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; + template bool FullPathToRelativePathEx_safe( const char *pFullpath, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) + { + return FullPathToRelativePathEx( pFullpath, pDest, (int)maxLenInChars ); + } virtual int GetPathIndex( const FileNameHandle_t &handle ) = 0; virtual long GetPathTime( const char *pPath, const char *pPathID ) = 0; @@ -892,6 +918,14 @@ public: // Called when we unload a file, to remove that file's info for pure server purposes. virtual void NotifyFileUnloaded( const char *pszFilename, const char *pPathId ) = 0; + + // Returns true on successfully retrieve case-sensitive full path, otherwise false + // Prefer using the GetCaseCorrectFullPath template wrapper to calling this directly + virtual bool GetCaseCorrectFullPath_Ptr( const char *pFullPath, OUT_Z_CAP( maxLenInChars ) char *pDest, int maxLenInChars ) = 0; + template bool GetCaseCorrectFullPath( const char *pFullPath, OUT_Z_ARRAY char( &pDest )[maxLenInChars] ) + { + return GetCaseCorrectFullPath_Ptr( pFullPath, pDest, (int)maxLenInChars ); + } }; //----------------------------------------------------------------------------- diff --git a/public/filesystem_init.cpp b/public/filesystem_init.cpp index 86b70c65..5548bd2b 100644 --- a/public/filesystem_init.cpp +++ b/public/filesystem_init.cpp @@ -86,7 +86,7 @@ public: if ( pValue ) { m_bExisted = true; - m_OriginalValue.SetSize( strlen( pValue ) + 1 ); + m_OriginalValue.SetSize( Q_strlen( pValue ) + 1 ); memcpy( m_OriginalValue.Base(), pValue, m_OriginalValue.Count() ); } else diff --git a/public/filesystem_passthru.h b/public/filesystem_passthru.h index ed123e06..955e2136 100644 --- a/public/filesystem_passthru.h +++ b/public/filesystem_passthru.h @@ -120,8 +120,9 @@ public: virtual const char *FindNext( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindNext( handle ); } virtual bool FindIsDirectory( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindIsDirectory( handle ); } virtual void FindClose( FileFindHandle_t handle ) { m_pFileSystemPassThru->FindClose( handle ); } - virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) { return m_pFileSystemPassThru->GetLocalPath( pFileName, pLocalPath, localPathBufferSize ); } - virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) { return m_pFileSystemPassThru->FullPathToRelativePath( pFullpath, pRelative, maxlen ); } + virtual const char *GetLocalPath( const char *pFileName, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->GetLocalPath( pFileName, pDest, maxLenInChars ); } + virtual bool FullPathToRelativePath( const char *pFullpath, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->FullPathToRelativePath( pFullpath, pDest, maxLenInChars ); } + virtual bool GetCaseCorrectFullPath_Ptr( const char *pFullPath, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->GetCaseCorrectFullPath_Ptr( pFullPath, pDest, maxLenInChars ); } virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) { return m_pFileSystemPassThru->GetCurrentDirectory( pDirectory, maxlen ); } virtual void PrintOpenedFiles( void ) { m_pFileSystemPassThru->PrintOpenedFiles(); } virtual void PrintSearchPaths( void ) { m_pFileSystemPassThru->PrintSearchPaths(); } @@ -174,8 +175,8 @@ public: virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl, int newPriority) { return m_pFileSystemPassThru->AsyncSetPriority(hControl, newPriority); } virtual bool AsyncSuspend() { return m_pFileSystemPassThru->AsyncSuspend(); } virtual bool AsyncResume() { return m_pFileSystemPassThru->AsyncResume(); } - virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) { return m_pFileSystemPassThru->RelativePathToFullPath( pFileName, pPathID, pLocalPath, localPathBufferSize, pathFilter, pPathType ); } - virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) { return m_pFileSystemPassThru->GetSearchPath( pathID, bGetPackFiles, pPath, nMaxLen ); } + virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) { return m_pFileSystemPassThru->RelativePathToFullPath( pFileName, pPathID, pDest, maxLenInChars, pathFilter, pPathType ); } + virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->GetSearchPath( pathID, bGetPackFiles, pDest, maxLenInChars ); } virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) { return m_pFileSystemPassThru->OpenEx( pFileName, pOptions, flags, pathID, ppszResolvedFilename );} virtual int ReadEx( void* pOutput, int destSize, int size, FileHandle_t file ) { return m_pFileSystemPassThru->ReadEx( pOutput, destSize, size, file ); } @@ -208,7 +209,7 @@ public: virtual void EndMapAccess() { m_pFileSystemPassThru->EndMapAccess(); } virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadToBuffer( hFile, buf, nMaxBytes, pfnAlloc ); } - virtual bool FullPathToRelativePathEx( const char *pFullPath, const char *pPathId, char *pRelative, int nMaxLen ) { return m_pFileSystemPassThru->FullPathToRelativePathEx( pFullPath, pPathId, pRelative, nMaxLen ); } + virtual bool FullPathToRelativePathEx( const char *pFullPath, const char *pPathId, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->FullPathToRelativePathEx( pFullPath, pPathId, pDest, maxLenInChars ); } virtual int GetPathIndex( const FileNameHandle_t &handle ) { return m_pFileSystemPassThru->GetPathIndex( handle ); } virtual long GetPathTime( const char *pPath, const char *pPathID ) { return m_pFileSystemPassThru->GetPathTime( pPath, pPathID ); } diff --git a/public/gamebspfile.h b/public/gamebspfile.h index 786e0671..4dfce7ea 100644 --- a/public/gamebspfile.h +++ b/public/gamebspfile.h @@ -36,7 +36,7 @@ enum { GAMELUMP_DETAIL_PROPS_VERSION = 4, GAMELUMP_DETAIL_PROP_LIGHTING_VERSION = 0, - GAMELUMP_STATIC_PROPS_VERSION = 6, + GAMELUMP_STATIC_PROPS_VERSION = 7, GAMELUMP_STATIC_PROP_LIGHTING_VERSION = 0, GAMELUMP_DETAIL_PROP_LIGHTING_HDR_VERSION = 0, }; @@ -139,7 +139,9 @@ enum STATIC_PROP_NO_SELF_SHADOWING = 0x80, // disable self shadowing in vrad - STATIC_PROP_WC_MASK = 0xd8, // all flags settable in hammer (?) + STATIC_PROP_NO_PER_TEXEL_LIGHTING = 0x100, // whether we should do per-texel lightmaps in vrad. + + STATIC_PROP_WC_MASK = 0x1d8, // all flags settable in hammer (?) }; struct StaticPropDictLump_t @@ -183,7 +185,7 @@ struct StaticPropLumpV5_t // int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump }; -struct StaticPropLump_t +struct StaticPropLumpV6_t { DECLARE_BYTESWAP_DATADESC(); Vector m_Origin; @@ -203,6 +205,76 @@ struct StaticPropLump_t // int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump }; +struct StaticPropLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector m_Origin; + QAngle m_Angles; + unsigned short m_PropType; + unsigned short m_FirstLeaf; + unsigned short m_LeafCount; + unsigned char m_Solid; + int m_Skin; + float m_FadeMinDist; + float m_FadeMaxDist; + Vector m_LightingOrigin; + float m_flForcedFadeScale; + unsigned short m_nMinDXLevel; + unsigned short m_nMaxDXLevel; + // int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump + unsigned int m_Flags; + unsigned short m_nLightmapResolutionX; + unsigned short m_nLightmapResolutionY; + + + StaticPropLump_t& operator=(const StaticPropLumpV4_t& _rhs) + { + m_Origin = _rhs.m_Origin; + m_Angles = _rhs.m_Angles; + m_PropType = _rhs.m_PropType; + m_FirstLeaf = _rhs.m_FirstLeaf; + m_LeafCount = _rhs.m_LeafCount; + m_Solid = _rhs.m_Solid; + m_Flags = _rhs.m_Flags; + m_Skin = _rhs.m_Skin; + m_FadeMinDist = _rhs.m_FadeMinDist; + m_FadeMaxDist = _rhs.m_FadeMaxDist; + m_LightingOrigin = _rhs.m_LightingOrigin; + + // These get potentially set twice--once here and once in the caller. + // Value judgement: This makes the code easier to work with, so unless it's a perf issue... + m_flForcedFadeScale = 1.0f; + m_nMinDXLevel = 0; + m_nMaxDXLevel = 0; + m_nLightmapResolutionX = 0; + m_nLightmapResolutionY = 0; + + // Older versions don't want this. + m_Flags |= STATIC_PROP_NO_PER_TEXEL_LIGHTING; + return *this; + } + + StaticPropLump_t& operator=(const StaticPropLumpV5_t& _rhs) + { + (*this) = reinterpret_cast(_rhs); + + m_flForcedFadeScale = _rhs.m_flForcedFadeScale; + return *this; + } + + StaticPropLump_t& operator=(const StaticPropLumpV6_t& _rhs) + { + (*this) = reinterpret_cast(_rhs); + + m_nMinDXLevel = _rhs.m_nMinDXLevel; + m_nMaxDXLevel = _rhs.m_nMaxDXLevel; + return *this; + } +}; + + + + struct StaticPropLeafLump_t { DECLARE_BYTESWAP_DATADESC(); diff --git a/public/html/htmlmessages.h b/public/html/htmlmessages.h deleted file mode 100644 index b2d5dd0e..00000000 --- a/public/html/htmlmessages.h +++ /dev/null @@ -1,116 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -//=============================================================================// - -#ifndef HTMLMESSAGES_H -#define HTMLMESSAGES_H - -#ifdef _WIN32 -#pragma once -#endif - -//----------------------------------------------------------------------------- -// Purpose: Commands we IPC across to the html thread and get responses for -//----------------------------------------------------------------------------- -enum EHTMLCommands -{ - // input events - eHTMLCommands_KeyUp, - eHTMLCommands_KeyDown, - eHTMLCommands_KeyChar, - eHTMLCommands_MouseDown, - eHTMLCommands_MouseUp, - eHTMLCommands_MouseDblClick, - eHTMLCommands_MouseWheel, - eHTMLCommands_MouseMove, - eHTMLCommands_MouseLeave, - - // command events - eHTMLCommands_BrowserCreate, - eHTMLCommands_BrowserRemove, - eHTMLCommands_BrowserErrorStrings, - eHTMLCommands_BrowserSize, - eHTMLCommands_BrowserPosition, - eHTMLCommands_PostURL, - eHTMLCommands_StopLoad, - eHTMLCommands_Reload, - eHTMLCommands_GoForward, - eHTMLCommands_GoBack, - eHTMLCommands_Copy, - eHTMLCommands_Paste, - eHTMLCommands_ExecuteJavaScript, - eHTMLCommands_SetFocus, - eHTMLCommands_HorizontalScrollBarSize, - eHTMLCommands_VerticalScrollBarSize, - eHTMLCommands_Find, - eHTMLCommands_StopFind, - eHTMLCommands_SetHorizontalScroll, - eHTMLCommands_SetVerticalScroll, - eHTMLCommands_SetZoomLevel, - eHTMLCommands_ViewSource, - eHTMLCommands_NeedsPaintResponse, - eHTMLCommands_AddHeader, - eHTMLCommands_GetZoom, - eHTMLCommands_FileLoadDialogResponse, - eHTMLCommands_LinkAtPosition, - eHTMLCommands_ZoomToElementAtPosition, - eHTMLCommands_SavePageToJPEG, - eHTMLCommands_JSAlert, - eHTMLCommands_JSConfirm, - eHTMLCommands_CanGoBackandForward, - eHTMLCommands_OpenSteamURL, - eHTMLCommands_SizePopup, - eHTMLCommands_SetCookie, - eHTMLCommands_SetTargetFrameRate, - eHTMLCommands_FullRepaint, - eHTMLCommands_SetPageScale, - eHTMLCommands_RequestFullScreen, - eHTMLCommands_ExitFullScreen, - eHTMLCommands_GetCookiesForURL, - eHTMLCommands_ZoomToCurrentlyFocusedNode, - eHTMLCommands_CloseFullScreenFlashIfOpen, - eHTMLCommands_PauseFullScreenFlashMovieIfOpen, - eHTMLCommands_GetFocusedNodeValue, - - // output back to the main thread - eHTMLCommands_BrowserCreateResponse, - eHTMLCommands_BrowserReady, - eHTMLCommands_URLChanged, - eHTMLCommands_FinishedRequest, - eHTMLCommands_StartRequest, - eHTMLCommands_ShowPopup, - eHTMLCommands_HidePopup, - eHTMLCommands_OpenNewTab, - eHTMLCommands_PopupHTMLWindow, - eHTMLCommands_PopupHTMLWindowResponse, - eHTMLCommands_SetHTMLTitle, - eHTMLCommands_LoadingResource, - eHTMLCommands_StatusText, - eHTMLCommands_SetCursor, - eHTMLCommands_FileLoadDialog, - eHTMLCommands_ShowToolTip, - eHTMLCommands_UpdateToolTip, - eHTMLCommands_HideToolTip, - eHTMLCommands_SearchResults, - eHTMLCommands_Close, - eHTMLCommands_VerticalScrollBarSizeResponse, - eHTMLCommands_HorizontalScrollBarSizeResponse, - eHTMLCommands_GetZoomResponse, - eHTMLCommands_StartRequestResponse, - eHTMLCommands_NeedsPaint, - eHTMLCommands_LinkAtPositionResponse, - eHTMLCommands_ZoomToElementAtPositionResponse, - eHTMLCommands_JSDialogResponse, - eHTMLCommands_ScaleToValueResponse, - eHTMLCommands_RequestFullScreenResponse, - eHTMLCommands_GetCookiesForURLResponse, - eHTMLCommands_NodeGotFocus, - eHTMLCommands_SavePageToJPEGResponse, - eHTMLCommands_GetFocusedNodeValueResponse, - - eHTMLCommands_None, - -}; - -#endif // HTMLMESSAGES_H \ No newline at end of file diff --git a/public/html/htmlprotobuf.cpp b/public/html/htmlprotobuf.cpp deleted file mode 100644 index 59168c99..00000000 --- a/public/html/htmlprotobuf.cpp +++ /dev/null @@ -1,70 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -//=============================================================================// - - -#include "html/htmlprotobuf.h" -#include "tier0/vprof.h" -#include "tier0/valve_minmax_off.h" - - -#ifdef _WIN64 -// disable 64-bit warnings for the google headers -#pragma warning(push) -#pragma warning(disable:4244) // warning C4244: 'return' : conversion from '__int64' to 'int', possible loss of data -#pragma warning(disable:4267) // warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data -#endif - -#include "tier0/memdbgoff.h" -#include "protobuf-2.3.0/src/google/protobuf/message_lite.h" -#include "tier0/memdbgon.h" - -#ifdef _WIN64 -#pragma warning(pop) -#endif - -//----------------------------------------------------------------------------- -// Purpose: serialize a protobuf into a utlbuffer -//----------------------------------------------------------------------------- -void CHTMLBaseProtoBufMsg::SerializeCrossProc( CUtlBuffer *pBuffer ) const -{ - VPROF_BUDGET( "CUIProtoBufMsg::SerializeCrossProc", VPROF_BUDGETGROUP_OTHER_VGUI ); - uint32 unSize = ((google::protobuf::MessageLite *)m_pMsg)->ByteSize(); - - // Ensure enough for type, size, and serialized data - pBuffer->EnsureCapacity( pBuffer->TellPut() + sizeof(uint32) * 3 + unSize ); // bugbug cboyd - drop to * 2 whenpassthrough is removed below - - pBuffer->PutUnsignedInt( unSize ); - - if ( unSize == 0 ) - return; - - uint8 *pBody = (uint8*)pBuffer->Base()+pBuffer->TellPut(); - ((google::protobuf::MessageLite *)m_pMsg)->SerializeWithCachedSizesToArray( pBody ); - pBuffer->SeekPut( CUtlBuffer::SEEK_CURRENT, unSize ); -} - - -//----------------------------------------------------------------------------- -// Purpose: grab a previously serialized protobuf -//----------------------------------------------------------------------------- -bool CHTMLBaseProtoBufMsg::BDeserializeCrossProc( CUtlBuffer *pBuffer ) -{ - VPROF_BUDGET( "CUIProtoBufMsg::BDeserialize", VPROF_BUDGETGROUP_OTHER_VGUI ); - if ( pBuffer->GetBytesRemaining() < (int)sizeof(uint32) ) - return false; - uint32 unSize = pBuffer->GetUnsignedInt(); - - if ( unSize == 0 ) - return true; - - if ( pBuffer->GetBytesRemaining() < (int)unSize ) - return false; - - bool bSucccess = ((google::protobuf::MessageLite *)m_pMsg)->ParseFromArray( (uint8*)pBuffer->Base()+pBuffer->TellGet(), unSize ); - pBuffer->SeekGet( CUtlBuffer::SEEK_CURRENT, unSize ); - - return bSucccess; -} - diff --git a/public/html/htmlprotobuf.h b/public/html/htmlprotobuf.h deleted file mode 100644 index 38ee6400..00000000 --- a/public/html/htmlprotobuf.h +++ /dev/null @@ -1,71 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -//=============================================================================// - -#ifndef HTML_PROTOBUF -#define HTML_PROTOBUF - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier1/utlbuffer.h" -#include "html/htmlmessages.h" - -namespace google -{ - namespace protobuf - { - class MessageLite; - } -} - -class CHTMLBaseProtoBufMsg -{ -public: - void SerializeCrossProc( CUtlBuffer *pBuffer ) const; - bool BDeserializeCrossProc( CUtlBuffer *pBuffer ); - -protected: - void *m_pMsg; - bool m_bIsValid; -}; - - -//----------------------------------------------------------------------------- -// Purpose: Base class for protobuf objects -//----------------------------------------------------------------------------- -template< typename PB_OBJECT_TYPE > -class CHTMLProtoBufMsg : public CHTMLBaseProtoBufMsg -{ -public: - CHTMLProtoBufMsg( EHTMLCommands eMsg ) - { - m_pMsg = new PB_OBJECT_TYPE; - m_bIsValid = true; - } - - // Construct and deserialize in one - CHTMLProtoBufMsg( CUtlBuffer *pBuffer ) - { - m_pMsg = NULL; - m_bIsValid = BDeserializeCrossProc( pBuffer ); - } - - // Destructor - virtual ~CHTMLProtoBufMsg() - { - delete (PB_OBJECT_TYPE *)m_pMsg; - } - - bool BIsValid() { return m_bIsValid; } - - // Accessors - PB_OBJECT_TYPE &Body() { return *((PB_OBJECT_TYPE*)( (google::protobuf::MessageLite *)m_pMsg )); } - const PB_OBJECT_TYPE &BodyConst() const { return *((const PB_OBJECT_TYPE*)( (google::protobuf::MessageLite *)m_pMsg )); } - -}; - - -#endif // HTML_PROTOBUF diff --git a/public/html/ichromehtmlwrapper.h b/public/html/ichromehtmlwrapper.h deleted file mode 100644 index 6504c255..00000000 --- a/public/html/ichromehtmlwrapper.h +++ /dev/null @@ -1,63 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef ICHROMEHTMLWRAPPER_H -#define ICHROMEHTMLWRAPPER_H - -#ifdef _WIN32 -#pragma once -#endif - -#include - -class CUtlString; -class IHTMLResponses; -struct HTMLCommandBuffer_t; - - -//------------------------------------------------------------- ---------------- -// Purpose: wrapper for HTML functionality -//----------------------------------------------------------------------------- -class IHTMLChromeController -{ -public: - virtual ~IHTMLChromeController() {} - - virtual bool Init( const char *pchHTMLCacheDir, const char *pchCookiePath ) = 0; - virtual void Shutdown() = 0; - virtual bool RunFrame() = 0; - - - // set a cookie in the CEF instance. pchPath is typically "/". If nExpires is 0 then it is a session only cookie, other wise it is saved. - virtual void SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires = 0 ) = 0; - virtual void GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) = 0; - - virtual void SetClientBuildID( uint64 ulBuildID ) = 0; - - virtual bool BHasPendingMessages() = 0; - - virtual void CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) = 0; - virtual void RemoveBrowser( IHTMLResponses *pBrowser ) = 0; - - virtual void WakeThread() = 0; - virtual HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) = 0; - virtual void PushCommand( HTMLCommandBuffer_t * ) = 0; - -#ifdef DBGFLAG_VALIDATE - virtual void Validate( CValidator &validator, const char *pchName ) = 0; - - virtual bool ChromePrepareForValidate() = 0; - virtual bool ChromeResumeFromValidate() = 0; -#endif - - virtual void SetCefThreadTargetFrameRate( uint32 nFPS ) = 0; -}; - -#define CHROMEHTML_CONTROLLER_INTERFACE_VERSION "ChromeHTML_Controller_001" - - -#endif // ICHROMEHTMLWRAPPER_H \ No newline at end of file diff --git a/public/html/ihtmlchrome.h b/public/html/ihtmlchrome.h deleted file mode 100644 index d39c987b..00000000 --- a/public/html/ihtmlchrome.h +++ /dev/null @@ -1,120 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -//=============================================================================// - -#ifndef IHTMLCHROME_H -#define IHTMLCHROME_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "htmlmessages.h" -#include "tier1/utlbuffer.h" - -// prototypes for all the protobuf messages, so we don't need to include all of protobuf -class CMsgBrowserReady; -class CMsgNeedsPaint; -class CMsgStartRequest; -class CMsgURLChanged; -class CMsgFinishedRequest; -class CMsgShowPopup; -class CMsgHidePopup; -class CMsgOpenNewTab; -class CMsgPopupHTMLWindow; -class CMsgSetHTMLTitle; -class CMsgLoadingResource; -class CMsgStatusText; -class CMsgSetCursor; -class CMsgFileLoadDialog; -class CMsgShowToolTip; -class CMsgUpdateToolTip; -class CMsgHideToolTip; -class CMsgSearchResults; -class CMsgClose; -class CMsgHorizontalScrollBarSizeResponse; -class CMsgVerticalScrollBarSizeResponse; -class CMsgGetZoomResponse; -class CMsgLinkAtPositionResponse; -class CMsgZoomToElementAtPositionResponse; -class CMsgJSAlert; -class CMsgJSConfirm; -class CMsgCanGoBackAndForward; -class CMsgOpenSteamURL; -class CMsgSizePopup; -class CMsgScalePageToValueResponse; -class CMsgRequestFullScreen; -class CMsgExitFullScreen; -class CMsgGetCookiesForURLResponse; -class CMsgNodeHasFocus; -class CMsgSavePageToJPEGResponse; -class CMsgFocusedNodeTextResponse; - -//----------------------------------------------------------------------------- -// Purpose: a single IPC packet for the html thread (in and out) -//----------------------------------------------------------------------------- -struct HTMLCommandBuffer_t -{ - EHTMLCommands m_eCmd; - int m_iBrowser; - CUtlBuffer m_Buffer; -#ifdef DBGFLAG_VALIDATE - virtual void Validate( CValidator &validator, const tchar *pchName ) - { - VALIDATE_SCOPE(); - ValidateObj( m_Buffer ); - } -#endif -}; - - -//----------------------------------------------------------------------------- -// Purpose: callback interfaces for messages from the html thread -//----------------------------------------------------------------------------- -class IHTMLResponses -{ -public: - virtual ~IHTMLResponses() {} - - virtual void BrowserSetIndex( int idx ) = 0; - virtual int BrowserGetIndex() = 0; - virtual void BrowserReady( const CMsgBrowserReady *pCmd ) = 0; - virtual void BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) = 0; - virtual void BrowserStartRequest( const CMsgStartRequest *pCmd ) = 0; - virtual void BrowserURLChanged( const CMsgURLChanged *pCmd ) = 0; - virtual void BrowserFinishedRequest( const CMsgFinishedRequest *pCmd ) = 0; - virtual void BrowserShowPopup( const CMsgShowPopup *pCmd ) = 0; - virtual void BrowserHidePopup( const CMsgHidePopup *pCmd ) = 0; - virtual void BrowserOpenNewTab( const CMsgOpenNewTab *pCmd ) = 0; - virtual void BrowserPopupHTMLWindow( const CMsgPopupHTMLWindow *pCmd ) = 0; - virtual void BrowserSetHTMLTitle( const CMsgSetHTMLTitle *pCmd ) = 0; - virtual void BrowserLoadingResource( const CMsgLoadingResource *pCmd ) = 0; - virtual void BrowserStatusText( const CMsgStatusText *pCmd ) = 0; - virtual void BrowserSetCursor( const CMsgSetCursor *pCmd ) = 0; - virtual void BrowserFileLoadDialog( const CMsgFileLoadDialog *pCmd ) = 0; - virtual void BrowserShowToolTip( const CMsgShowToolTip *pCmd ) = 0; - virtual void BrowserUpdateToolTip( const CMsgUpdateToolTip *pCmd ) = 0; - virtual void BrowserHideToolTip( const CMsgHideToolTip *pCmd ) = 0; - virtual void BrowserSearchResults( const CMsgSearchResults *pCmd ) = 0; - virtual void BrowserClose( const CMsgClose *pCmd ) = 0; - virtual void BrowserHorizontalScrollBarSizeResponse( const CMsgHorizontalScrollBarSizeResponse *pCmd ) = 0; - virtual void BrowserVerticalScrollBarSizeResponse( const CMsgVerticalScrollBarSizeResponse *pCmd ) = 0; - virtual void BrowserGetZoomResponse( const CMsgGetZoomResponse *pCmd ) = 0; - virtual void BrowserLinkAtPositionResponse( const CMsgLinkAtPositionResponse *pCmd ) = 0; - virtual void BrowserZoomToElementAtPositionResponse( const CMsgZoomToElementAtPositionResponse *pCmd ) = 0; - virtual void BrowserJSAlert( const CMsgJSAlert *pCmd ) = 0; - virtual void BrowserJSConfirm( const CMsgJSConfirm *pCmd ) = 0; - virtual void BrowserCanGoBackandForward( const CMsgCanGoBackAndForward *pCmd ) = 0; - virtual void BrowserOpenSteamURL( const CMsgOpenSteamURL *pCmd ) = 0; - virtual void BrowserSizePopup( const CMsgSizePopup *pCmd ) = 0; - virtual void BrowserScalePageToValueResponse( const CMsgScalePageToValueResponse *pCmd ) = 0; - virtual void BrowserRequestFullScreen( const CMsgRequestFullScreen *pCmd ) = 0; - virtual void BrowserExitFullScreen( const CMsgExitFullScreen *pCmd ) = 0; - virtual void BrowserGetCookiesForURLResponse( const CMsgGetCookiesForURLResponse *pCmd ) = 0; - virtual void BrowserNodeGotFocus( const CMsgNodeHasFocus *pCmd ) = 0; - virtual void BrowserSavePageToJPEGResponse( const CMsgSavePageToJPEGResponse *pCmd ) = 0; - virtual void BrowserFocusedNodeValueResponse( const CMsgFocusedNodeTextResponse *pCmd ) = 0; -}; - -#endif // IHTMLCHROME_H diff --git a/public/html/ipainthtml.h b/public/html/ipainthtml.h deleted file mode 100644 index 56af78b9..00000000 --- a/public/html/ipainthtml.h +++ /dev/null @@ -1,54 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// -#ifndef IPAINTHTML_H -#define IPAINTHTML_H - -class IPaintHTML -{ -public: - enum EPaintTarget - { - ePaintBrowser, - ePaintPopup, - ePaintMAX - }; - // returns the texture id used, pass in -1 to create a new texture - virtual int DrawSubTextureRGBA( EPaintTarget eTarget, int textureID, int x, int y, const unsigned char *pRGBA, int updateWide, int updateTall, int fullTextureWide, int fullTextureTall ) = 0; - virtual void DeleteTexture( EPaintTarget eTarget, int textureID ) = 0; -}; - -class IInputEventHTML -{ -public: - enum EMouseButton - { - eButtonLeft, - eButtonMiddle, - eButtonRight - }; - - virtual bool ChromeHandleMouseClick( EMouseButton eButton, bool bUp, int nClickCount ) = 0; - virtual bool ChromeHandleMouseMove( int x, int y ) = 0; - virtual bool ChromeHandleMouseWheel( int delta ) = 0; - - enum EKeyType - { - KeyDown, - KeyUp, - Char - }; - enum EKeyModifier - { - AltDown = 1, - CrtlDown = 2, - ShiftDown = 4, - }; - - virtual bool ChromeHandleKeyEvent( EKeyType type, int key, int modifiers, bool bKeyUp ) = 0; -}; - -#endif // IPAINTHTML_H \ No newline at end of file diff --git a/public/iclientnetworkable.h b/public/iclientnetworkable.h index 5f1c6dff..c58ccd7e 100644 --- a/public/iclientnetworkable.h +++ b/public/iclientnetworkable.h @@ -99,6 +99,8 @@ public: // Tells the entity that it's about to be destroyed due to the client receiving // an uncompressed update that's caused it to destroy all entities & recreate them. virtual void SetDestroyedOnRecreateEntities( void ) = 0; + + virtual void OnDataUnchangedInPVS() = 0; }; diff --git a/public/icvar.h b/public/icvar.h index 89475b3d..b496848e 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -87,9 +87,9 @@ public: // Install a console printer virtual void InstallConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0; virtual void RemoveConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0; - virtual void ConsoleColorPrintf( const Color& clr, PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; - virtual void ConsolePrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; - virtual void ConsoleDPrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; + virtual void ConsoleColorPrintf( const Color& clr, PRINTF_FORMAT_STRING const char *pFormat, ... ) const FMTFUNCTION( 3, 4 ) = 0; + virtual void ConsolePrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const FMTFUNCTION( 2, 3 ) = 0; + virtual void ConsoleDPrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const FMTFUNCTION( 2, 3 ) = 0; // Reverts cvars which contain a specific flag virtual void RevertFlaggedConVars( int nFlag ) = 0; diff --git a/public/istudiorender.h b/public/istudiorender.h index 64935bba..7a929a8a 100644 --- a/public/istudiorender.h +++ b/public/istudiorender.h @@ -178,6 +178,16 @@ struct DrawModelResults_t CUtlVectorFixed m_Materials; }; +struct ColorTexelsInfo_t +{ + int m_nWidth; + int m_nHeight; + int m_nMipmapCount; + ImageFormat m_ImageFormat; + int m_nByteCount; + byte* m_pTexelData; +}; + struct ColorMeshInfo_t { // A given color mesh can own a unique Mesh, or it can use a shared Mesh @@ -186,6 +196,8 @@ struct ColorMeshInfo_t IPooledVBAllocator * m_pPooledVBAllocator; int m_nVertOffsetInBytes; int m_nNumVerts; + ITexture * m_pLightmap; + ColorTexelsInfo_t * m_pLightmapData; }; struct DrawModelInfo_t diff --git a/public/materialsystem/imaterialsystem.h b/public/materialsystem/imaterialsystem.h index 92e7313e..907da447 100644 --- a/public/materialsystem/imaterialsystem.h +++ b/public/materialsystem/imaterialsystem.h @@ -1039,6 +1039,10 @@ public: // returns the display device name that matches the adapter index we were started with virtual char *GetDisplayDeviceName() const = 0; + + // creates a texture suitable for use with materials from a raw stream of bits. + // The bits will be retained by the material system and can be freed upon return. + virtual ITexture* CreateTextureFromBits(int w, int h, int mips, ImageFormat fmt, int srcBufferSize, byte* srcBits) = 0; }; diff --git a/public/materialsystem/imesh.h b/public/materialsystem/imesh.h index 7ee35de9..33571240 100644 --- a/public/materialsystem/imesh.h +++ b/public/materialsystem/imesh.h @@ -3329,6 +3329,8 @@ inline void CMeshBuilder::ComputeNumVertsAndIndices( int *pMaxVertices, int *pMa break; default: + *pMaxVertices = 0; + *pMaxIndices = 0; Assert(0); } diff --git a/public/mathlib/mathlib.h b/public/mathlib/mathlib.h index e1873cd0..7d09a1fb 100644 --- a/public/mathlib/mathlib.h +++ b/public/mathlib/mathlib.h @@ -457,7 +457,7 @@ void inline SinCos( float radians, float *sine, float *cosine ) *sine = sin( radians ); *cosine = cos( radians ); #elif defined( POSIX ) - register double __cosr, __sinr; + double __cosr, __sinr; __asm ("fsincos" : "=t" (__cosr), "=u" (__sinr) : "0" (radians)); *sine = __sinr; diff --git a/public/mathlib/vmatrix.h b/public/mathlib/vmatrix.h index e4a17e76..2de2c98b 100644 --- a/public/mathlib/vmatrix.h +++ b/public/mathlib/vmatrix.h @@ -107,7 +107,6 @@ public: void PreTranslate(const Vector &vTrans); void PostTranslate(const Vector &vTrans); - matrix3x4_t& As3x4(); const matrix3x4_t& As3x4() const; void CopyFrom3x4( const matrix3x4_t &m3x4 ); void Set3x4( matrix3x4_t& matrix3x4 ) const; @@ -630,11 +629,6 @@ inline const matrix3x4_t& VMatrix::As3x4() const return *((const matrix3x4_t*)this); } -inline matrix3x4_t& VMatrix::As3x4() -{ - return *((matrix3x4_t*)this); -} - inline void VMatrix::CopyFrom3x4( const matrix3x4_t &m3x4 ) { memcpy( m, m3x4.Base(), sizeof( matrix3x4_t ) ); diff --git a/public/matsys_controls/mdlpanel.h b/public/matsys_controls/mdlpanel.h index cac6d2c5..9909a877 100644 --- a/public/matsys_controls/mdlpanel.h +++ b/public/matsys_controls/mdlpanel.h @@ -130,6 +130,7 @@ private: virtual void OnPaint3D(); virtual void PrePaint3D( IMatRenderContext *pRenderContext ) { }; virtual void PostPaint3D( IMatRenderContext *pRenderContext ) { }; + virtual void RenderingRootModel( IMatRenderContext *pRenderContext, CStudioHdr *pStudioHdr, MDLHandle_t mdlHandle, matrix3x4_t *pWorldMatrix ) { }; virtual void RenderingMergedModel( IMatRenderContext *pRenderContext, CStudioHdr *pStudioHdr, MDLHandle_t mdlHandle, matrix3x4_t *pWorldMatrix ) { }; void OnMouseDoublePressed( vgui::MouseCode code ); diff --git a/public/networkvar.h b/public/networkvar.h index dc3e0ee6..7c99b0c2 100644 --- a/public/networkvar.h +++ b/public/networkvar.h @@ -456,7 +456,7 @@ public: SetX( ix ); SetY( iy ); SetZ( iz ); - SetZ( iw ); + SetW( iw ); } const Type& operator=( const Type &val ) diff --git a/public/p4lib/ip4.h b/public/p4lib/ip4.h index d3c500a1..64262d00 100644 --- a/public/p4lib/ip4.h +++ b/public/p4lib/ip4.h @@ -39,6 +39,7 @@ struct P4File_t CUtlSymbol m_sDepotFile; // the name in the depot CUtlSymbol m_sClientFile; // the name on the client in Perforce syntax CUtlSymbol m_sLocalFile; // the name on the client in local syntax + CUtlSymbol m_sFileType; // the type according to the server, see p4 help filetypes int m_iHeadRevision; // head revision number int m_iHaveRevision; // the revision the clientspec has synced locally bool m_bDir; // directory @@ -78,9 +79,7 @@ struct P4Client_t //----------------------------------------------------------------------------- // Purpose: Interface to accessing P4 commands //----------------------------------------------------------------------------- -#define P4_INTERFACE_VERSION "VP4001" -// Vitaliy - 09-Feb-'07: if anybody ups the version of this interface, please -// move the method "SetOpenFileChangeList" into the appropriate section. +#define P4_INTERFACE_VERSION "VP4002" abstract_class IP4 : public IAppSystem { @@ -116,6 +115,9 @@ public: // changes the clientspec to remove the specified path (cloaking) virtual void RemovePathFromActiveClientspec( const char *path ) = 0; + // sets the name of the changelist to open files under, NULL for "Default" changelist + virtual void SetOpenFileChangeList(const char *pChangeListName) = 0; + // file manipulation virtual bool OpenFileForAdd( const char *pFullPath ) = 0; virtual bool OpenFileForEdit( const char *pFullPath ) = 0; @@ -173,15 +175,17 @@ public: // Returns file information for a single file virtual bool GetFileInfo( const char *pFullPath, P4File_t *pFileInfo ) = 0; + // Reopens a file for edit or add with the specified filetype. To see the valid strings for + // filetypes, see p4 help fileinfo. Perforce has to know about files before the filetype can + // be changed (so for new files, they must be added first, then the filetype modified). + virtual bool SetFileType( const char *pFullPath, const char *pFileType ) = 0; + // retreives the list of files in a path, using a known client spec virtual CUtlVector &GetFileListUsingClientSpec( const char *pPath, const char *pClientSpec ) = 0; // retrieves the last error from the last op (which is likely to span multiple lines) // this is only valid after OpenFile[s]For{Add,Edit,Delete} or {Submit,Revert}File[s] virtual const char *GetLastError() = 0; - - // sets the name of the changelist to open files under, NULL for "Default" changelist - virtual void SetOpenFileChangeList( const char *pChangeListName ) = 0; }; diff --git a/public/pixelwriter.h b/public/pixelwriter.h index 64b46c56..00c7f554 100644 --- a/public/pixelwriter.h +++ b/public/pixelwriter.h @@ -331,6 +331,14 @@ FORCEINLINE_PIXEL void CPixelWriter::SetPixelMemory( ImageFormat format, void* p format_error_printed[format] = true; } m_Size = 0; // set to zero so that we don't stomp memory for formats that we don't understand. + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0x00; + m_GMask = 0x00; + m_BMask = 0x00; + m_AMask = 0x00; } break; } diff --git a/public/saverestoretypes.h b/public/saverestoretypes.h index 2b355b66..b4a95ed5 100644 --- a/public/saverestoretypes.h +++ b/public/saverestoretypes.h @@ -514,8 +514,8 @@ inline const char *CSaveRestoreSegment::StringFromSymbol( int token ) #ifndef _WIN32 inline unsigned CSaveRestoreSegment::_rotr ( unsigned val, int shift) { - register unsigned lobit; /* non-zero means lo bit set */ - register unsigned num = val; /* number to rotate */ + unsigned lobit; /* non-zero means lo bit set */ + unsigned num = val; /* number to rotate */ shift &= 0x1f; /* modulo 32 -- this will also make negative shifts work */ diff --git a/public/sentence.cpp b/public/sentence.cpp index 2f833952..e9f17fb7 100644 --- a/public/sentence.cpp +++ b/public/sentence.cpp @@ -1678,7 +1678,7 @@ bool CSentence::ShouldSplitWord( char in ) if ( in <= 32 ) return true; - if ( in >= 128 ) + if ( (unsigned char)in > SCHAR_MAX ) return true; if ( ispunct( in ) ) diff --git a/public/shaderapi/ishaderdynamic.h b/public/shaderapi/ishaderdynamic.h index 090ee0c3..fafa2a59 100644 --- a/public/shaderapi/ishaderdynamic.h +++ b/public/shaderapi/ishaderdynamic.h @@ -36,7 +36,8 @@ struct LightState_t { int m_nNumLights; bool m_bAmbientLight; - bool m_bStaticLight; + bool m_bStaticLightVertex; + bool m_bStaticLightTexel; inline int HasDynamicLight() { return (m_bAmbientLight || (m_nNumLights > 0)) ? 1 : 0; } }; @@ -106,6 +107,9 @@ enum StandardTextureId_t // A snapshot of the frame buffer's depth. Currently only valid on the 360 TEXTURE_IDENTITY_LIGHTWARP, + // Equivalent to the debug material for mat_luxels, in convenient texture form. + TEXTURE_DEBUG_LUXELS, + TEXTURE_MAX_STD_TEXTURES = 32 }; diff --git a/public/shaderlib/BaseShader.h b/public/shaderlib/BaseShader.h index 56d56d37..b79391a4 100644 --- a/public/shaderlib/BaseShader.h +++ b/public/shaderlib/BaseShader.h @@ -168,6 +168,8 @@ public: void BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrame = 0 ); void BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrame = 0 ); + void GetTextureDimensions( float* pOutWidth, float* pOutHeight, int nTextureVar ); + // Is the texture translucent? bool TextureIsTranslucent( int textureVar, bool isBaseTexture ); diff --git a/public/shaderlib/cshader.h b/public/shaderlib/cshader.h index a3165f8a..c1274750 100644 --- a/public/shaderlib/cshader.h +++ b/public/shaderlib/cshader.h @@ -314,10 +314,12 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // FIXME: There's a compiler bug preventing this from working. // Maybe it'll work under VC7! +/* //#define BEGIN_INHERITED_SHADER( name, _baseclass, help ) \ // namespace _baseclass \ // {\ // __BEGIN_SHADER_INTERNAL( _baseclass::CShader, name, help ) +*/ //#define END_INHERITED_SHADER END_SHADER } @@ -354,14 +356,14 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // psh ## shader is used here to generate a warning if you don't ever call SET_DYNAMIC_PIXEL_SHADER #define DECLARE_DYNAMIC_PIXEL_SHADER( shader ) \ int declaredynpixshader_ ## shader ## _missingcurlybraces = 0; \ - declaredynpixshader_ ## shader ## _missingcurlybraces = declaredynpixshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( declaredynpixshader_ ## shader ## _missingcurlybraces ); \ shader ## _Dynamic_Index _pshIndex; \ int psh ## shader = 0 // vsh ## shader is used here to generate a warning if you don't ever call SET_DYNAMIC_VERTEX_SHADER #define DECLARE_DYNAMIC_VERTEX_SHADER( shader ) \ int declaredynvertshader_ ## shader ## _missingcurlybraces = 0; \ - declaredynvertshader_ ## shader ## _missingcurlybraces = declaredynvertshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( declaredynvertshader_ ## shader ## _missingcurlybraces ); \ shader ## _Dynamic_Index _vshIndex; \ int vsh ## shader = 0 @@ -369,14 +371,14 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // psh ## shader is used here to generate a warning if you don't ever call SET_STATIC_PIXEL_SHADER #define DECLARE_STATIC_PIXEL_SHADER( shader ) \ int declarestaticpixshader_ ## shader ## _missingcurlybraces = 0; \ - declarestaticpixshader_ ## shader ## _missingcurlybraces = declarestaticpixshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( declarestaticpixshader_ ## shader ## _missingcurlybraces ); \ shader ## _Static_Index _pshIndex; \ int psh ## shader = 0 // vsh ## shader is used here to generate a warning if you don't ever call SET_STATIC_VERTEX_SHADER #define DECLARE_STATIC_VERTEX_SHADER( shader ) \ int declarestaticvertshader_ ## shader ## _missingcurlybraces = 0; \ - declarestaticvertshader_ ## shader ## _missingcurlybraces = declarestaticvertshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( declarestaticvertshader_ ## shader ## _missingcurlybraces ); \ shader ## _Static_Index _vshIndex; \ int vsh ## shader = 0 @@ -386,7 +388,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // in the SET_DYNAMIC_PIXEL_SHADER block. #define SET_DYNAMIC_PIXEL_SHADER_COMBO( var, val ) \ int dynpixshadercombo_ ## var ## _missingcurlybraces = 0; \ - dynpixshadercombo_ ## var ## _missingcurlybraces = dynpixshadercombo_ ## var ## _missingcurlybraces; \ + NOTE_UNUSED( dynpixshadercombo_ ## var ## _missingcurlybraces ); \ _pshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n PS dyn var %s = %d (%s)", #var, (int) val, #val );}; \ int psh_forgot_to_set_dynamic_ ## var = 0 @@ -395,7 +397,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // in the SET_DYNAMIC_VERTEX_SHADER block. #define SET_DYNAMIC_VERTEX_SHADER_COMBO( var, val ) \ int dynvertshadercombo_ ## var ## _missingcurlybraces = 0; \ - dynvertshadercombo_ ## var ## _missingcurlybraces = dynvertshadercombo_ ## var ## _missingcurlybraces; \ + NOTE_UNUSED( dynvertshadercombo_ ## var ## _missingcurlybraces ); \ _vshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n VS dyn var %s = %d (%s)", #var, (int) val, #val );}; \ int vsh_forgot_to_set_dynamic_ ## var = 0 @@ -405,7 +407,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // in the SET_STATIC_PIXEL_SHADER block. #define SET_STATIC_PIXEL_SHADER_COMBO( var, val ) \ int staticpixshadercombo_ ## var ## _missingcurlybraces = 0; \ - staticpixshadercombo_ ## var ## _missingcurlybraces = staticpixshadercombo_ ## var ## _missingcurlybraces; \ + NOTE_UNUSED( staticpixshadercombo_ ## var ## _missingcurlybraces ); \ _pshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n PS stat var %s = %d (%s)", #var, (int) val, #val );}; \ int psh_forgot_to_set_static_ ## var = 0 @@ -414,7 +416,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // in the SET_STATIC_VERTEX_SHADER block. #define SET_STATIC_VERTEX_SHADER_COMBO( var, val ) \ int staticvertshadercombo_ ## var ## _missingcurlybraces = 0; \ - staticvertshadercombo_ ## var ## _missingcurlybraces = staticvertshadercombo_ ## var ## _missingcurlybraces; \ + NOTE_UNUSED( staticvertshadercombo_ ## var ## _missingcurlybraces ); \ _vshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n VS stat var %s = %d (%s)", #var, (int) val, #val );}; \ int vsh_forgot_to_set_static_ ## var = 0 @@ -426,18 +428,18 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // was called for this particular shader. #define SET_DYNAMIC_PIXEL_SHADER( shader ) \ int dynamicpixshader_ ## shader ## _missingcurlybraces = 0; \ - dynamicpixshader_ ## shader ## _missingcurlybraces = dynamicpixshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( dynamicpixshader_ ## shader ## _missingcurlybraces ); \ int psh_testAllCombos = shaderDynamicTest_ ## shader; \ - psh_testAllCombos = psh_testAllCombos; \ - psh ## shader = psh ## shader; \ + NOTE_UNUSED( psh_testAllCombos ); \ + NOTE_UNUSED( psh ## shader ); \ pShaderAPI->SetPixelShaderIndex( _pshIndex.GetIndex() ) #define SET_DYNAMIC_PIXEL_SHADER_CMD( cmdstream, shader ) \ int dynamicpixshader_ ## shader ## _missingcurlybraces = 0; \ - dynamicpixshader_ ## shader ## _missingcurlybraces = dynamicpixshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( dynamicpixshader_ ## shader ## _missingcurlybraces ); \ int psh_testAllCombos = shaderDynamicTest_ ## shader; \ - psh_testAllCombos = psh_testAllCombos; \ - psh ## shader = psh ## shader; \ + NOTE_UNUSED( psh_testAllCombos ); \ + NOTE_UNUSED( psh ## shader ); \ cmdstream.SetPixelShaderIndex( _pshIndex.GetIndex() ) @@ -448,18 +450,18 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // was called for this particular shader. #define SET_DYNAMIC_VERTEX_SHADER( shader ) \ int dynamicvertshader_ ## shader ## _missingcurlybraces = 0; \ - dynamicvertshader_ ## shader ## _missingcurlybraces = dynamicvertshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( dynamicvertshader_ ## shader ## _missingcurlybraces ); \ int vsh_testAllCombos = shaderDynamicTest_ ## shader; \ - vsh_testAllCombos = vsh_testAllCombos; \ - vsh ## shader = vsh ## shader; \ + NOTE_UNUSED( vsh_testAllCombos ); \ + NOTE_UNUSED( vsh ## shader ); \ pShaderAPI->SetVertexShaderIndex( _vshIndex.GetIndex() ) #define SET_DYNAMIC_VERTEX_SHADER_CMD( cmdstream, shader ) \ int dynamicvertshader_ ## shader ## _missingcurlybraces = 0; \ - dynamicvertshader_ ## shader ## _missingcurlybraces = dynamicvertshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( dynamicvertshader_ ## shader ## _missingcurlybraces ); \ int vsh_testAllCombos = shaderDynamicTest_ ## shader; \ - vsh_testAllCombos = vsh_testAllCombos; \ - vsh ## shader = vsh ## shader; \ + NOTE_UNUSED( vsh_testAllCombos ); \ + NOTE_UNUSED( vsh ## shader ); \ cmdstream.SetVertexShaderIndex( _vshIndex.GetIndex() ) @@ -470,10 +472,10 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // was called for this particular shader. #define SET_STATIC_PIXEL_SHADER( shader ) \ int staticpixshader_ ## shader ## _missingcurlybraces = 0; \ - staticpixshader_ ## shader ## _missingcurlybraces = staticpixshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( staticpixshader_ ## shader ## _missingcurlybraces ); \ int psh_testAllCombos = shaderStaticTest_ ## shader; \ - psh_testAllCombos = psh_testAllCombos; \ - psh ## shader = psh ## shader; \ + NOTE_UNUSED( psh_testAllCombos ); \ + NOTE_UNUSED( psh ## shader ); \ pShaderShadow->SetPixelShader( #shader, _pshIndex.GetIndex() ) // vsh_testAllCombos adds up all of the vsh_forgot_to_set_static_ ## var's from @@ -483,10 +485,10 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // was called for this particular shader. #define SET_STATIC_VERTEX_SHADER( shader ) \ int staticvertshader_ ## shader ## _missingcurlybraces = 0; \ - staticvertshader_ ## shader ## _missingcurlybraces = staticvertshader_ ## shader ## _missingcurlybraces; \ + NOTE_UNUSED( staticvertshader_ ## shader ## _missingcurlybraces ); \ int vsh_testAllCombos = shaderStaticTest_ ## shader; \ - vsh_testAllCombos = vsh_testAllCombos; \ - vsh ## shader = vsh ## shader; \ + NOTE_UNUSED( vsh_testAllCombos ); \ + NOTE_UNUSED( vsh ## shader ); \ pShaderShadow->SetVertexShader( #shader, _vshIndex.GetIndex() ) #endif // CSHADER_H diff --git a/public/sourcevr/isourcevirtualreality.h b/public/sourcevr/isourcevirtualreality.h index 4ec0c149..6a27bbac 100644 --- a/public/sourcevr/isourcevirtualreality.h +++ b/public/sourcevr/isourcevirtualreality.h @@ -150,7 +150,9 @@ public: // ---------------------------------------------------------------------- virtual bool Activate() = 0; virtual void Deactivate() = 0; - + + virtual bool ShouldForceVRMode() = 0; + virtual void SetShouldForceVRMode() = 0; }; @@ -165,4 +167,9 @@ inline bool UseVR() return g_pSourceVR != NULL && g_pSourceVR->ShouldRunInVR(); } +inline bool ShouldForceVRActive() +{ + return g_pSourceVR != NULL && g_pSourceVR->ShouldForceVRMode(); +} + #endif // ISOURCEVIRTUALREALITY_H diff --git a/public/steam/isteamapps.h b/public/steam/isteamapps.h index 4b985194..82ef788e 100644 --- a/public/steam/isteamapps.h +++ b/public/steam/isteamapps.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: interface to app data in Steam // @@ -59,10 +59,19 @@ public: virtual bool GetCurrentBetaName( char *pchName, int cchNameBufferSize ) = 0; // returns current beta branch name, 'public' is the default branch virtual bool MarkContentCorrupt( bool bMissingFilesOnly ) = 0; // signal Steam that game files seems corrupt or missing - virtual uint32 GetInstalledDepots( DepotId_t *pvecDepots, uint32 cMaxDepots ) = 0; // return installed depots in mount order + virtual uint32 GetInstalledDepots( AppId_t appID, DepotId_t *pvecDepots, uint32 cMaxDepots ) = 0; // return installed depots in mount order // returns current app install folder for AppID, returns folder name length virtual uint32 GetAppInstallDir( AppId_t appID, char *pchFolder, uint32 cchFolderBufferSize ) = 0; + virtual bool BIsAppInstalled( AppId_t appID ) = 0; // returns true if that app is installed (not necessarily owned) + + virtual CSteamID GetAppOwner() = 0; // returns the SteamID of the original owner. If different from current user, it's borrowed + + // Returns the associated launch param if the game is run via steam://run///?param1=value1;param2=value2;param3=value3 etc. + // Parameter names starting with the character '@' are reserved for internal use and will always return and empty string. + // Parameter names starting with an underscore '_' are reserved for steam features -- they can be queried by the game, + // but it is advised that you not param names beginning with an underscore for your own features. + virtual const char *GetLaunchQueryParam( const char *pchKey ) = 0; #ifdef _PS3 // Result returned in a RegisterActivationCodeResponse_t callresult @@ -70,7 +79,7 @@ public: #endif }; -#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION005" +#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION006" // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -123,5 +132,18 @@ struct AppProofOfPurchaseKeyResponse_t uint32 m_nAppID; char m_rgchKey[ k_cubAppProofOfPurchaseKeyMax ]; }; + +//--------------------------------------------------------------------------------- +// Purpose: posted after the user gains executes a steam url with query parameters +// such as steam://run///?param1=value1;param2=value2;param3=value3; etc +// while the game is already running. The new params can be queried +// with GetLaunchQueryParam. +//--------------------------------------------------------------------------------- +struct NewLaunchQueryParameters_t +{ + enum { k_iCallback = k_iSteamAppsCallbacks + 14 }; +}; + + #pragma pack( pop ) #endif // ISTEAMAPPS_H diff --git a/public/steam/isteamclient.h b/public/steam/isteamclient.h index 952b1eba..a14948b6 100644 --- a/public/steam/isteamclient.h +++ b/public/steam/isteamclient.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: Main interface for loading and accessing Steamworks API's from the // Steam client. @@ -17,6 +17,10 @@ // Define compile time assert macros to let us validate the structure sizes. #define VALVE_COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1]; +#ifndef REFERENCE +#define REFERENCE(arg) ((void)arg) +#endif + #if defined(__linux__) || defined(__APPLE__) // The 32-bit version of gcc has the alignment requirement for uint64 and double set to // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. @@ -65,7 +69,8 @@ typedef int32 HSteamUser; #define __cdecl #endif extern "C" typedef void (__cdecl *SteamAPIWarningMessageHook_t)(int, const char *); - +extern "C" typedef void( *SteamAPI_PostAPIResultInProcess_t )(SteamAPICall_t callHandle, void *, uint32 unCallbackSize, int iCallbackNum); +extern "C" typedef uint32 ( *SteamAPI_CheckCallbackRegistered_t )( int iCallbackNum ); #if defined( __SNC__ ) #pragma diag_suppress=1700 // warning 1700: class "%s" has virtual functions but non-virtual destructor #endif @@ -83,10 +88,16 @@ class ISteamApps; class ISteamNetworking; class ISteamRemoteStorage; class ISteamScreenshots; +class ISteamMusic; +class ISteamMusicRemote; class ISteamGameServerStats; class ISteamPS3OverlayRender; class ISteamHTTP; class ISteamUnifiedMessages; +class ISteamController; +class ISteamUGC; +class ISteamAppList; +class ISteamHTMLSurface; //----------------------------------------------------------------------------- // Purpose: Interface to creating a new steam instance, or to @@ -159,7 +170,6 @@ public: // user screenshots virtual ISteamScreenshots *GetISteamScreenshots( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; - // this needs to be called every frame to process matchmaking results // redundant if you're already calling SteamAPI_RunCallbacks() virtual void RunFrame() = 0; @@ -189,9 +199,31 @@ public: // Exposes the ISteamUnifiedMessages interface virtual ISteamUnifiedMessages *GetISteamUnifiedMessages( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + // Exposes the ISteamController interface + virtual ISteamController *GetISteamController( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + + // Exposes the ISteamUGC interface + virtual ISteamUGC *GetISteamUGC( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + + // returns app list interface, only available on specially registered apps + virtual ISteamAppList *GetISteamAppList( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + + // Music Player + virtual ISteamMusic *GetISteamMusic( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + + // Music Player Remote + virtual ISteamMusicRemote *GetISteamMusicRemote(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion) = 0; + + // html page display + virtual ISteamHTMLSurface *GetISteamHTMLSurface(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion) = 0; + + // Helper functions for internal Steam usage + virtual void Set_SteamAPI_CPostAPIResultInProcess( SteamAPI_PostAPIResultInProcess_t func ) = 0; + virtual void Remove_SteamAPI_CPostAPIResultInProcess( SteamAPI_PostAPIResultInProcess_t func ) = 0; + virtual void Set_SteamAPI_CCheckCallbackRegisteredInProcess( SteamAPI_CheckCallbackRegistered_t func ) = 0; }; -#define STEAMCLIENT_INTERFACE_VERSION "SteamClient012" +#define STEAMCLIENT_INTERFACE_VERSION "SteamClient016" //----------------------------------------------------------------------------- // Purpose: Base values for callback identifiers, each callback must @@ -210,7 +242,7 @@ enum { k_iSteamAppsCallbacks = 1000 }; enum { k_iSteamUserStatsCallbacks = 1100 }; enum { k_iSteamNetworkingCallbacks = 1200 }; enum { k_iClientRemoteStorageCallbacks = 1300 }; -enum { k_iSteamUserItemsCallbacks = 1400 }; +enum { k_iClientDepotBuilderCallbacks = 1400 }; enum { k_iSteamGameServerItemsCallbacks = 1500 }; enum { k_iClientUtilsCallbacks = 1600 }; enum { k_iSteamGameCoordinatorCallbacks = 1700 }; @@ -228,7 +260,21 @@ enum { k_iSteamControllerCallbacks = 2800 }; enum { k_iClientParentalSettingsCallbacks = 2900 }; enum { k_iClientDeviceAuthCallbacks = 3000 }; enum { k_iClientNetworkDeviceManagerCallbacks = 3100 }; - +enum { k_iClientMusicCallbacks = 3200 }; +enum { k_iClientRemoteClientManagerCallbacks = 3300 }; +enum { k_iClientUGCCallbacks = 3400 }; +enum { k_iSteamStreamClientCallbacks = 3500 }; +enum { k_IClientProductBuilderCallbacks = 3600 }; +enum { k_iClientShortcutsCallbacks = 3700 }; +enum { k_iClientRemoteControlManagerCallbacks = 3800 }; +enum { k_iSteamAppListCallbacks = 3900 }; +enum { k_iSteamMusicCallbacks = 4000 }; +enum { k_iSteamMusicRemoteCallbacks = 4100 }; +enum { k_iClientVRCallbacks = 4200 }; +enum { k_iClientReservedCallbacks = 4300 }; +enum { k_iSteamReservedCallbacks = 4400 }; +enum { k_iSteamHTMLSurfaceCallbacks = 4500 }; +enum { k_iClientVideoCallbacks = 4600 }; //----------------------------------------------------------------------------- // The CALLBACK macros are for client side callback logging enabled with @@ -236,21 +282,18 @@ enum { k_iClientNetworkDeviceManagerCallbacks = 3100 }; // Do not change any of these. //----------------------------------------------------------------------------- -class CSteamCallback +struct SteamCallback_t { public: - virtual const char *GetCallbackName() const = 0; - virtual uint32 GetCallbackID() const = 0; - virtual uint8 *GetFixedData() const = 0; - virtual uint32 GetFixedSize() const = 0; - virtual uint32 GetNumMemberVariables() const = 0; - virtual bool GetMemberVariable( uint32 index, uint32 &varOffset, uint32 &varSize, uint32 &varCount, const char **pszName, const char **pszType ) const = 0; + SteamCallback_t() {} }; #define DEFINE_CALLBACK( callbackname, callbackid ) \ -struct callbackname##_t { \ +struct callbackname : SteamCallback_t { \ enum { k_iCallback = callbackid }; \ - static callbackname##_t *GetNullPointer() { return 0; } + static callbackname *GetNullPointer() { return 0; } \ + static const char *GetCallbackName() { return #callbackname; } \ + static uint32 GetCallbackID() { return callbackname::k_iCallback; } #define CALLBACK_MEMBER( varidx, vartype, varname ) \ public: vartype varname ; \ @@ -269,64 +312,60 @@ struct callbackname##_t { \ *pszName = #varname; *pszType = #vartype; } -#define END_CALLBACK_INTERNAL_BEGIN( callbackname, numvars ) }; \ -class C##callbackname : public CSteamCallback { \ -public: callbackname##_t m_Data; \ - C##callbackname () { memset( &m_Data, 0, sizeof(m_Data) ); } \ - virtual const char *GetCallbackName() const { return #callbackname; } \ - virtual uint32 GetCallbackID() const { return callbackname##_t::k_iCallback; } \ - virtual uint32 GetFixedSize() const { return sizeof( m_Data ); } \ - virtual uint8 *GetFixedData() const { return (uint8*)&m_Data; } \ - virtual uint32 GetNumMemberVariables() const { return numvars; } \ - virtual bool GetMemberVariable( uint32 index, uint32 &varOffset, uint32 &varSize, uint32 &varCount, const char **pszName, const char **pszType ) const { \ +#define END_CALLBACK_INTERNAL_BEGIN( numvars ) \ + static uint32 GetNumMemberVariables() { return numvars; } \ + static bool GetMemberVariable( uint32 index, uint32 &varOffset, uint32 &varSize, uint32 &varCount, const char **pszName, const char **pszType ) { \ switch ( index ) { default : return false; -#define END_CALLBACK_INTERNAL_SWITCH( varidx ) case varidx : m_Data.GetMemberVar_##varidx( varOffset, varSize, varCount, pszName, pszType ); return true; +#define END_CALLBACK_INTERNAL_SWITCH( varidx ) case varidx : GetMemberVar_##varidx( varOffset, varSize, varCount, pszName, pszType ); return true; -#define END_CALLBACK_INTERNAL_END() }; }; }; +#define END_CALLBACK_INTERNAL_END() }; } }; -#define END_DEFINE_CALLBACK_0( callbackname ) }; \ -class C##callbackname : public CSteamCallback { \ -public: callbackname##_t m_Data; \ - virtual const char *GetCallbackName() const { return #callbackname; } \ - virtual uint32 GetCallbackID() const { return callbackname##_t::k_iCallback; } \ - virtual uint32 GetFixedSize() const { return sizeof( m_Data ); } \ - virtual uint8 *GetFixedData() const { return (uint8*)&m_Data; } \ - virtual uint32 GetNumMemberVariables() const { return 0; } \ - virtual bool GetMemberVariable( uint32 index, uint32 &varOffset, uint32 &varSize, uint32 &varCount, const char **pszName, const char **pszType ) const { return false; } \ - }; \ +#define END_DEFINE_CALLBACK_0() \ + static uint32 GetNumMemberVariables() { return 0; } \ + static bool GetMemberVariable( uint32 index, uint32 &varOffset, uint32 &varSize, uint32 &varCount, const char **pszName, const char **pszType ) { REFERENCE( pszType ); REFERENCE( pszName ); REFERENCE( varCount ); REFERENCE( varSize ); REFERENCE( varOffset ); REFERENCE( index ); return false; } \ + }; -#define END_DEFINE_CALLBACK_1( callbackname ) \ - END_CALLBACK_INTERNAL_BEGIN( callbackname, 1 ) \ +#define END_DEFINE_CALLBACK_1() \ + END_CALLBACK_INTERNAL_BEGIN( 1 ) \ END_CALLBACK_INTERNAL_SWITCH( 0 ) \ END_CALLBACK_INTERNAL_END() -#define END_DEFINE_CALLBACK_2( callbackname ) \ - END_CALLBACK_INTERNAL_BEGIN( callbackname, 2 ) \ +#define END_DEFINE_CALLBACK_2() \ + END_CALLBACK_INTERNAL_BEGIN( 2 ) \ END_CALLBACK_INTERNAL_SWITCH( 0 ) \ END_CALLBACK_INTERNAL_SWITCH( 1 ) \ END_CALLBACK_INTERNAL_END() -#define END_DEFINE_CALLBACK_3( callbackname ) \ - END_CALLBACK_INTERNAL_BEGIN( callbackname, 3 ) \ +#define END_DEFINE_CALLBACK_3() \ + END_CALLBACK_INTERNAL_BEGIN( 3 ) \ END_CALLBACK_INTERNAL_SWITCH( 0 ) \ END_CALLBACK_INTERNAL_SWITCH( 1 ) \ END_CALLBACK_INTERNAL_SWITCH( 2 ) \ END_CALLBACK_INTERNAL_END() -#define END_DEFINE_CALLBACK_4( callbackname ) \ - END_CALLBACK_INTERNAL_BEGIN( callbackname, 4 ) \ +#define END_DEFINE_CALLBACK_4() \ + END_CALLBACK_INTERNAL_BEGIN( 4 ) \ END_CALLBACK_INTERNAL_SWITCH( 0 ) \ END_CALLBACK_INTERNAL_SWITCH( 1 ) \ END_CALLBACK_INTERNAL_SWITCH( 2 ) \ END_CALLBACK_INTERNAL_SWITCH( 3 ) \ END_CALLBACK_INTERNAL_END() +#define END_DEFINE_CALLBACK_5() \ + END_CALLBACK_INTERNAL_BEGIN( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_END() -#define END_DEFINE_CALLBACK_6( callbackname ) \ - END_CALLBACK_INTERNAL_BEGIN( callbackname, 6 ) \ + +#define END_DEFINE_CALLBACK_6() \ + END_CALLBACK_INTERNAL_BEGIN( 6 ) \ END_CALLBACK_INTERNAL_SWITCH( 0 ) \ END_CALLBACK_INTERNAL_SWITCH( 1 ) \ END_CALLBACK_INTERNAL_SWITCH( 2 ) \ @@ -335,8 +374,8 @@ public: callbackname##_t m_Data; \ END_CALLBACK_INTERNAL_SWITCH( 5 ) \ END_CALLBACK_INTERNAL_END() -#define END_DEFINE_CALLBACK_7( callbackname ) \ - END_CALLBACK_INTERNAL_BEGIN( callbackname, 7 ) \ +#define END_DEFINE_CALLBACK_7() \ + END_CALLBACK_INTERNAL_BEGIN( 7 ) \ END_CALLBACK_INTERNAL_SWITCH( 0 ) \ END_CALLBACK_INTERNAL_SWITCH( 1 ) \ END_CALLBACK_INTERNAL_SWITCH( 2 ) \ @@ -346,4 +385,109 @@ public: callbackname##_t m_Data; \ END_CALLBACK_INTERNAL_SWITCH( 6 ) \ END_CALLBACK_INTERNAL_END() +#define END_DEFINE_CALLBACK_8() \ + END_CALLBACK_INTERNAL_BEGIN( 8 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 5 ) \ + END_CALLBACK_INTERNAL_SWITCH( 6 ) \ + END_CALLBACK_INTERNAL_SWITCH( 7 ) \ + END_CALLBACK_INTERNAL_END() + +#define END_DEFINE_CALLBACK_9() \ + END_CALLBACK_INTERNAL_BEGIN( 9 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 5 ) \ + END_CALLBACK_INTERNAL_SWITCH( 6 ) \ + END_CALLBACK_INTERNAL_SWITCH( 7 ) \ + END_CALLBACK_INTERNAL_SWITCH( 8 ) \ + END_CALLBACK_INTERNAL_END() + +#define END_DEFINE_CALLBACK_10() \ + END_CALLBACK_INTERNAL_BEGIN( 10 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 5 ) \ + END_CALLBACK_INTERNAL_SWITCH( 6 ) \ + END_CALLBACK_INTERNAL_SWITCH( 7 ) \ + END_CALLBACK_INTERNAL_SWITCH( 8 ) \ + END_CALLBACK_INTERNAL_SWITCH( 9 ) \ + END_CALLBACK_INTERNAL_END() + +#define END_DEFINE_CALLBACK_11() \ + END_CALLBACK_INTERNAL_BEGIN( 11 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 5 ) \ + END_CALLBACK_INTERNAL_SWITCH( 6 ) \ + END_CALLBACK_INTERNAL_SWITCH( 7 ) \ + END_CALLBACK_INTERNAL_SWITCH( 8 ) \ + END_CALLBACK_INTERNAL_SWITCH( 9 ) \ + END_CALLBACK_INTERNAL_SWITCH( 10 ) \ + END_CALLBACK_INTERNAL_END() + +#define END_DEFINE_CALLBACK_12() \ + END_CALLBACK_INTERNAL_BEGIN( 12 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 5 ) \ + END_CALLBACK_INTERNAL_SWITCH( 6 ) \ + END_CALLBACK_INTERNAL_SWITCH( 7 ) \ + END_CALLBACK_INTERNAL_SWITCH( 8 ) \ + END_CALLBACK_INTERNAL_SWITCH( 9 ) \ + END_CALLBACK_INTERNAL_SWITCH( 10 ) \ + END_CALLBACK_INTERNAL_SWITCH( 11 ) \ + END_CALLBACK_INTERNAL_END() + +#define END_DEFINE_CALLBACK_13() \ + END_CALLBACK_INTERNAL_BEGIN( 13 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 5 ) \ + END_CALLBACK_INTERNAL_SWITCH( 6 ) \ + END_CALLBACK_INTERNAL_SWITCH( 7 ) \ + END_CALLBACK_INTERNAL_SWITCH( 8 ) \ + END_CALLBACK_INTERNAL_SWITCH( 9 ) \ + END_CALLBACK_INTERNAL_SWITCH( 10 ) \ + END_CALLBACK_INTERNAL_SWITCH( 11 ) \ + END_CALLBACK_INTERNAL_SWITCH( 12 ) \ + END_CALLBACK_INTERNAL_END() + +#define END_DEFINE_CALLBACK_14() \ + END_CALLBACK_INTERNAL_BEGIN( 14 ) \ + END_CALLBACK_INTERNAL_SWITCH( 0 ) \ + END_CALLBACK_INTERNAL_SWITCH( 1 ) \ + END_CALLBACK_INTERNAL_SWITCH( 2 ) \ + END_CALLBACK_INTERNAL_SWITCH( 3 ) \ + END_CALLBACK_INTERNAL_SWITCH( 4 ) \ + END_CALLBACK_INTERNAL_SWITCH( 5 ) \ + END_CALLBACK_INTERNAL_SWITCH( 6 ) \ + END_CALLBACK_INTERNAL_SWITCH( 7 ) \ + END_CALLBACK_INTERNAL_SWITCH( 8 ) \ + END_CALLBACK_INTERNAL_SWITCH( 9 ) \ + END_CALLBACK_INTERNAL_SWITCH( 10 ) \ + END_CALLBACK_INTERNAL_SWITCH( 11 ) \ + END_CALLBACK_INTERNAL_SWITCH( 12 ) \ + END_CALLBACK_INTERNAL_SWITCH( 13 ) \ + END_CALLBACK_INTERNAL_END() + #endif // ISTEAMCLIENT_H diff --git a/public/steam/isteamcontroller.h b/public/steam/isteamcontroller.h index 6c2e1173..a00c76a9 100644 --- a/public/steam/isteamcontroller.h +++ b/public/steam/isteamcontroller.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright 1996-2013, Valve Corporation, All rights reserved. ======= // // Purpose: interface to valve controller // @@ -11,6 +11,7 @@ #endif #include "isteamclient.h" +#include "steamcontrollerpublic.h" // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -21,16 +22,44 @@ #error isteamclient.h must be included #endif +#define MAX_STEAM_CONTROLLERS 16 #pragma pack( pop ) +enum ESteamControllerPad +{ + k_ESteamControllerPad_Left, + k_ESteamControllerPad_Right +}; + + //----------------------------------------------------------------------------- -// Purpose: Functions for accessing stats, achievements, and leaderboard information +// Purpose: Native Steam controller support API //----------------------------------------------------------------------------- class ISteamController { public: - + + // + // Native controller support API + // + + // Must call init and shutdown when starting/ending use of the interface + virtual bool Init( const char *pchAbsolutePathToControllerConfigVDF ) = 0; + virtual bool Shutdown() = 0; + + // Pump callback/callresult events, SteamAPI_RunCallbacks will do this for you, + // normally never need to call directly. + virtual void RunFrame() = 0; + + // Get the state of the specified controller, returns false if that controller is not connected + virtual bool GetControllerState( uint32 unControllerIndex, SteamControllerState_t *pState ) = 0; + + // Trigger a haptic pulse on the controller + virtual void TriggerHapticPulse( uint32 unControllerIndex, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ) = 0; + + // Set the override mode which is used to choose to use different base/legacy bindings from your config file + virtual void SetOverrideMode( const char *pchMode ) = 0; }; #define STEAMCONTROLLER_INTERFACE_VERSION "STEAMCONTROLLER_INTERFACE_VERSION" diff --git a/public/steam/isteamfriends.h b/public/steam/isteamfriends.h index 6e8ad0c5..8e2136a9 100644 --- a/public/steam/isteamfriends.h +++ b/public/steam/isteamfriends.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright (C) 1996-2008, Valve Corporation, All rights reserved. ===== // // Purpose: interface to both friends list data and general information about users // @@ -203,6 +203,9 @@ public: // accesses old friends names - returns an empty string when their are no more items in the history virtual const char *GetFriendPersonaNameHistory( CSteamID steamIDFriend, int iPersonaName ) = 0; + // Returns nickname the current user has set for the specified player. Returns NULL if the no nickname has been set for that player. + virtual const char *GetPlayerNickname( CSteamID steamIDPlayer ) = 0; + // returns true if the specified user meets any of the criteria specified in iFriendFlags // iFriendFlags can be the union (binary or, |) of one or more k_EFriendFlags values virtual bool HasFriend( CSteamID steamIDFriend, int iFriendFlags ) = 0; @@ -340,7 +343,7 @@ public: virtual int GetClanChatMemberCount( CSteamID steamIDClan ) = 0; virtual CSteamID GetChatMemberByIndex( CSteamID steamIDClan, int iUser ) = 0; virtual bool SendClanChatMessage( CSteamID steamIDClanChat, const char *pchText ) = 0; - virtual int GetClanChatMessage( CSteamID steamIDClanChat, int iMessage, void *prgchText, int cchTextMax, EChatEntryType *, CSteamID * ) = 0; + virtual int GetClanChatMessage( CSteamID steamIDClanChat, int iMessage, void *prgchText, int cchTextMax, EChatEntryType *peChatEntryType, CSteamID *psteamidChatter ) = 0; virtual bool IsClanChatAdmin( CSteamID steamIDClanChat, CSteamID steamIDUser ) = 0; // interact with the Steam (game overlay / desktop) @@ -360,7 +363,7 @@ public: virtual SteamAPICall_t EnumerateFollowingList( uint32 unStartIndex ) = 0; }; -#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends013" +#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends014" // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) diff --git a/public/steam/isteamgameserver.h b/public/steam/isteamgameserver.h index 6ae3cd6f..c97ad6f5 100644 --- a/public/steam/isteamgameserver.h +++ b/public/steam/isteamgameserver.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright (c) 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: interface to steam for game servers // @@ -56,10 +56,7 @@ public: /// @see SteamServersConnected_t /// @see SteamServerConnectFailure_t /// @see SteamServersDisconnected_t - virtual void LogOn( - const char *pszAccountName, - const char *pszPassword - ) = 0; + virtual void LogOn( const char *pszToken ) = 0; /// Login to a generic, anonymous account. /// @@ -121,7 +118,7 @@ public: /// it allows users to filter in the matchmaking/server-browser interfaces based on the value /// /// @see k_cbMaxGameServerTags - virtual void SetGameTags( const char *pchGameTags ) = 0; + virtual void SetGameTags( const char *pchGameTags ) = 0; /// Sets a string defining the "gamedata" for this server, this is optional, but if it is set /// it allows users to filter in the matchmaking/server-browser interfaces based on the value @@ -129,7 +126,7 @@ public: /// acknowledged) /// /// @see k_cbMaxGameServerGameData - virtual void SetGameData( const char *pchGameData) = 0; + virtual void SetGameData( const char *pchGameData ) = 0; /// Region identifier. This is an optional field, the default value is empty, meaning the "world" region virtual void SetRegion( const char *pszRegion ) = 0; @@ -192,15 +189,10 @@ public: // returns false if we're not connected to the steam servers and thus cannot ask virtual bool RequestUserGroupStatus( CSteamID steamIDUser, CSteamID steamIDGroup ) = 0; -// -// Query steam for server data -// - // Ask for the gameplay stats for the server. Results returned in a callback + // these two functions s are deprecated, and will not return results + // they will be removed in a future version of the SDK virtual void GetGameplayStats( ) = 0; - - // Gets the reputation score for the game server. This API also checks if the server or some - // other server on the same IP is banned from the Steam master servers. virtual SteamAPICall_t GetServerReputation( ) = 0; // Returns the public IP of the server according to Steam, useful when the server is @@ -255,7 +247,7 @@ public: }; -#define STEAMGAMESERVER_INTERFACE_VERSION "SteamGameServer011" +#define STEAMGAMESERVER_INTERFACE_VERSION "SteamGameServer012" // game server flags const uint32 k_unServerFlagNone = 0x00; @@ -284,7 +276,8 @@ const uint32 k_unServerFlagPrivate = 0x20; // server shouldn't list on master struct GSClientApprove_t { enum { k_iCallback = k_iSteamGameServerCallbacks + 1 }; - CSteamID m_SteamID; + CSteamID m_SteamID; // SteamID of approved player + CSteamID m_OwnerSteamID; // SteamID of original owner for game license }; diff --git a/public/steam/isteammatchmaking.h b/public/steam/isteammatchmaking.h index 829c5091..b2dd563c 100644 --- a/public/steam/isteammatchmaking.h +++ b/public/steam/isteammatchmaking.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: interface to steam managing game server/client match making // @@ -71,10 +71,10 @@ public: virtual bool GetFavoriteGame( int iGame, AppId_t *pnAppID, uint32 *pnIP, uint16 *pnConnPort, uint16 *pnQueryPort, uint32 *punFlags, uint32 *pRTime32LastPlayedOnServer ) = 0; // adds the game server to the local list; updates the time played of the server if it already exists in the list - virtual int AddFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags, uint32 rTime32LastPlayedOnServer ) =0; + virtual int AddFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags, uint32 rTime32LastPlayedOnServer ) = 0; // removes the game server from the local storage; returns true if one was removed - virtual bool RemoveFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags ) = 0; + virtual bool RemoveFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags ) = 0; /////// // Game lobby functions @@ -563,6 +563,7 @@ struct FavoritesListChanged_t uint32 m_nAppID; uint32 m_nFlags; bool m_bAdd; // true if this is adding the entry, otherwise it is a remove + AccountID_t m_unAccountId; }; @@ -725,6 +726,21 @@ struct PSNGameBootInviteResult_t bool m_bGameBootInviteExists; CSteamID m_steamIDLobby; // Should be valid if m_bGameBootInviteExists == true }; + + +//----------------------------------------------------------------------------- +// Purpose: Result of our request to create a Lobby +// m_eResult == k_EResultOK on success +// at this point, the lobby has been joined and is ready for use +// a LobbyEnter_t callback will also be received (since the local user is joining their own lobby) +//----------------------------------------------------------------------------- +struct FavoritesListAccountsUpdated_t +{ + enum { k_iCallback = k_iSteamMatchmakingCallbacks + 16 }; + + EResult m_eResult; +}; + #pragma pack( pop ) diff --git a/public/steam/isteamremotestorage.h b/public/steam/isteamremotestorage.h index d282556a..db34eee7 100644 --- a/public/steam/isteamremotestorage.h +++ b/public/steam/isteamremotestorage.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: public interface to user remote file storage in Steam // @@ -41,6 +41,7 @@ struct SteamParamStringArray_t typedef uint64 UGCHandle_t; typedef uint64 PublishedFileUpdateHandle_t; typedef uint64 PublishedFileId_t; +const PublishedFileId_t k_PublishedFileIdInvalid = 0; const UGCHandle_t k_UGCHandleInvalid = 0xffffffffffffffffull; const PublishedFileUpdateHandle_t k_PublishedFileUpdateHandleInvalid = 0xffffffffffffffffull; @@ -87,21 +88,24 @@ enum EWorkshopFileType { k_EWorkshopFileTypeFirst = 0, - k_EWorkshopFileTypeCommunity = 0, - k_EWorkshopFileTypeMicrotransaction = 1, - k_EWorkshopFileTypeCollection = 2, - k_EWorkshopFileTypeArt = 3, - k_EWorkshopFileTypeVideo = 4, - k_EWorkshopFileTypeScreenshot = 5, - k_EWorkshopFileTypeGame = 6, - k_EWorkshopFileTypeSoftware = 7, - k_EWorkshopFileTypeConcept = 8, - k_EWorkshopFileTypeWebGuide = 9, - k_EWorkshopFileTypeIntegratedGuide = 10, - k_EWorkshopFileTypeMerch = 11, + k_EWorkshopFileTypeCommunity = 0, + k_EWorkshopFileTypeMicrotransaction = 1, + k_EWorkshopFileTypeCollection = 2, + k_EWorkshopFileTypeArt = 3, + k_EWorkshopFileTypeVideo = 4, + k_EWorkshopFileTypeScreenshot = 5, + k_EWorkshopFileTypeGame = 6, + k_EWorkshopFileTypeSoftware = 7, + k_EWorkshopFileTypeConcept = 8, + k_EWorkshopFileTypeWebGuide = 9, + k_EWorkshopFileTypeIntegratedGuide = 10, + k_EWorkshopFileTypeMerch = 11, + k_EWorkshopFileTypeControllerBinding = 12, + k_EWorkshopFileTypeSteamworksAccessInvite = 13, + k_EWorkshopFileTypeSteamVideo = 14, - // Update k_EWorkshopFileTypeMax if you add values - k_EWorkshopFileTypeMax = 12 + // Update k_EWorkshopFileTypeMax if you add values. + k_EWorkshopFileTypeMax = 15 }; @@ -135,6 +139,24 @@ enum EWorkshopVideoProvider k_EWorkshopVideoProviderYoutube = 1 }; + +enum EUGCReadAction +{ + // Keeps the file handle open unless the last byte is read. You can use this when reading large files (over 100MB) in sequential chunks. + // If the last byte is read, this will behave the same as k_EUGCRead_Close. Otherwise, it behaves the same as k_EUGCRead_ContinueReading. + // This value maintains the same behavior as before the EUGCReadAction parameter was introduced. + k_EUGCRead_ContinueReadingUntilFinished = 0, + + // Keeps the file handle open. Use this when using UGCRead to seek to different parts of the file. + // When you are done seeking around the file, make a final call with k_EUGCRead_Close to close it. + k_EUGCRead_ContinueReading = 1, + + // Frees the file handle. Use this when you're done reading the content. + // To read the file from Steam again you will need to call UGCDownload again. + k_EUGCRead_Close = 2, +}; + + //----------------------------------------------------------------------------- // Purpose: Functions for accessing, reading and writing files stored remotely // and cached locally @@ -200,7 +222,7 @@ class ISteamRemoteStorage // enough memory for each chunk). Once the last byte is read, the file is implicitly closed and further calls to UGCRead will fail // unless UGCDownload is called again. // For especially large files (anything over 100MB) it is a requirement that the file is read in chunks. - virtual int32 UGCRead( UGCHandle_t hContent, void *pvData, int32 cubDataToRead, uint32 cOffset ) = 0; + virtual int32 UGCRead( UGCHandle_t hContent, void *pvData, int32 cubDataToRead, uint32 cOffset, EUGCReadAction eAction ) = 0; // Functions to iterate through UGC that has finished downloading but has not yet been read via UGCRead() virtual int32 GetCachedUGCCount() = 0; @@ -235,8 +257,8 @@ class ISteamRemoteStorage virtual bool UpdatePublishedFileTags( PublishedFileUpdateHandle_t updateHandle, SteamParamStringArray_t *pTags ) = 0; virtual SteamAPICall_t CommitPublishedFileUpdate( PublishedFileUpdateHandle_t updateHandle ) = 0; // Gets published file details for the given publishedfileid. If unMaxSecondsOld is greater than 0, - // cached data may be returned, depending on how long ago it was cached. A value of 0 will force a refresh, - // a value of -1 will use cached data if it exists, no matter how old it is. + // cached data may be returned, depending on how long ago it was cached. A value of 0 will force a refresh. + // A value of k_WorkshopForceLoadPublishedFileDetailsFromCache will use cached data if it exists, no matter how old it is. virtual SteamAPICall_t GetPublishedFileDetails( PublishedFileId_t unPublishedFileId, uint32 unMaxSecondsOld ) = 0; virtual SteamAPICall_t DeletePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; // enumerate the files that the current user published with this app @@ -258,7 +280,7 @@ class ISteamRemoteStorage virtual SteamAPICall_t UGCDownloadToLocation( UGCHandle_t hContent, const char *pchLocation, uint32 unPriority ) = 0; }; -#define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION011" +#define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION012" // callbacks @@ -342,6 +364,7 @@ struct RemoteStorageFileShareResult_t enum { k_iCallback = k_iClientRemoteStorageCallbacks + 7 }; EResult m_eResult; // The result of the operation UGCHandle_t m_hFile; // The handle that can be shared with users and features + char m_rgchFilename[k_cchFilenameMax]; // The name of the file that was shared }; @@ -480,6 +503,7 @@ struct RemoteStorageGetPublishedFileDetailsResult_t int32 m_nPreviewFileSize; // Size of the preview file char m_rgchURL[k_cchPublishedFileURLMax]; // URL (for a video or a website) EWorkshopFileType m_eFileType; // Type of the file + bool m_bAcceptedForUse; // developer has specifically flagged this item as accepted in the Workshop }; @@ -491,6 +515,8 @@ struct RemoteStorageEnumerateWorkshopFilesResult_t int32 m_nTotalResultCount; PublishedFileId_t m_rgPublishedFileId[ k_unEnumeratePublishedFilesMaxResults ]; float m_rgScore[ k_unEnumeratePublishedFilesMaxResults ]; + AppId_t m_nAppId; + uint32 m_unStartIndex; }; @@ -603,6 +629,18 @@ struct RemoteStoragePublishFileProgress_t }; +//----------------------------------------------------------------------------- +// Purpose: Called when the content for a published file is updated +//----------------------------------------------------------------------------- +struct RemoteStoragePublishedFileUpdated_t +{ + enum { k_iCallback = k_iClientRemoteStorageCallbacks + 30 }; + PublishedFileId_t m_nPublishedFileId; // The published file id + AppId_t m_nAppID; // ID of the app that will consume this file. + UGCHandle_t m_hFile; // The new content +}; + + #pragma pack( pop ) diff --git a/public/steam/isteamuser.h b/public/steam/isteamuser.h index 7e046166..0b73178d 100644 --- a/public/steam/isteamuser.h +++ b/public/steam/isteamuser.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright (c) 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: interface to user account information in Steam // @@ -97,7 +97,7 @@ public: // levels of speech are detected. // nUncompressedVoiceDesiredSampleRate is necessary to know the number of bytes to return in pcbUncompressed - can be set to 0 if you don't need uncompressed (the usual case) // If you're upgrading from an older Steamworks API, you'll want to pass in 11025 to nUncompressedVoiceDesiredSampleRate - virtual EVoiceResult GetAvailableVoice(uint32 *pcbCompressed, uint32 *pcbUncompressed, uint32 nUncompressedVoiceDesiredSampleRate) = 0; + virtual EVoiceResult GetAvailableVoice( uint32 *pcbCompressed, uint32 *pcbUncompressed, uint32 nUncompressedVoiceDesiredSampleRate ) = 0; // Gets the latest voice data from the microphone. Compressed data is an arbitrary format, and is meant to be handed back to // DecompressVoice() for playback later as a binary blob. Uncompressed data is 16-bit, signed integer, 11025Hz PCM format. @@ -158,6 +158,14 @@ public: // retrieve a finished ticket virtual bool GetEncryptedAppTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) = 0; + // Trading Card badges data access + // if you only have one set of cards, the series will be 1 + // the user has can have two different badges for a series; the regular (max level 5) and the foil (max level 1) + virtual int GetGameBadgeLevel( int nSeries, bool bFoil ) = 0; + + // gets the Steam Level of the user, as shown on their profile + virtual int GetPlayerSteamLevel() = 0; + #ifdef _PS3 // Initiates PS3 Logon request using just PSN ticket. // @@ -197,7 +205,7 @@ public: }; -#define STEAMUSER_INTERFACE_VERSION "SteamUser016" +#define STEAMUSER_INTERFACE_VERSION "SteamUser017" // callbacks @@ -287,6 +295,7 @@ struct ValidateAuthTicketResponse_t enum { k_iCallback = k_iSteamUserCallbacks + 43 }; CSteamID m_SteamID; EAuthSessionResponse m_eAuthSessionResponse; + CSteamID m_OwnerSteamID; // different from m_SteamID if borrowed }; diff --git a/public/steam/isteamutils.h b/public/steam/isteamutils.h index d0bf2c62..2e302b9e 100644 --- a/public/steam/isteamutils.h +++ b/public/steam/isteamutils.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: interface to utility functions in Steam // @@ -149,17 +149,20 @@ public: #endif // Activates the Big Picture text input dialog which only supports gamepad input - virtual bool ShowGamepadTextInput( EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32 unCharMax ) = 0; + virtual bool ShowGamepadTextInput( EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32 unCharMax, const char *pchExistingText ) = 0; // Returns previously entered text & length virtual uint32 GetEnteredGamepadTextLength() = 0; - virtual bool GetEnteredGamepadTextInput( char *pchText, uint32 cchText ) = 0; + virtual bool GetEnteredGamepadTextInput( char *pchText, uint32 cchText ) = 0; // returns the language the steam client is running in, you probably want ISteamApps::GetCurrentGameLanguage instead, this is for very special usage cases virtual const char *GetSteamUILanguage() = 0; + + // returns true if Steam itself is running in VR mode + virtual bool IsSteamRunningInVR() = 0; }; -#define STEAMUTILS_INTERFACE_VERSION "SteamUtils006" +#define STEAMUTILS_INTERFACE_VERSION "SteamUtils007" // callbacks diff --git a/public/steam/matchmakingtypes.h b/public/steam/matchmakingtypes.h index 06bc2959..61bb69ec 100644 --- a/public/steam/matchmakingtypes.h +++ b/public/steam/matchmakingtypes.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============ // // Purpose: // @@ -32,6 +32,11 @@ const int k_cbMaxGameServerName = 64; const int k_cbMaxGameServerTags = 128; const int k_cbMaxGameServerGameData = 2048; +/// Store key/value pair used in matchmaking queries. +/// +/// Actually, the name Key/Value is a bit misleading. The "key" is better +/// understood as "filter operation code" and the "value" is the operand to this +/// filter operation. The meaning of the operand depends upon the filter. struct MatchMakingKeyValuePair_t { MatchMakingKeyValuePair_t() { m_szKey[0] = m_szValue[0] = 0; } diff --git a/public/steam/steam_api.h b/public/steam/steam_api.h index e16f226b..2890cb15 100644 --- a/public/steam/steam_api.h +++ b/public/steam/steam_api.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: // @@ -20,9 +20,14 @@ #include "isteamnetworking.h" #include "isteamremotestorage.h" #include "isteamscreenshots.h" +#include "isteammusic.h" +#include "isteammusicremote.h" #include "isteamhttp.h" #include "isteamunifiedmessages.h" #include "isteamcontroller.h" +#include "isteamugc.h" +#include "isteamapplist.h" +#include "isteamhtmlsurface.h" #if defined( _PS3 ) #include "steamps3params.h" @@ -59,10 +64,10 @@ //----------------------------------------------------------------------------------------------------------------------------------------------------------// // S_API void SteamAPI_Init(); (see below) -S_API void SteamAPI_Shutdown(); +S_API void S_CALLTYPE SteamAPI_Shutdown(); // checks if a local Steam client is running -S_API bool SteamAPI_IsSteamRunning(); +S_API bool S_CALLTYPE SteamAPI_IsSteamRunning(); // Detects if your executable was launched through the Steam client, and restarts your game through // the client if necessary. The Steam client will be started if it is not running. @@ -75,14 +80,14 @@ S_API bool SteamAPI_IsSteamRunning(); // // NOTE: This function should be used only if you are using CEG or not using Steam's DRM. Once applied // to your executable, Steam's DRM will handle restarting through Steam if necessary. -S_API bool SteamAPI_RestartAppIfNecessary( uint32 unOwnAppID ); +S_API bool S_CALLTYPE SteamAPI_RestartAppIfNecessary( uint32 unOwnAppID ); // crash dump recording functions -S_API void SteamAPI_WriteMiniDump( uint32 uStructuredExceptionCode, void* pvExceptionInfo, uint32 uBuildID ); -S_API void SteamAPI_SetMiniDumpComment( const char *pchMsg ); +S_API void S_CALLTYPE SteamAPI_WriteMiniDump( uint32 uStructuredExceptionCode, void* pvExceptionInfo, uint32 uBuildID ); +S_API void S_CALLTYPE SteamAPI_SetMiniDumpComment( const char *pchMsg ); // interface pointers, configured by SteamAPI_Init() -S_API ISteamClient *SteamClient(); +S_API ISteamClient *S_CALLTYPE SteamClient(); // @@ -96,29 +101,35 @@ S_API ISteamClient *SteamClient(); // functions below to get at the Steam interfaces. // #ifdef VERSION_SAFE_STEAM_API_INTERFACES -S_API bool SteamAPI_InitSafe(); +S_API bool S_CALLTYPE SteamAPI_InitSafe(); #else #if defined(_PS3) -S_API bool SteamAPI_Init( SteamPS3Params_t *pParams ); +S_API bool S_CALLTYPE SteamAPI_Init( SteamPS3Params_t *pParams ); #else -S_API bool SteamAPI_Init(); +S_API bool S_CALLTYPE SteamAPI_Init(); #endif -S_API ISteamUser *SteamUser(); -S_API ISteamFriends *SteamFriends(); -S_API ISteamUtils *SteamUtils(); -S_API ISteamMatchmaking *SteamMatchmaking(); -S_API ISteamUserStats *SteamUserStats(); -S_API ISteamApps *SteamApps(); -S_API ISteamNetworking *SteamNetworking(); -S_API ISteamMatchmakingServers *SteamMatchmakingServers(); -S_API ISteamRemoteStorage *SteamRemoteStorage(); -S_API ISteamScreenshots *SteamScreenshots(); -S_API ISteamHTTP *SteamHTTP(); -S_API ISteamUnifiedMessages *SteamUnifiedMessages(); +S_API ISteamUser *S_CALLTYPE SteamUser(); +S_API ISteamFriends *S_CALLTYPE SteamFriends(); +S_API ISteamUtils *S_CALLTYPE SteamUtils(); +S_API ISteamMatchmaking *S_CALLTYPE SteamMatchmaking(); +S_API ISteamUserStats *S_CALLTYPE SteamUserStats(); +S_API ISteamApps *S_CALLTYPE SteamApps(); +S_API ISteamNetworking *S_CALLTYPE SteamNetworking(); +S_API ISteamMatchmakingServers *S_CALLTYPE SteamMatchmakingServers(); +S_API ISteamRemoteStorage *S_CALLTYPE SteamRemoteStorage(); +S_API ISteamScreenshots *S_CALLTYPE SteamScreenshots(); +S_API ISteamHTTP *S_CALLTYPE SteamHTTP(); +S_API ISteamUnifiedMessages *S_CALLTYPE SteamUnifiedMessages(); +S_API ISteamController *S_CALLTYPE SteamController(); +S_API ISteamUGC *S_CALLTYPE SteamUGC(); +S_API ISteamAppList *S_CALLTYPE SteamAppList(); +S_API ISteamMusic *S_CALLTYPE SteamMusic(); +S_API ISteamMusicRemote *S_CALLTYPE SteamMusicRemote(); +S_API ISteamHTMLSurface *S_CALLTYPE SteamHTMLSurface(); #ifdef _PS3 -S_API ISteamPS3OverlayRender * SteamPS3OverlayRender(); +S_API ISteamPS3OverlayRender *S_CALLTYPE SteamPS3OverlayRender(); #endif #endif // VERSION_SAFE_STEAM_API_INTERFACES @@ -132,16 +143,16 @@ S_API ISteamPS3OverlayRender * SteamPS3OverlayRender(); // to as many functions/objects as are registered to it //----------------------------------------------------------------------------------------------------------------------------------------------------------// -S_API void SteamAPI_RunCallbacks(); +S_API void S_CALLTYPE SteamAPI_RunCallbacks(); // functions used by the utility CCallback objects to receive callbacks -S_API void SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback ); -S_API void SteamAPI_UnregisterCallback( class CCallbackBase *pCallback ); +S_API void S_CALLTYPE SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback ); +S_API void S_CALLTYPE SteamAPI_UnregisterCallback( class CCallbackBase *pCallback ); // functions used by the utility CCallResult objects to receive async call results -S_API void SteamAPI_RegisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); -S_API void SteamAPI_UnregisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); +S_API void S_CALLTYPE SteamAPI_RegisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); +S_API void S_CALLTYPE SteamAPI_UnregisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); //----------------------------------------------------------------------------- @@ -397,6 +408,12 @@ public: ISteamScreenshots* SteamScreenshots() { return m_pSteamScreenshots; } ISteamHTTP* SteamHTTP() { return m_pSteamHTTP; } ISteamUnifiedMessages* SteamUnifiedMessages() { return m_pSteamUnifiedMessages; } + ISteamController* SteamController() { return m_pController; } + ISteamUGC* SteamUGC() { return m_pSteamUGC; } + ISteamAppList* SteamAppList() { return m_pSteamAppList; } + ISteamMusic* SteamMusic() { return m_pSteamMusic; } + ISteamMusicRemote* SteamMusicRemote() { return m_pSteamMusicRemote; } + ISteamHTMLSurface* SteamHTMLSurface() { return m_pSteamHTMLSurface; } #ifdef _PS3 ISteamPS3OverlayRender* SteamPS3OverlayRender() { return m_pSteamPS3OverlayRender; } #endif @@ -415,6 +432,11 @@ private: ISteamHTTP *m_pSteamHTTP; ISteamUnifiedMessages*m_pSteamUnifiedMessages; ISteamController *m_pController; + ISteamUGC *m_pSteamUGC; + ISteamAppList *m_pSteamAppList; + ISteamMusic *m_pSteamMusic; + ISteamMusicRemote *m_pSteamMusicRemote; + ISteamHTMLSurface *m_pSteamHTMLSurface; #ifdef _PS3 ISteamPS3OverlayRender *m_pSteamPS3OverlayRender; #endif @@ -438,7 +460,14 @@ inline void CSteamAPIContext::Clear() m_pSteamRemoteStorage = NULL; m_pSteamHTTP = NULL; m_pSteamScreenshots = NULL; + m_pSteamMusic = NULL; m_pSteamUnifiedMessages = NULL; + m_pController = NULL; + m_pSteamUGC = NULL; + m_pSteamAppList = NULL; + m_pSteamMusic = NULL; + m_pSteamMusicRemote= NULL; + m_pSteamHTMLSurface = NULL; #ifdef _PS3 m_pSteamPS3OverlayRender = NULL; #endif @@ -501,6 +530,36 @@ inline bool CSteamAPIContext::Init() if ( !m_pSteamUnifiedMessages ) return false; + m_pController = SteamClient()->GetISteamController( hSteamUser, hSteamPipe, STEAMCONTROLLER_INTERFACE_VERSION ); + if ( !m_pController ) + return false; + + m_pSteamUGC = SteamClient()->GetISteamUGC( hSteamUser, hSteamPipe, STEAMUGC_INTERFACE_VERSION ); + if ( !m_pSteamUGC ) + return false; + + m_pSteamAppList = SteamClient()->GetISteamAppList( hSteamUser, hSteamPipe, STEAMAPPLIST_INTERFACE_VERSION ); + if ( !m_pSteamAppList ) + return false; + + m_pSteamMusic = SteamClient()->GetISteamMusic( hSteamUser, hSteamPipe, STEAMMUSIC_INTERFACE_VERSION ); + if ( !m_pSteamMusic ) + { + return false; + } + + m_pSteamMusicRemote = SteamClient()->GetISteamMusicRemote( hSteamUser, hSteamPipe, STEAMMUSICREMOTE_INTERFACE_VERSION ); + if ( !m_pSteamMusicRemote ) + { + return false; + } + + m_pSteamHTMLSurface = SteamClient()->GetISteamHTMLSurface( hSteamUser, hSteamPipe, STEAMHTMLSURFACE_INTERFACE_VERSION ); + if ( !m_pSteamHTMLSurface ) + { + return false; + } + #ifdef _PS3 m_pSteamPS3OverlayRender = SteamClient()->GetISteamPS3OverlayRender(); #endif @@ -512,13 +571,13 @@ inline bool CSteamAPIContext::Init() #if defined(USE_BREAKPAD_HANDLER) || defined(STEAM_API_EXPORTS) // this should be called before the game initialized the steam APIs -// pchDate should be of the format "Mmm dd yyyy" (such as from the __DATE __ macro ) -// pchTime should be of the format "hh:mm:ss" (such as from the __TIME __ macro ) +// pchDate should be of the format "Mmm dd yyyy" (such as from the __DATE__ macro ) +// pchTime should be of the format "hh:mm:ss" (such as from the __TIME__ macro ) // bFullMemoryDumps (Win32 only) -- writes out a uuid-full.dmp in the client/dumps folder // pvContext-- can be NULL, will be the void * context passed into m_pfnPreMinidumpCallback // PFNPreMinidumpCallback m_pfnPreMinidumpCallback -- optional callback which occurs just before a .dmp file is written during a crash. Applications can hook this to allow adding additional information into the .dmp comment stream. -S_API void SteamAPI_UseBreakpadCrashHandler( char const *pchVersion, char const *pchDate, char const *pchTime, bool bFullMemoryDumps, void *pvContext, PFNPreMinidumpCallback m_pfnPreMinidumpCallback ); -S_API void SteamAPI_SetBreakpadAppID( uint32 unAppID ); +S_API void S_CALLTYPE SteamAPI_UseBreakpadCrashHandler( char const *pchVersion, char const *pchDate, char const *pchTime, bool bFullMemoryDumps, void *pvContext, PFNPreMinidumpCallback m_pfnPreMinidumpCallback ); +S_API void S_CALLTYPE SteamAPI_SetBreakpadAppID( uint32 unAppID ); #endif #endif // STEAM_API_H diff --git a/public/steam/steam_gameserver.h b/public/steam/steam_gameserver.h index 47cb7848..2d384894 100644 --- a/public/steam/steam_gameserver.h +++ b/public/steam/steam_gameserver.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: // @@ -151,7 +151,7 @@ inline bool CSteamGameServerAPIContext::Init() return false; m_pSteamHTTP = g_pSteamClientGameServer->GetISteamHTTP( hSteamUser, hSteamPipe, STEAMHTTP_INTERFACE_VERSION ); - if ( !m_pSteamGameServerStats ) + if ( !m_pSteamHTTP ) return false; return true; diff --git a/public/steam/steamclientpublic.h b/public/steam/steamclientpublic.h index d9d076ae..1620520b 100644 --- a/public/steam/steamclientpublic.h +++ b/public/steam/steamclientpublic.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============ // // Purpose: // @@ -20,7 +20,7 @@ // interface layer, no need to include anything about the implementation. #include "steamtypes.h" - +#include "steamuniverse.h" // General result codes enum EResult @@ -102,7 +102,18 @@ enum EResult k_EResultNoMatchingURL = 75, k_EResultBadResponse = 76, // parse failure, missing field, etc. k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password - k_EResultValueOutOfRange = 78 // the value entered is outside the acceptable range + k_EResultValueOutOfRange = 78, // the value entered is outside the acceptable range + k_EResultUnexpectedError = 79, // something happened that we didn't expect to ever happen + k_EResultDisabled = 80, // The requested service has been configured to be unavailable + k_EResultInvalidCEGSubmission = 81, // The set of files submitted to the CEG server are not valid ! + k_EResultRestrictedDevice = 82, // The device being used is not allowed to perform this action + k_EResultRegionLocked = 83, // The action could not be complete because it is region restricted + k_EResultRateLimitExceeded = 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent + k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to login + k_EResultItemDeleted = 86, // The thing we're trying to access has been deleted + k_EResultAccountLoginDeniedThrottle = 87, // login attempt failed, try to throttle response to possible attacker + k_EResultTwoFactorCodeMismatch = 88, // two factor code mismatch + k_EResultTwoFactorActivationCodeMismatch = 89, // activation code for two-factor didn't match }; // Error codes for use with the voice functions @@ -167,6 +178,7 @@ typedef enum k_EAuthSessionResponseAuthTicketCanceled = 6, // The ticket has been canceled by the issuer k_EAuthSessionResponseAuthTicketInvalidAlreadyUsed = 7, // This ticket has already been used, it is not valid. k_EAuthSessionResponseAuthTicketInvalid = 8, // This ticket is not from a user instance currently connected to steam. + k_EAuthSessionResponsePublisherIssuedBan = 9, // The user is banned for this game. The ban came via the web api and not VAC } EAuthSessionResponse; // results from UserHasLicenseForApp @@ -178,18 +190,6 @@ typedef enum } EUserHasLicenseForAppResult; -// Steam universes. Each universe is a self-contained Steam instance. -enum EUniverse -{ - k_EUniverseInvalid = 0, - k_EUniversePublic = 1, - k_EUniverseBeta = 2, - k_EUniverseInternal = 3, - k_EUniverseDev = 4, - // k_EUniverseRC = 5, // no such universe anymore - k_EUniverseMax -}; - // Steam account types enum EAccountType { @@ -227,15 +227,23 @@ enum EAppReleaseState //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -enum EAppOwernshipFlags +enum EAppOwnershipFlags { - k_EAppOwernshipFlags_None = 0, // unknown - k_EAppOwernshipFlags_OwnsLicense = 1, // owns license for this game - k_EAppOwernshipFlags_FreeLicense = 2, // not paid for game - k_EAppOwernshipFlags_RegionRestricted = 4, // owns app, but not allowed to play in current region - k_EAppOwernshipFlags_LowViolence = 8, // only low violence version - k_EAppOwernshipFlags_InvalidPlatform = 16, // app not supported on current platform - k_EAppOwernshipFlags_DeviceLicense = 32, // license was granted by authorized local device + k_EAppOwnershipFlags_None = 0x0000, // unknown + k_EAppOwnershipFlags_OwnsLicense = 0x0001, // owns license for this game + k_EAppOwnershipFlags_FreeLicense = 0x0002, // not paid for game + k_EAppOwnershipFlags_RegionRestricted = 0x0004, // owns app, but not allowed to play in current region + k_EAppOwnershipFlags_LowViolence = 0x0008, // only low violence version + k_EAppOwnershipFlags_InvalidPlatform = 0x0010, // app not supported on current platform + k_EAppOwnershipFlags_SharedLicense = 0x0020, // license was granted by authorized local device + k_EAppOwnershipFlags_FreeWeekend = 0x0040, // owned by a free weekend licenses + k_EAppOwnershipFlags_RetailLicense = 0x0080, // has a retail license for game, (CD-Key etc) + k_EAppOwnershipFlags_LicenseLocked = 0x0100, // shared license is locked (in use) by other user + k_EAppOwnershipFlags_LicensePending = 0x0200, // owns app, but transaction is still pending. Can't install or play + k_EAppOwnershipFlags_LicenseExpired = 0x0400, // doesn't own app anymore since license expired + k_EAppOwnershipFlags_LicensePermanent = 0x0800, // permanent license, not borrowed, or guest or freeweekend etc + k_EAppOwnershipFlags_LicenseRecurring = 0x1000, // Recurring license, user is charged periodically + k_EAppOwnershipFlags_LicenseCanceled = 0x2000, // Mark as canceled, but might be still active if recurring }; @@ -249,16 +257,23 @@ enum EAppType k_EAppType_Application = 0x002, // software application k_EAppType_Tool = 0x004, // SDKs, editors & dedicated servers k_EAppType_Demo = 0x008, // game demo - k_EAppType_Media = 0x010, // media trailer + k_EAppType_Media_DEPRECATED = 0x010, // legacy - was used for game trailers, which are now just videos on the web k_EAppType_DLC = 0x020, // down loadable content k_EAppType_Guide = 0x040, // game guide, PDF etc k_EAppType_Driver = 0x080, // hardware driver updater (ATI, Razor etc) - + k_EAppType_Config = 0x100, // hidden app used to config Steam features (backpack, sales, etc) + k_EAppType_Film = 0x200, // A Movie (feature film) + k_EAppType_TVSeries = 0x400, // A TV or other video series which will have episodes and perhaps seasons + k_EAppType_Video = 0x800, // A video component of either a Film or TVSeries (may be the feature, an episode, preview, making-of, etc) + k_EAppType_Plugin = 0x1000, // Plug-in types for other Apps + k_EAppType_Music = 0x2000, // Music files + k_EAppType_Shortcut = 0x40000000, // just a shortcut, client side only k_EAppType_DepotOnly = 0x80000000, // placeholder since depots and apps share the same namespace }; + //----------------------------------------------------------------------------- // types of user game stats fields // WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN DATABASE @@ -296,7 +311,8 @@ enum EChatEntryType k_EChatEntryTypeWasBanned = 9, // user was banned (data: 64-bit steamid of actor performing the ban) k_EChatEntryTypeDisconnected = 10, // user disconnected k_EChatEntryTypeHistoricalChat = 11, // a chat message from user's chat history or offilne message - + k_EChatEntryTypeReserved1 = 12, + k_EChatEntryTypeReserved2 = 13, }; @@ -322,18 +338,6 @@ enum EChatRoomEnterResponse }; -//----------------------------------------------------------------------------- -// Purpose: Status of a given depot version, these are stored in the DB, don't renumber -//----------------------------------------------------------------------------- -enum EStatusDepotVersion -{ - k_EStatusDepotVersionInvalid = 0, - k_EStatusDepotVersionDisabled = 1, // version was disabled, no manifest & content available - k_EStatusDepotVersionAvailable = 2, // manifest & content is available, but not current - k_EStatusDepotVersionCurrent = 3, // current depot version. The can be multiple, one for public and one for each beta key -}; - - typedef void (*PFNLegacyKeyRegistration)( const char *pchCDKey, const char *pchInstallPath ); typedef bool (*PFNLegacyKeyInstalled)(); @@ -449,6 +453,12 @@ public: { SetFromUint64( ulSteamID ); } +#ifdef INT64_DIFFERENT_FROM_INT64_T + CSteamID( uint64_t ulSteamID ) + { + SetFromUint64( (uint64)ulSteamID ); + } +#endif //----------------------------------------------------------------------------- @@ -463,7 +473,7 @@ public: m_steamid.m_comp.m_EUniverse = eUniverse; m_steamid.m_comp.m_EAccountType = eAccountType; - if ( eAccountType == k_EAccountTypeClan ) + if ( eAccountType == k_EAccountTypeClan || eAccountType == k_EAccountTypeGameServer ) { m_steamid.m_comp.m_unAccountInstance = 0; } @@ -525,7 +535,7 @@ public: } -#if defined( INCLUDED_STEAM_COMMON_STEAMCOMMON_H ) +#if defined( INCLUDED_STEAM2_USERID_STRUCTS ) //----------------------------------------------------------------------------- // Purpose: Initializes a steam ID from a Steam2 ID structure // Input: pTSteamGlobalUserID - Steam2 ID to convert @@ -845,6 +855,12 @@ public: { m_ulGameID = ulGameID; } +#ifdef INT64_DIFFERENT_FROM_INT64_T + CGameID( uint64_t ulGameID ) + { + m_ulGameID = (uint64)ulGameID; + } +#endif explicit CGameID( int32 nAppID ) { diff --git a/public/steam/steamhttpenums.h b/public/steam/steamhttpenums.h index d43d33df..155fe770 100644 --- a/public/steam/steamhttpenums.h +++ b/public/steam/steamhttpenums.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright © 1996-2010, Valve Corporation, All rights reserved. ======= // // Purpose: HTTP related enums, stuff that is shared by both clients and servers, and our // UI projects goes here. @@ -20,13 +20,13 @@ enum EHTTPMethod k_EHTTPMethodGET, k_EHTTPMethodHEAD, k_EHTTPMethodPOST, + k_EHTTPMethodPUT, + k_EHTTPMethodDELETE, + k_EHTTPMethodOPTIONS, // The remaining HTTP methods are not yet supported, per rfc2616 section 5.1.1 only GET and HEAD are required for // a compliant general purpose server. We'll likely add more as we find uses for them. - // k_EHTTPMethodOPTIONS, - k_EHTTPMethodPUT, - k_EHTTPMethodDELETE, // k_EHTTPMethodTRACE, // k_EHTTPMethodCONNECT }; @@ -81,6 +81,7 @@ enum EHTTPStatusCode k_EHTTPStatusCode415UnsupportedMediaType = 415, k_EHTTPStatusCode416RequestedRangeNotSatisfiable = 416, k_EHTTPStatusCode417ExpectationFailed = 417, + k_EHTTPStatusCode429TooManyRequests = 429, // Server error codes k_EHTTPStatusCode500InternalServerError = 500, diff --git a/public/steam/steamtypes.h b/public/steam/steamtypes.h index 6b6bc265..cc14fbf6 100644 --- a/public/steam/steamtypes.h +++ b/public/steam/steamtypes.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============ // // Purpose: // @@ -10,6 +10,8 @@ #pragma once #endif +#define S_CALLTYPE __cdecl + // Steam-specific types. Defined here so this header file can be included in other code bases. #ifndef WCHARTYPES_H typedef unsigned char uint8; @@ -43,6 +45,9 @@ typedef unsigned __int32 uint32; typedef __int64 int64; typedef unsigned __int64 uint64; +typedef int64 lint64; +typedef uint64 ulint64; + #ifdef X64BITS typedef __int64 intp; // intp is an integer that can accomodate a pointer typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *) @@ -59,6 +64,16 @@ typedef int int32; typedef unsigned int uint32; typedef long long int64; typedef unsigned long long uint64; + +// [u]int64 are actually defined as 'long long' and gcc 64-bit +// doesn't automatically consider them the same as 'long int'. +// Changing the types for [u]int64 is complicated by +// there being many definitions, so we just +// define a 'long int' here and use it in places that would +// otherwise confuse the compiler. +typedef long int lint64; +typedef unsigned long int ulint64; + #ifdef X64BITS typedef long long intp; typedef unsigned long long uintp; @@ -133,4 +148,10 @@ typedef uint32 AccountID_t; typedef uint32 PartnerId_t; const PartnerId_t k_uPartnerIdInvalid = 0; +// ID for a depot content manifest +typedef uint64 ManifestId_t; +const ManifestId_t k_uManifestIdInvalid = 0; + + + #endif // STEAMTYPES_H diff --git a/public/studio.cpp b/public/studio.cpp index 643c9e6e..b7cef5ed 100644 --- a/public/studio.cpp +++ b/public/studio.cpp @@ -1673,7 +1673,7 @@ void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict // Now, create starting indices for each activity. For an activity n, // the starting index is of course the sum of counts [0..n-1]. - register int sequenceCount = 0; + int sequenceCount = 0; int topActivity = 0; // this will store the highest seen activity number (used later to make an ad hoc map on the stack) for ( UtlHashHandle_t handle = m_ActToSeqHash.GetFirstHandle() ; m_ActToSeqHash.IsValidHandle(handle) ; diff --git a/public/studio.h b/public/studio.h index b6b9ae1e..e5118adf 100644 --- a/public/studio.h +++ b/public/studio.h @@ -2571,11 +2571,10 @@ public: // ctor CActivityToSequenceMapping( void ) - : m_pSequenceTuples(NULL), m_iSequenceTuplesCount(0), + : m_pSequenceTuples(NULL), m_iSequenceTuplesCount(0), m_ActToSeqHash(8,0,0), m_expectedPStudioHdr(NULL), m_expectedVModel(NULL) #if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE - m_bIsInitialized(false), + , m_bIsInitialized(false) #endif - m_ActToSeqHash(8,0,0), m_expectedPStudioHdr(NULL), m_expectedVModel(NULL) {}; // dtor -- not virtual because this class has no inheritors diff --git a/public/tier0/P4PerformanceCounters.h b/public/tier0/P4PerformanceCounters.h index 44a53922..b4d71f08 100644 --- a/public/tier0/P4PerformanceCounters.h +++ b/public/tier0/P4PerformanceCounters.h @@ -8,9 +8,7 @@ #ifndef P4PERFORMANCECOUNTERS_H #define P4PERFORMANCECOUNTERS_H -#ifdef _WIN32 #pragma once -#endif // Pentium 4 support /* @@ -77,9 +75,7 @@ enum Counters // register base for CCCR register #define MSR_CCCR_BASE 0x360 -#ifdef _WIN32 #pragma pack(push, 1) -#endif // access to these bits is through the methods typedef union ESCR { @@ -125,9 +121,7 @@ typedef union CCCR } CCCR; -#ifdef _WIN32 #pragma pack(pop) -#endif extern const unsigned short cccr_escr_map[NCOUNTERS][8]; diff --git a/public/tier0/annotations.h b/public/tier0/annotations.h index fe674971..ecc9dae7 100644 --- a/public/tier0/annotations.h +++ b/public/tier0/annotations.h @@ -13,44 +13,6 @@ // Include the annotation header file. #include -// /Analyze warnings can only be suppressed when using a compiler that supports them, which VS 2010 -// Professional does not. - -// We don't care about these warnings because they are bugs that can only occur during resource -// exhaustion or other unexpected API failure, which we are nowhere near being able to handle. -#pragma warning(disable : 6308) // warning C6308: 'realloc' might return null pointer: assigning null pointer to 's_ppTestCases', which is passed as an argument to 'realloc', will cause the original memory block to be leaked -#pragma warning(disable : 6255) // warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead -#pragma warning(disable : 6387) // warning C6387: 'argument 1' might be '0': this does not adhere to the specification for the function 'GetProcAddress' -#pragma warning(disable : 6309) // warning C6309: Argument '1' is null: this does not adhere to function specification of 'GetProcAddress' -#pragma warning(disable : 6011) // warning C6011: Dereferencing NULL pointer 'm_ppTestCases' -#pragma warning(disable : 6211) // warning C6211: Leaking memory 'newKeyValue' due to an exception. Consider using a local catch block to clean up memory -#pragma warning(disable : 6031) // warning C6031: Return value ignored: '_getcwd' - -// These warnings are because /analyze doesn't like our use of constants, especially things like IsPC() -#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant -#pragma warning(disable : 6239) // warning C6239: ( && ) always evaluates to the result of . Did you intend to use the bitwise-and operator? -#pragma warning(disable : 6285) // warning C6285: ( || ) is always a non-zero constant. Did you intend to use the bitwise-and operator? -#pragma warning(disable : 6237) // warning C6237: ( && ) is always zero. is never evaluated and might have side effects -#pragma warning(disable : 6235) // warning C6235: ( || ) is always a non-zero constant -#pragma warning(disable : 6240) // warning C6240: ( && ) always evaluates to the result of . Did you intend to use the bitwise-and operator? - -// These warnings aren't really important: -#pragma warning(disable : 6323) // warning C6323: Use of arithmetic operator on Boolean type(s) - -// Miscellaneous other /analyze warnings. We should consider fixing these at some point. -//#pragma warning(disable : 6204) // warning C6204: Possible buffer overrun in call to 'memcpy': use of unchecked parameter 'src' -//#pragma warning(disable : 6262) // warning C6262: Function uses '16464' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap -// This is a serious warning. Don't suppress it. -//#pragma warning(disable : 6263) // warning C6263: Using _alloca in a loop: this can quickly overflow stack -// 6328 is also used for passing __int64 to printf when int is expected so we can't suppress it. -//#pragma warning(disable : 6328) // warning C6328: 'char' passed as parameter '1' when 'unsigned char' is required in call to 'V_isdigit' -// /analyze doesn't like GCOMPILER_ASSERT's implementation of compile-time asserts -#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant -#pragma warning(disable : 6335) // warning C6335: Leaking process information handle 'pi.hThread' -#pragma warning(disable : 6320) // warning C6320: Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled -#pragma warning(disable : 6250) // warning C6250: Calling 'VirtualFree' without the MEM_RELEASE flag might free memory but not address descriptors (VADs). This causes address space leaks -#pragma warning(disable : 6384) // ientity2_class_h_schema_gen.cpp(76): warning C6384: Dividing sizeof a pointer by another value - // For temporarily suppressing warnings -- the warnings are suppressed for the next source line. #define ANALYZE_SUPPRESS(wnum) __pragma(warning(suppress: wnum)) #define ANALYZE_SUPPRESS2(wnum1, wnum2) __pragma(warning(supress: wnum1 wnum2)) @@ -86,6 +48,8 @@ #define OUT_Z_ARRAY _Deref_post_z_ #define INOUT_Z_ARRAY _Deref_prepost_z_ #endif // _MSC_VER >= 1700 +// Used for annotating functions to describe their return types. +#define MUST_CHECK_RETURN _Check_return_ // Use the macros above to annotate string functions that fill buffers as shown here, // in order to give VS's /analyze more opportunities to find bugs. // void V_wcsncpy( OUT_Z_BYTECAP(maxLenInBytes) wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes ); @@ -114,6 +78,7 @@ #define INOUT_Z_BYTECAP(x) #define OUT_Z_ARRAY #define INOUT_Z_ARRAY +#define MUST_CHECK_RETURN #endif #endif // ANALYSIS_ANNOTATIONS_H diff --git a/public/tier0/dbg.h b/public/tier0/dbg.h index 9fd5b47f..8c94c0f5 100644 --- a/public/tier0/dbg.h +++ b/public/tier0/dbg.h @@ -285,7 +285,7 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); #define AssertFatal( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), true ) #define AssertFatalOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), true ) -#define AssertFatalMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), true ) +#define AssertFatalMsg( _exp, _msg, ... ) _AssertMsg( _exp, (const tchar *)CDbgFmtMsg( _msg, ##__VA_ARGS__ ), ((void)0), true ) #define AssertFatalMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, true ) #define AssertFatalFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: " _T(#_exp), _f, true ) #define AssertFatalEquals( _exp, _expectedValue ) AssertFatalMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) ) @@ -293,16 +293,15 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); #define VerifyFatal( _exp ) AssertFatal( _exp ) #define VerifyEqualsFatal( _exp, _expectedValue ) AssertFatalEquals( _exp, _expectedValue ) -#define AssertFatalMsg1( _exp, _msg, a1 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 ))) -#define AssertFatalMsg2( _exp, _msg, a1, a2 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 ))) -#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 ))) -#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 ))) -#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 ))) -#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ))) -#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ))) -#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 ))) -#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 ))) -#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ))) +#define AssertFatalMsg1( _exp, _msg, a1 ) AssertFatalMsg( _exp, _msg, a1 ) +#define AssertFatalMsg2( _exp, _msg, a1, a2 ) AssertFatalMsg( _exp, _msg, a1, a2 ) +#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) AssertFatalMsg( _exp, _msg, a1, a2, a3 ) +#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4 ) +#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5 ) +#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5, a6 ) +#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) +#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) +#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) #else // DBGFLAG_ASSERTFATAL @@ -322,7 +321,6 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); #define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0) #define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0) #define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0) -#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0) #define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0) #define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0) #define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0) @@ -336,7 +334,7 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); #ifdef DBGFLAG_ASSERT #define Assert( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false ) -#define AssertMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false ) +#define AssertMsg( _exp, _msg, ... ) _AssertMsg( _exp, (const tchar *)CDbgFmtMsg( _msg, ##__VA_ARGS__ ), ((void)0), false ) #define AssertOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), false ) #define AssertMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, false ) #define AssertFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), _f, false ) @@ -349,21 +347,21 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); #define VerifyEquals( _exp, _expectedValue ) AssertEquals( _exp, _expectedValue ) #define DbgVerify( _exp ) Assert( _exp ) -#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )) ) -#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )) ) -#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )) ) -#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )) ) -#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )) ) -#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )) ) -#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )) ) -#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )) ) -#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )) ) +#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, _msg, a1 ) +#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, _msg, a1, a2 ) +#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, _msg, a1, a2, a3 ) +#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, _msg, a1, a2, a3, a4 ) +#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5 ) +#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6 ) +#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) +#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) +#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) #else // DBGFLAG_ASSERT #define Assert( _exp ) ((void)0) #define AssertOnce( _exp ) ((void)0) -#define AssertMsg( _exp, _msg ) ((void)0) +#define AssertMsg( _exp, _msg, ... ) ((void)0) #define AssertMsgOnce( _exp, _msg ) ((void)0) #define AssertFunc( _exp, _f ) ((void)0) #define AssertEquals( _exp, _expectedValue ) ((void)0) @@ -393,6 +391,21 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); #define AssertAlways( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false ) #define AssertMsgAlways( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false ) +// Stringify a number +#define V_STRINGIFY_INTERNAL(x) #x +// Extra level of indirection needed when passing in a macro to avoid getting the macro name instead of value +#define V_STRINGIFY(x) V_STRINGIFY_INTERNAL(x) + +// Macros to help decorate warnings or errors with the location in code +#define FILE_LINE_FUNCTION_STRING __FILE__ "(" V_STRINGIFY(__LINE__) "):" __FUNCTION__ ":" +#define FILE_LINE_STRING __FILE__ "(" V_STRINGIFY(__LINE__) "):" +#define FUNCTION_LINE_STRING __FUNCTION__ "(" V_STRINGIFY(__LINE__) "): " + +// Handy define for inserting clickable messages into the build output. +// Use like this: +// #pragma MESSAGE("Some message") +#define MESSAGE(msg) message(__FILE__ "(" V_STRINGIFY(__LINE__) "): " msg) + #if !defined( _X360 ) || !defined( _RETAIL ) diff --git a/public/tier0/fasttimer.h b/public/tier0/fasttimer.h index e9833b29..4c474421 100644 --- a/public/tier0/fasttimer.h +++ b/public/tier0/fasttimer.h @@ -222,8 +222,6 @@ private: unsigned m_nIters; CCycleCount m_Total; CCycleCount m_Peak; - bool m_fReport; - const tchar *m_pszName; }; // -------------------------------------------------------------------------- // @@ -499,10 +497,10 @@ public: CLimitTimer() {} CLimitTimer( uint64 cMicroSecDuration ) { SetLimit( cMicroSecDuration ); } void SetLimit( uint64 m_cMicroSecDuration ); - bool BLimitReached(); + bool BLimitReached() const; - int CMicroSecOverage(); - uint64 CMicroSecLeft(); + int CMicroSecOverage() const; + uint64 CMicroSecLeft() const; private: uint64 m_lCycleLimit; @@ -526,7 +524,7 @@ inline void CLimitTimer::SetLimit( uint64 cMicroSecDuration ) // Purpose: Determines whether our specified time period has passed // Output: true if at least the specified time period has passed //----------------------------------------------------------------------------- -inline bool CLimitTimer::BLimitReached( ) +inline bool CLimitTimer::BLimitReached() const { CCycleCount cycleCount; cycleCount.Sample( ); @@ -538,7 +536,7 @@ inline bool CLimitTimer::BLimitReached( ) // Purpose: If we're over our specified time period, return the amount of the overage. // Output: # of microseconds since we reached our specified time period. //----------------------------------------------------------------------------- -inline int CLimitTimer::CMicroSecOverage() +inline int CLimitTimer::CMicroSecOverage() const { CCycleCount cycleCount; cycleCount.Sample(); @@ -555,7 +553,7 @@ inline int CLimitTimer::CMicroSecOverage() // Purpose: If we're under our specified time period, return the amount under. // Output: # of microseconds until we reached our specified time period, 0 if we've passed it //----------------------------------------------------------------------------- -inline uint64 CLimitTimer::CMicroSecLeft() +inline uint64 CLimitTimer::CMicroSecLeft() const { CCycleCount cycleCount; cycleCount.Sample(); diff --git a/public/tier0/icommandline.h b/public/tier0/icommandline.h index abe21340..64d2e800 100644 --- a/public/tier0/icommandline.h +++ b/public/tier0/icommandline.h @@ -40,6 +40,8 @@ public: // copies the string passwed virtual void SetParm( int nIndex, char const *pNewParm ) =0; + + virtual const char *ParmValueByIndex( int nIndex, const char *pDefaultVal = 0 ) const = 0; }; //----------------------------------------------------------------------------- diff --git a/public/tier0/memoverride.cpp b/public/tier0/memoverride.cpp index e663094d..1f6c3f5c 100644 --- a/public/tier0/memoverride.cpp +++ b/public/tier0/memoverride.cpp @@ -811,9 +811,7 @@ void InvalidParameterViolation() // Disable compiler optimizations. If we don't do this then VC++ generates code // that confuses the Visual Studio debugger and causes it to display completely // random call stacks. That makes the minidumps excruciatingly hard to understand. -#ifdef _WIN32 #pragma optimize("", off) -#endif // Write a minidump file, unless running under the debugger in which case break // into the debugger. @@ -850,9 +848,7 @@ void VInvalidParameterHandler(const wchar_t* expression, } // Restore compiler optimizations. -#ifdef _WIN32 #pragma optimize("", on) -#endif // Helper class for registering error callbacks. See above for details. class ErrorHandlerRegistrar @@ -1147,7 +1143,6 @@ _TSCHAR * __cdecl _ttempnam ( const _TSCHAR *dir, const _TSCHAR *pfx ) Assert(0); return 0; } -#endif wchar_t * __cdecl _wcsdup_dbg ( const wchar_t * string, int nBlockUse, const char * szFileName, int nLine ) { @@ -1160,7 +1155,7 @@ wchar_t * __cdecl _wcsdup ( const wchar_t * string ) Assert(0); return 0; } - +#endif } // end extern "C" #if _MSC_VER >= 1400 diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 8d6ce1b1..5b4646a7 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -90,7 +90,9 @@ #define IsLinux() false #define IsOSX() false #define IsPosix() false + #ifndef PLATFORM_WINDOWS #define PLATFORM_WINDOWS 1 // Windows PC or Xbox 360 + #endif #ifndef _X360 #define IsWindows() true #define IsPC() true @@ -229,16 +231,16 @@ typedef double float64; // for when we don't care about how many bits we use typedef unsigned int uint; -#if defined(__clang__) -#define CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) -#endif - #ifdef _MSC_VER #pragma once // Ensure that everybody has the right compiler version installed. The version // number can be obtained by looking at the compiler output when you type 'cl' // and removing the last two digits and the periods: 16.00.40219.01 becomes 160040219 -#if _MSC_FULL_VER > 160000000 +#if _MSC_FULL_VER > 180000000 + #if _MSC_FULL_VER < 180030723 + #error You must install VS 2013 Update 3 + #endif +#elif _MSC_FULL_VER > 160000000 #if _MSC_FULL_VER < 160040219 #error You must install VS 2010 SP1 #endif @@ -405,6 +407,12 @@ typedef void * HINSTANCE; #endif #define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() +#ifdef STAGING_ONLY +#define DebuggerBreakIfDebugging_StagingOnly() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() +#else +#define DebuggerBreakIfDebugging_StagingOnly() +#endif + // C functions for external declarations that call the appropriate C++ methods #ifndef EXPORT #ifdef _WIN32 @@ -504,8 +512,7 @@ typedef void * HINSTANCE; #define FMTFUNCTION( a, b ) #elif defined(GNUC) #define SELECTANY __attribute__((weak)) - // Versions of clang older than 3.4 or Apple's 5.1 mangle member function names with the __restrict modifier in a GCC-incompatible way - #if ( defined(LINUX) && !defined(DEDICATED) ) || ( defined(__clang__) && ( ( defined(__apple_build_version__) && CLANG_VERSION < 501 ) || CLANG_VERSION < 304 ) ) + #if defined(LINUX) && !defined(DEDICATED) #define RESTRICT #else #define RESTRICT __restrict @@ -675,7 +682,7 @@ typedef void * HINSTANCE; // When we port to 64 bit, we'll have to resolve the int, ptr vs size_t 32/64 bit problems... -#if !defined( _WIN64 ) && defined ( _WIN32 ) +#if !defined( _WIN64 ) #pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data #pragma warning( disable : 4311 ) // pointer truncation from 'char *' to 'int' #pragma warning( disable : 4312 ) // conversion from 'unsigned int' to 'memhandle_t' of greater size @@ -1095,7 +1102,6 @@ PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode(); PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded. PLATFORM_INTERFACE unsigned int Plat_MSTime(); // Time in milliseconds. -PLATFORM_INTERFACE char * Plat_asctime( const struct tm *tm, char *buf ); PLATFORM_INTERFACE char * Plat_ctime( const time_t *timep, char *buf, size_t bufsize ); PLATFORM_INTERFACE struct tm * Plat_gmtime( const time_t *timep, struct tm *result ); PLATFORM_INTERFACE time_t Plat_timegm( struct tm *timeptr ); @@ -1149,7 +1155,7 @@ inline uint64 Plat_Rdtsc() memcpy( this, &src, sizeof(_classname) ); \ return *this; \ } - + // Processor Information: struct CPUInformation { @@ -1253,7 +1259,7 @@ PLATFORM_INTERFACE void* Plat_SimpleLog( const tchar* file, int line ); // Returns true if debugger attached, false otherwise //----------------------------------------------------------------------------- #if defined(_WIN32) || defined(LINUX) || defined(OSX) -PLATFORM_INTERFACE bool Plat_IsInDebugSession( bool bForceRecheck = false ); +PLATFORM_INTERFACE bool Plat_IsInDebugSession(); PLATFORM_INTERFACE void Plat_DebugString( const char * ); #else inline bool Plat_IsInDebugSession( bool bForceRecheck = false ) { return false; } @@ -1569,6 +1575,20 @@ private: #endif +// Watchdog timer support. Call Plat_BeginWatchdogTimer( nn ) to kick the timer off. if you don't call +// Plat_EndWatchdogTimer within nn seconds, the program will kick off an exception. This is for making +// sure that hung dedicated servers abort (and restart) instead of staying hung. Calling +// Plat_EndWatchdogTimer more than once or when there is no active watchdog is fine. Only does anything +// under linux right now. It should be possible to implement this functionality in windows via a +// thread, if desired. +PLATFORM_INTERFACE void Plat_BeginWatchdogTimer( int nSecs ); +PLATFORM_INTERFACE void Plat_EndWatchdogTimer( void ); +PLATFORM_INTERFACE int Plat_GetWatchdogTime( void ); + +typedef void (*Plat_WatchDogHandlerFunction_t)(void); +PLATFORM_INTERFACE void Plat_SetWatchdogHandlerFunction( Plat_WatchDogHandlerFunction_t function ); + + //----------------------------------------------------------------------------- #include "tier0/valve_on.h" diff --git a/public/tier0/threadtools.h b/public/tier0/threadtools.h index 7faeff72..d4eecb5f 100644 --- a/public/tier0/threadtools.h +++ b/public/tier0/threadtools.h @@ -346,7 +346,7 @@ template COMPILE_TIME_ASSERT( sizeof(T) >= sizeof(int) ); } - operator const int() const { return (int)this->Get(); } + operator int() const { return (int)this->Get(); } int operator=( int i ) { this->Set( (intp)i ); return i; } int operator++() { T i = this->Get(); this->Set( ++i ); return (int)i; } @@ -1227,9 +1227,9 @@ protected: CThreadMutex m_Lock; #ifdef WIN32 - const ThreadHandle_t GetThreadID() const { return (ThreadHandle_t)m_hThread; } + ThreadHandle_t GetThreadID() const { return (ThreadHandle_t)m_hThread; } #else - const ThreadId_t GetThreadID() const { return (ThreadId_t)m_threadId; } + ThreadId_t GetThreadID() const { return (ThreadId_t)m_threadId; } #endif private: diff --git a/public/tier0/tmapi_dummy.h b/public/tier0/tmapi_dummy.h index 348d2c9d..1a0362bc 100644 --- a/public/tier0/tmapi_dummy.h +++ b/public/tier0/tmapi_dummy.h @@ -30,11 +30,17 @@ #define tmEnterEx(...) #define tmZone(...) #define tmZoneFiltered(...) +#define tmLeave(...) #define tmLeaveEx(...) #define tmBeginTimeSpan(...) #define tmEndTimeSpan(...) +#define tmBeginTimeSpanAt(...) +#define tmEndTimeSpanAt(...) + +#define tmDynamicString(...) "" + #define tmEmitAccumulationZone(...) #define tmGetStati(...) 0 diff --git a/public/tier0/vprof.h b/public/tier0/vprof.h index 5267495f..282e65b2 100644 --- a/public/tier0/vprof.h +++ b/public/tier0/vprof.h @@ -135,10 +135,10 @@ #define VPROF_BUDGETGROUP_JOBS_COROUTINES _T("Jobs/Coroutines") #define VPROF_BUDGETGROUP_SLEEPING _T("Sleeping") #define VPROF_BUDGETGROUP_THREADINGMAIN _T("ThreadingMain") -#define VPROF_BUDGETGROUP_CHROMEHTML _T("Chromehtml") -#define VPROF_BUDGETGROUP_VGUI VPROF_BUDGETGROUP_CHROMEHTML -#define VPROF_BUDGETGROUP_TENFOOT VPROF_BUDGETGROUP_CHROMEHTML -#define VPROF_BUDGETGROUP_STEAMUI VPROF_BUDGETGROUP_CHROMEHTML +#define VPROF_BUDGETGROUP_HTMLSURFACE _T("HTMLSurface") +#define VPROF_BUDGETGROUP_VGUI VPROF_BUDGETGROUP_HTMLSURFACE +#define VPROF_BUDGETGROUP_TENFOOT VPROF_BUDGETGROUP_HTMLSURFACE +#define VPROF_BUDGETGROUP_STEAMUI VPROF_BUDGETGROUP_HTMLSURFACE #define VPROF_BUDGETGROUP_ATTRIBUTES _T("Attributes") #ifdef _X360 @@ -161,28 +161,28 @@ #define VPROF_VAR_NAME_INTERNAL( a, b ) VPROF_VAR_NAME_INTERNAL_CAT( a, b ) #define VPROF_VAR_NAME( a ) VPROF_VAR_NAME_INTERNAL( a, __LINE__ ) -#define VPROF_0(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL2, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 0, group, assertAccounted, budgetFlags); +#define VPROF_0(name,group,assertAccounted,budgetFlags) tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 0, group, assertAccounted, budgetFlags); #if VPROF_LEVEL > 0 -#define VPROF_1(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL3, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 1, group, assertAccounted, budgetFlags); +#define VPROF_1(name,group,assertAccounted,budgetFlags) tmZone( TELEMETRY_LEVEL3, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 1, group, assertAccounted, budgetFlags); #else #define VPROF_1(name,group,assertAccounted,budgetFlags) ((void)0) #endif #if VPROF_LEVEL > 1 -#define VPROF_2(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL4, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 2, group, assertAccounted, budgetFlags); +#define VPROF_2(name,group,assertAccounted,budgetFlags) CVProfScope VPROF_VAR_NAME( VProf_ )(name, 2, group, assertAccounted, budgetFlags); #else #define VPROF_2(name,group,assertAccounted,budgetFlags) ((void)0) #endif #if VPROF_LEVEL > 2 -#define VPROF_3(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL5, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 3, group, assertAccounted, budgetFlags); +#define VPROF_3(name,group,assertAccounted,budgetFlags) CVProfScope VPROF_VAR_NAME( VProf_ )(name, 3, group, assertAccounted, budgetFlags); #else #define VPROF_3(name,group,assertAccounted,budgetFlags) ((void)0) #endif #if VPROF_LEVEL > 3 -#define VPROF_4(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL6, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 4, group, assertAccounted, budgetFlags); +#define VPROF_4(name,group,assertAccounted,budgetFlags) CVProfScope VPROF_VAR_NAME( VProf_ )(name, 4, group, assertAccounted, budgetFlags); #else #define VPROF_4(name,group,assertAccounted,budgetFlags) ((void)0) #endif diff --git a/public/tier0/vprof_telemetry.h b/public/tier0/vprof_telemetry.h index 2b9c323a..e604638b 100644 --- a/public/tier0/vprof_telemetry.h +++ b/public/tier0/vprof_telemetry.h @@ -15,947 +15,19 @@ #define RAD_TELEMETRY_ENABLED #endif -#endif // !defined( MAKE_VPC ) +#endif // !MAKE_VPC #if !defined( RAD_TELEMETRY_ENABLED ) // -// If Telemetry isn't enabled, then kill all the tmZone() macros, etc. +// Kill all tmZone() macros, etc. // -#define NTELEMETRY 1 -// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here. -#undef RADCOPYRIGHT - #include "tmapi_dummy.h" inline void TelemetryTick() {} inline void TelemetrySetLevel( unsigned int Level ) {} - -#define TELEMETRY_REQUIRED( tmRequiredCode ) //a basic wrapper to only enable code if telemetry is present -#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) replacementCode //in case you need to replace the code with something specific if telemetry isn't present - -//#define TMZF_NONE - -#else - -// -// Telemetry is enabled. Include the telemetry header. -// -#include "../../thirdparty/telemetry/include/telemetry.h" -// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here. -#undef RADCOPYRIGHT - -PLATFORM_INTERFACE void TelemetryTick(); -PLATFORM_INTERFACE void TelemetrySetLevel( unsigned int Level ); - -struct TelemetryData -{ - HTELEMETRY tmContext[32]; - float flRDTSCToMilliSeconds; // Conversion from tmFastTime() (rdtsc) to milliseconds. - uint32 FrameCount; // Count of frames to capture before turning off. - char ServerAddress[128]; // Server name to connect to. - uint32 ZoneFilterVal; // tmZoneFiltered default filtered value (in MicroSeconds) - int playbacktick; // GetPlaybackTick() value from demo file (or 0 if not playing a demo). - float dotatime; // CDOTAGamerules::GetDOTATime() - uint32 DemoTickStart; // Start telemetry on demo tick # - uint32 DemoTickEnd; // End telemetry on demo tick # - uint32 Level; // Current Telemetry level (Use TelemetrySetLevel to modify) -}; -PLATFORM_INTERFACE TelemetryData g_Telemetry; - -#define TELEMETRY_REQUIRED( tmRequiredCode ) tmRequiredCode //a basic wrapper to only enable code if telemetry is present -#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) tmRequiredCode //in case you need to replace the code with something specific if telemetry isn't present - -#endif // RAD_TELEMETRY_ENABLED - - - - - - - - - - -#define TELEMETRY_ERROR_BUILD_DISABLED TELEMETRY_REQUIRED_REPLACE( TMERR_DISABLED, 0x0001 ) -#define TELEMETRY_ERROR_DISCONNECTED TELEMETRY_REQUIRED_REPLACE( TMCS_DISCONNECTED, 0 ) - - -#define TELEMETRY_LEVEL0 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[0], 0 ) // high level tmZone() -#define TELEMETRY_LEVEL1 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[1], 0 ) // lower level tmZone(), tmZoneFiltered() -#define TELEMETRY_LEVEL2 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[2], 0 ) // VPROF_0 -#define TELEMETRY_LEVEL3 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[3], 0 ) // VPROF_1 -#define TELEMETRY_LEVEL4 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[4], 0 ) // VPROF_2 -#define TELEMETRY_LEVEL5 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[5], 0 ) // VPROF_3 -#define TELEMETRY_LEVEL6 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[6], 0 ) // VPROF_4 - -//__rdtsc() -#define TM_FAST_TIME() TELEMETRY_REQUIRED_REPLACE( tmFastTime(), 0 ) - - -//int RADEXPLINK tmLoadTelemetry( int const kUseCheckedDLL ); -// -//Description -// On dynamic library platforms, this function loads the Telemetry DLL (or shared library) and then hooks up all of the dynamic function pointers. -//Parameters -// kUseCheckedDLL [in] set to 0 if you want to use the release mode DLL or 1 if you want to use the checked DLL. The checked DLL is compiled with optimizations but does extra run time checks and reporting. -#define TM_LOAD_TELEMETRY(kUseCheckedDll) TELEMETRY_REQUIRED_REPLACE( tmLoadTelemetry(kUseCheckedDll), 0 ) - - -//TmErrorCode tmStartup( ); -// -//Description -// Starts up all of Telemetry. -#define TM_STARTUP() TELEMETRY_REQUIRED_REPLACE( tmStartup(), TELEMETRY_ERROR_BUILD_DISABLED ) - - -//void tmShutdown( ); -// -//Description -// Shuts down all of Telemetry. -#define TM_SHUTDOWN() TELEMETRY_REQUIRED( tmShutdown() ) - - -//TmErrorCode tmInitializeContext( HTELEMETRY * pcx,void * pArena,TmU32 const kArenaSize ); -// -//Description -// Initializes a context. -// -//Parameters -// pcx [out] pointer to a TmHandle in which to store a handle to the initialized context -// pArena [in] pointer to a memory buffer for use by Telemetry to create the context. Applications should never free or modify this memory unless tmShutdownContext has been called! -// kArenaSize [in] size of the memory buffer pointed to by pArena. You want this large enough so that Telemetry never stalls trying to send over the network, but not so large that it takes up too much memory from your app. A good initial value is 1MB. -#define TM_INITIALIZE_CONTEXT( pContext, pArena, kArenaSize ) TELEMETRY_REQUIRED_REPLACE( tmInitializeContext( pContext, pArena, kArenaSize ), TELEMETRY_ERROR_BUILD_DISABLED ) - - -//void tmZoneFiltered( HTELEMETRY cx,TmU64 const kThreshold,TmU32 const kFlags,char const * kpFormat,... ); -// -//Description -// Identical to tmZone however also allows specification of threshold duration. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kThreshold [in] microseconds that the zone must span before being sent to server. -// kFlags [in] flags for the zone (same as those passed to tmEnter. -// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers. -#define TM_ZONE_FILTERED( context, kThreshold, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZoneFiltered( context, kThreshold, kFlags, kpFormat, ##__VA_ARGS__ ) ) - - -//void tmZone( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormat,... ); -// -//Description -// Helper macro in C++ that creates an anonymous local object that automatically calls tmEnter and then tmLeave when exiting scope. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kFlags [in] flags for the zone (same as those passed to tmEnter -// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers. -#define TM_ZONE( context, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZone( context, kFlags, kpFormat, ##__VA_ARGS__ ) ) - -//Standardized zones -#define TM_ZONE_DEFAULT( context ) TM_ZONE( context, TMZF_NONE, __FUNCTION__ ) -#define TM_ZONE_IDLE( context ) TM_ZONE( context, TMZF_IDLE, __FUNCTION__ ) -#define TM_ZONE_STALL( context ) TM_ZONE( context, TMZF_STALL, __FUNCTION__ ) - - -//TmErrorCode tmCheckVersion( HTELEMETRY cx, TmU32 const major, TmU32 const minor, TmU32 const build, TmU32 const cust ); -// -//could not find documentation -#define TM_CHECK_VERSION( context, major, minor, build, cust ) TELEMETRY_REQUIRED_REPLACE( tmCheckVersion( context, major, minor, build, cust ), TELEMETRY_ERROR_BUILD_DISABLED ) - - -//TmErrorCode tmListenIPC( HTELEMETRY cx, char const *name ); -// -//could not find documentation -#define TM_LISTEN_IPC( context, name ) TELEMETRY_REQUIRED_REPLACE( tmListenIPC( context, name ), TELEMETRY_ERROR_BUILD_DISABLED ) - - -//void tmUpdateSymbolData( HTELEMETRY cx ); -// -//Description -// Tells Telemetry to rescan loaded modules for symbol database information. -// -//Parameters -// cx [in] a valid context -#define TM_UPDATE_SYMBOL_DATA( context ) TELEMETRY_REQUIRED( tmUpdateSymbolData( context ) ) - - -//TmErrorCode tmGetSessionName( HTELEMETRY cx,char * dst,int const kDstSize ); -// -//Description -// Gets the name of the current session as determined by the server. -// -//Parameters -// cx [in] a valid context -// dst [in] pointer to buffer in which to copy the name -// kDstSize [in] size of dst -#define TM_GET_SESSION_NAME( context, dst, kDstSize ) TELEMETRY_REQUIRED_REPLACE( tmGetSessionName( context, dst, kDstSize ), TELEMETRY_ERROR_BUILD_DISABLED ) - - -//void tmUnwindToDebugZoneLevel( HTELEMETRY cx,int const kLevel ); -// -//Description -// Unwinds the current thread's zone stack back to the given level. -// -//Parameters -// cx [in] a valid context -// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel -#define TM_UNWIND_TO_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmUnwindToDebugZoneLevel( context, kLevel ) ) - - -//void tmSetDebugZoneLevel( HTELEMETRY cx,int const kLevel ); -// -//Description -// Set the Telemetry debug zone level. -// -//Parameters -// cx [in] a valid context -// kLevel [in] an arbitrary constant used to differentiate this zone level from another -#define TM_SET_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmSetDebugZoneLevel( context, kLevel ) ) - - -//void tmCheckDebugZoneLevel( HTELEMETRY cx,int const kLevel ); -// -//Description -// Check the current Telemetry debug zone level. -// -//Parameters -// cx [in] a valid context -// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel -#define TM_CHECK_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmCheckDebugZoneLevel( context, kLevel ) ) - - -//int tmGetCallStack( HTELEMETRY cx,TmCallStack * dst ); -// -//Description -// Retrieves the callstack for the current thread. -// -//Parameters -// cx [in] a valid context -// dst [in] TmCallStack structure in which to store the callstack information -#define TM_GET_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmGetCallStack( context, TmCallStack_Ptr ), 0 ) - - -//int tmSendCallStack( HTELEMETRY cx,TmCallStack const * kpCallStack ); -// -//Description -// Sends the current callstack to the server so that later references with string format specifiers are up to date. -// -//Parameters -// cx [in] a valid context -// kpCallStack [in] pointer to a pre-existing callstack or 0 if it should use the current callstack -#define TM_SEND_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmSendCallStack( context, TmCallStack_Ptr ), 0 ) - - -//TmErrorCode tmGetLastError( HTELEMETRY cx ); -// -//Description -// Returns and clears the current error condition for the given context. -// -//Parameters -// cx [in] handle to a valid Telemetry context -#define TM_GET_LAST_ERROR( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastError( context ), TELEMETRY_ERROR_BUILD_DISABLED ) - - -//void tmShutdownContext( HTELEMETRY cx ); -// -//Description -// Shuts down the given context. -// -//Parameters -// cx [in] handle to a valid context -#define TM_SHUTDOWN_CONTEXT( context ) TELEMETRY_REQUIRED( tmShutdownContext( context ) ) - - -//TmU64 tmGetAccumulationStart( HTELEMETRY cx ); -// -//Description -// Gets the start time for a set of accumulation zones. -// -//Parameters -// cx [in] handle to a telemetry context -// -//Return value -// return [out] start time for use with tmEmitAccumulationZone. -#define TM_GET_ACCUMULATION_START( context ) TELEMETRY_REQUIRED_REPLACE( tmGetAccumulationStart( context ), 0 ) - - -//TmU64 tmGetLastContextSwitchTime( HTELEMETRY cx ); -// -//Description -// Returns the time of the last received context switch event. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// -//Return value -// return [out] the time of the last received context switch event, or 0 on failure (e.g. invalid context, context switches disabled, etc.) -#define TM_GET_LAST_CONTEXT_SWITCH_TIME( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastContextSwitchTime( context ), 0 ) - - -//void tmEnterAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable ); -// -//Description -// Updates a zone variable passed to tmEmitAccumulationZone later. -// -//Parameters -// cx [in] handle to a telemetry context -// zone_variable [in] zone_variable to update -#define TM_ENTER_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmEnterAccumulationZone( context, zone_variable ) ) - - -//void tmLeaveAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable ); -// -//Description -// Updates a zone variable passed to tmEmitAccumulationZone later. -// -//Parameters -// cx [in] handle to a telemetry context -// zone_variable [in] zone_variable to update -#define TM_LEAVE_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmLeaveAccumulationZone( context, zone_variable ) ) - - -//void tmGetFormatCode( TmU32* pCode, char const * kpFmt ); -// -//could not find documentation -#define TM_GET_FORMAT_CODE( context, pCode, kpFmt ) TELEMETRY_REQUIRED( tmGetFormatCode( context, pCode, kpFmt ) ) - - -//char const * tmDynamicString( HTELEMETRY cx,char const * kpString ); -// -//Description -// Returns an opaque string identifier usable by Telemetry that is a copy of the kpString parameter. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpString [in] string to copy -#define TM_DYNAMIC_STRING( context, kpString ) TELEMETRY_REQUIRED_REPLACE( tmDynamicString( context, kpString ), NULL ) - - -//void tmClearStaticString( HTELEMETRY cx,char const * kpString ); -// -//Description -// Marks the given string pointer as 'changed', forcing Telemetry to resend its contents. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpString [in] string to reset -#define TM_CLEAR_STATIC_STRING( context, kpString ) TELEMETRY_REQUIRED( tmClearStaticString( context, kpString ) ) - - -//void tmEnable( HTELEMETRY cx,TmOption const kOption,int const kValue ); -// -//Description -// Enables or disables a specific Telemetry option. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kOption [in] the option to modify. One of the TmOption constants. -// kValue [in] the new value for the option. Must be 0 (disable) or 1 (enable). -#define TM_ENABLE( context, kOption, kValue ) TELEMETRY_REQUIRED( tmEnable( context, kOption, kValue ) ) - - -//int tmIsEnabled( HTELEMETRY cx,TmOption const kOption ); -// -//Description -// Inspects the state of a Telemetry option. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kOption [in] the option to inspect. Must be one of the TmOption constants. -// -//Return value -// return [out] 1 if the option is enabled, 0 if not enabled. In case of error, 0 is enabled and last error is set. -#define TM_IS_ENABLED( context, kOption ) TELEMETRY_REQUIRED_REPLACE( tmIsEnabled( context, kOption ), 0 ) - -//void tmSetParameter( HTELEMETRY cx,TmParameter const kParameter,void const * kpValue ); -// -//Description -// Sets a Telemetry parameter. -// -//Parameters -// cx [in] a valid context -// kParameter [in] TmParameter constant -// kpValue [in] pointer to value of the parameter. This varies depending on the value. -#define TM_SET_PARAMETER( context, kParameter, kpValue ) TELEMETRY_REQUIRED( tmSetParameter( context, kParameter, kpValue ) ) - - -//TmErrorCode tmOpen( HTELEMETRY cx,char const * kpAppName,char const * kpBuildInfo,char const * kpServerAddress,TmConnectionType const kConnection,TmU16 const kServerPort,TmU32 const kFlags,int const kTimeoutMS ); -// -//Description -// Starts a Telemetry context and attempts to connect to a Telemetry server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpAppName [in] name of the application. NOTE: This MUST be alphanumeric only, e.g. "Game234", no spaces, special characters, etc. are allowed. -// kpBuildInfo [in] information about the application. Used to annotate this Telemetry session. This information will show up when connecting to the server later to examine this particular run. Common uses include build numbers, compiled options, etc. -// kpServerAddress [in] name or IP address of the Telemetry server to connect to -// kConnection [in] type of connection to establish. Currently only TMCT_TCP is supported. -// kServerPort [in] port to connect to. Specify 0 or TELEMETRY_DEFAULT_PORT for the default port. -// kFlags [in] bitwise OR of TmOpenFlag flags -// kTimeoutMS [in] duration, in milliseconds, to wait for a connection to the Telemetry server. Specify -1 to wait indefinitely. -// -//Return value -// return [out] TM_OK on success, or on error one of the following: TMERR_INVALID_PARAM, TMERR_INVALID_CONTEXT, TMERR_UNKNOWN_NETWORK. -#define TM_OPEN( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ) TELEMETRY_REQUIRED_REPLACE( tmOpen( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ), TELEMETRY_ERROR_BUILD_DISABLED ) - - -//void tmClose( HTELEMETRY cx ); -// -//Description -// Closes a context previously opened with tmOpen. -// -//Parameters -// cx [in] handle to a valid and open Telemetry context -#define TM_CLOSE( context ) TELEMETRY_REQUIRED( tmClose( context ) ) - - -//void tmTick( HTELEMETRY cx ); -// -//Description -// "Ticks" the Telemetry context, i.e. signifies the end of a frame of execution so that Telemetry can perform internal processing and send data to the Telemetry server. -// -//Parameters -// cx [in] handle to a valid and open Telemetry context -#define TM_TICK( context ) TELEMETRY_REQUIRED( tmTick( context ) ) - - -//void tmFlush( HTELEMETRY cx ); -// -//cannot find documentation -#define TM_FLUSH( context ) TELEMETRY_REQUIRED( tmFlush( context ) ) - - -//void tmPause( HTELEMETRY cx,int const kPause ); -// -//Description -// Pauses/unpauses Telemetry capture. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kPause [in] 1 to pause, 0 to unpause -#define TM_PAUSE( context, kPause ) TELEMETRY_REQUIRED( tmPause( context, kPause ) ) - - -//int tmIsPaused( HTELEMETRY cx ); -// -//cannot find documentation. Presumably returns 1 if paused, 0 if not -#define TM_IS_PAUSED( context ) TELEMETRY_REQUIRED_REPLACE( tmIsPaused( context ), 0 ) - - -//TmConnectionStatus tmGetConnectionStatus( HTELEMETRY cx ); -// -//Description -// Get the current connection status. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// -//Return value -// return [out] a TmConnectionStatus constant. On error returns TMCS_DISCONNECTED and sets the context's last error. -#define TM_GET_CONNECTION_STATUS( context ) TELEMETRY_REQUIRED_REPLACE( tmGetConnectionStatus( context ), TELEMETRY_ERROR_DISCONNECTED ) - - -//void tmFree( HTELEMETRY cx,void const * kpPtr ); -// -//Description -// Notify Telemetry that memory has been freed. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpPtr [in] address of the old memory block previously passed to a tmAlloc call -#define TM_FREE( context, kpPtr ) TELEMETRY_REQUIRED( tmFree( context, kpPtr ) ) - - -//TmI32 tmGetStati( HTELEMETRY cx,TmStat const kStat ); -// -//Description -// Retrieves internal Telemetry statistics. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kStat [in] the TmStat to retrieve -// -//Return value -// return [out] the value of the indicated internal statistic. On error returns 0 and sets last error. -#define TM_GET_STAT_I( context, kStat ) TELEMETRY_REQUIRED_REPLACE( tmGetStati( context, kStat ), 0 ) - - -//void tmLeave( HTELEMETRY cx ); -// -//Description -// Notify Telemetry that a zone is being left. -// -//Parameters -// cx [in] handle to a valid Telemetry context -#define TM_LEAVE( context ) TELEMETRY_REQUIRED( tmLeave( context ) ) - - -//void tmLeaveEx( HTELEMETRY cx,TmU64 const kMatchId,TmU32 const kThreadId,char const * kpFilename,int const kLine ); -// -//Description -// Notify Telemetry that a zone is being left. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kMatchId [in] match id returned by tmEnterEx, used for Zones: Runtime Zone Filtering by Duration . Pass 0 if you're not filtering. -// kThreadId [in] thread id for this zone. Pass 0 for 'current thread'. -// kpFilename [in] name of the file -// kLine [in] line number for the leave -#define TM_LEAVE_EX( context, kMatchId, kThreadId, kpFilename, kLine ) TELEMETRY_REQUIRED( tmLeaveEx( context, kMatchId, kThreadId, kpFilename, kLine ) ) - - -//void tmTryLock( HTELEMETRY cx,void const * kPtr,char const * kpLockName,... ); -// -//Description -// Notify Telemetry that an attempt to grab a lock is beginning. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kPtr [in] pointer to the item being locked -// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers. -#define TM_TRY_LOCK( context, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLock( context, kPtr, kpLockName, ##__VA_ARGS__ ) ) - - -//void tmTryLockEx( HTELEMETRY cx,TmU64 * matcher,TmU64 const kThreshold,char const * kpFileName,int const kLine,void const * kPtr,char const * kpLockName,... ); -// -//Description -// Same as tmTryLock, but also specifying file and line information. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// matcher [in] reference in which to store a match ID used for later filtering by duration -// kpFileName [in] pointer to filename -// kLine [in] line number -// kPtr [in] pointer to the item being locked -// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers. -#define TM_TRY_LOCK_EX( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLockEx( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ##__VA_ARGS__ ) ) - - -//void tmEndTryLock( HTELEMETRY cx,void const * kPtr,TmLockResult const kResult ); -// -//Description -// Specify the result of a lock attempt previously started with tmTryLock. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kPtr [in] pointer for the object (mutex, etc.) being locked -// kResult [in] the result of the lock attempt, one of TmLockResult. -#define TM_END_TRY_LOCK( context, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLock( context, kPtr, kResult ) ) - - -//void tmEndTryLockEx( HTELEMETRY cx,TmU64 const kMatchId,char const * kpFileName,int const kLine,void const * kPtr,TmLockResult const kResult ); -// -//Description -// Specify the result of a lock attempt previously started with tmTryLock, but also with file and line information. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kMatchId [in] match id returned from tmTryLockEx -// kpFileName [in] pointer to filename -// kLine [in] line number -// kPtr [in] pointer for the object (mutex, etc.) being locked -// kResult [in] the result of the lock attempt, one of TmLockResult. -#define TM_END_TRY_LOCK_EX( context, kMatchId, kpFileName, kLine, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLockEx( context, kMatchId, kpFileName, kLine, kPtr, kResult ) ) - - -//void tmBeginTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... ); -// -//Description -// Start the beginning of a timespan. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kId [in] a user defined identifier for the timespan. Should be > 0. -// kFlags [in] flags for the timespan. Reserved, must be 0. -// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. -#define TM_BEGIN_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmEndTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... ); -// -//Description -// Mark the end a timespan. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan. -// kFlags [in] flags for the timespan. Reserved, must be 0. -// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. -#define TM_END_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmBeginTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... ); -// -//Description -// Start the beginning of a timespan but at an explicit time. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kId [in] a user defined identifier for the timespan. Should be > 0. -// kFlags [in] flags for the timespan. Reserved, must be 0. -// kTimeStamp [in] explicit timestamp (e.g. from tmFastTime) -// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. -#define TM_BEGIN_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmEndTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... ); -// -//Description -// Mark the end a timespan, but with an explicit timestamp. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan. -// kFlags [in] flags for the timespan. Reserved, must be 0. -// kTimeStamp [in] a user specified timestamp (e.g. from tmFastTime. -// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. -#define TM_END_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmSignalLockCount( HTELEMETRY cx,void const * kPtr,TmU32 const kCount,char const * kpDescription,... ); -// -//Description -// Signal that a semaphore's lock count has been incremented. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kPtr [in] pointer to the being whose count is being incremented (e.g. HANDLE) -// kCount [in] count value -// kpDescription [in] description of the event. This may contain printf-style format specifiers. -#define TM_SIGNAL_LOCK_COUNT( context, kPtr, kCount, kpDescription, ... ) TELEMETRY_REQUIRED( tmSignalLockCount( context, kPtr, kCount, kpDescription, ##__VA_ARGS__ ) ) - - -//void tmSetLockState( HTELEMETRY cx,void const * kPtr,TmLockState const kState,char const * kpDescription,... ); -// -//Description -// Sets the state of a lock (mutex, critical section, semaphore, etc.) -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kPtr [in] identifier for the lock, typically its address or HANDLE -// kState [in] new state of the lock -// kpDescription [in] description of the event. This may contain printf-style format specifiers. -#define TM_SET_LOCK_STATE( context, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockState( context, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) - - -//void tmSetLockStateEx( HTELEMETRY cx,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState ); -// -//Description -// Set the state of a lock but with explicit file and line information. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpFilename [in] filename where the state change occurs -// kLine [in] line number of the state change -// kPtr [in] identifier for the lock, typically its address or HANDLE -// kState [in] new state of the lock -// kpDescription [in] description of the event. This may contain printf-style format specifiers. -#define TM_SET_LOCK_STATE_EX( context, kpFileName, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateEx( context, kpFileName, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) - - -//void tmSetLockStateMinTime( HTELEMETRY cx,void * buf,void const * kPtr,TmLockState const kState,char const * fmt,... ); -// -//Description -// Set the state of a lock but with a minimum time threshold. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size. -// kPtr [in] identifier for the lock, typically its address or HANDLE -// kState [in] new state of the lock -// kpDescription [in] description of the event. This may contain printf-style format specifiers. -#define TM_SET_LOCK_STATE_MIN_TIME( context, buf, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTime( context, buf, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) - - -//void tmSetLockStateMinTimeEx( HTELEMETRY cx,void * buf,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState ); -// -//Description -// This is the 'Ex' version of tmSetLockStateMinTimeEx. Please refer to tmSetLockStateEx and tmSetLockStateMinTime for more information. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size. -// kpFilename [in] filename where the state change occurs -// kLine [in] line number of the state change -// kPtr [in] identifier for the lock, typically its address or HANDLE -// kState [in] new state of the lock -// kpDescription [in] description of the event. This may contain printf-style format specifiers. -#define TM_SET_LOCK_STATE_MIN_TIME_EX( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTimeEx( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) - - -//void tmThreadName( HTELEMETRY cx,TmU32 const kThreadID,char const * kpNameFormat,... ); -// -//Description -// Sets the name of the specified thread. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kThreadID [in] thread identifier of the thread to name. Use 0 to specify the current thread. -// kpNameFormat [in] name of the thread. This may contain printf-style format specifiers. -#define TM_THREAD_NAME( context, kThreadID, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmThreadName( context, kThreadID, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmLockName( HTELEMETRY cx,void const* kPtr,char const * kpNameFormat,... ); -// -//Description -// Sets the name of the specified locking object. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kPtr [in] identifier for the lock. Usually you can supply a pointer/HANDLE. -// kpNameFormat [in] name of the lock. This may contain printf-style format specifiers. -#define TM_LOCK_NAME( context, kPtr, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmLockName( context, kPtr, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmEmitAccumulationZone( HTELEMETRY cx,TmU32 const kZoneFlags,TmU64 * pStart,int const kCount,TmU64 const kTotal,char const * kpZoneFormat,... ); -// -//Description -// Emits an accumulation zone. -// -//Parameters -// cx [in] handle to a valid telemetry context -// kZoneFlags [in] reserved, must be 0 -// pStart [out] pointer to start time variable retrieved with a prior call to tmGetAccumulationStart. This value is modified. -// kCount [in] number of times the accumulation zone was called -// kTotal [in] total amount of time spent in the accumulation zone -// kpZoneFormat [in] name of the accumulation zone. This may contain printf-style format specifiers. -#define TM_EMIT_ACCUMULATION_ZONE( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ... ) TELEMETRY_REQUIRED( tmEmitAccumulationZone( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ##__VA_ARGS__ ) ) - - -//void tmSetVariable( HTELEMETRY cx,char const * kpKey,char const * kpValueFormat,... ); -// -//Description -// Binds a string to a key name and sends to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpKey [in] pointer to string identify the key being set -// kpValueFormat [in] pointer to string to bind to the associated key. This may contain printf-style format specifiers. -#define TM_SET_VARIABLE( context, kpKey, kpValueFormat, ... ) TELEMETRY_REQUIRED( tmSetVariable( context, kpKey, kpValueFormat, ##__VA_ARGS__ ) ) - - -//void tmSetTimelineSectionName( HTELEMETRY cx,char const * kpNameFormat,... ); -// -//Description -// Changes the name of the global state. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpNameFormat [in] name of the current state. This may contain printf-style format specifiers. -#define TM_SET_TIMELINE_SECTION_NAME( context, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmSetTimelineSectionName( context, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmEnter( HTELEMETRY cx,TmU32 const kFlags,char const * kpZoneName,... ); -// -//Description -// Notify Telemetry that a zone is being entered. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kFlags [in] Bitwise OR of TmZoneFlag -// kpZoneName [in] name of the zone. This may contain printf-style format specifiers. -#define TM_ENTER( context, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnter( context, kFlags, kpZoneName, ##__VA_ARGS__ ) ) - - -//void tmEnterEx( HTELEMETRY cx,TmU64 * pMatchId,TmU32 const kThreadId,TmU64 const kThreshold,char const * kpFilename,int const kLine,TmU32 const kFlags,char const * kpZoneName,... ); -// -//Description -// Notify Telemetry that a zone is being entered, but with explicit file and line information. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// pMatchId [in] pointer variable to assign a match ID, pass NULL if you are not Zones: Runtime Zone Filtering by Duration. -// kThreadId [in] thread ID for this zone, pass 0 for current thread -// kThreshold [in] microseconds that the zone must span before being sent to server. -// kpFilename [in] filename -// kLine [in] line number -// kFlags [in] Bitwise OR of TmZoneFlag -// kpZoneName [in] name of the zone. This may contain printf-style format specifiers. -#define TM_ENTER_EX( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnterEx( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ##__VA_ARGS__ ) ) - - -//void tmAlloc( HTELEMETRY cx,void const * kPtr,TmU64 const kSize,char const * kpDescription,... ); -// -//Description -// Notify Telemetry that memory has been allocated. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kPtr [in] address of the memory that has been allocated -// kSize [in] size of memory that has been allocated -// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers. -#define TM_ALLOC( context, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAlloc( context, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) ) - - -//void tmAllocEx( HTELEMETRY cx,char const * kpFilename,int const kLineNumber,void const * kPtr,TmU64 const kSize,char const * kpDescription,... ); -// -//Description -// Notify Telemetry that memory has been allocated, but with explicit file and line information. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpFilename [in] name of the file -// kLineNumber [in] line number of the allocation -// kPtr [in] address of the memory that has been allocated -// kSize [in] size of memory that has been allocated -// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers. -#define TM_ALLOC_EX( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAllocEx( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) ) - - -//void tmMessage( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormatString,... ); -// -//Description -// Send a message to the server for later viewing in the Visualizer. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kFlags [in] Bitwise OR of TmMessageFlag -// kpFormatString [in] message string (not to exceed TM_MAX_STRING in length). This may contain printf-style format specifiers. Note that the message may have a Telemetry object path in it so that it can be hierarchically displayed with other messages. -#define TM_MESSAGE( context, kFlags, kpFormatString, ... ) TELEMETRY_REQUIRED( tmMessage( context, kFlags, kpFormatString, ##__VA_ARGS__ ) ) -#define TM_LOG( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_LOG, kpFormatString, ##__VA_ARGS__ ) -#define TM_WARNING( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_WARNING, kpFormatString, ##__VA_ARGS__ ) -#define TM_ERROR( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_ERROR, kpFormatString, ##__VA_ARGS__ ) - - - -//void tmPlot( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... ); -// -//Description -// Sends a floating point plot value to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). -// kValue [in] the value of the plot at this moment in time -// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. -#define TM_PLOT( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlot( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) - - -//Identical to tmPlot() -//void tmPlotF32( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... ); -// -//Description -// Sends a floating point plot value to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). -// kValue [in] the value of the plot at this moment in time -// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. -#define TM_PLOT_F32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmPlotF64( HTELEMETRY cx,TmPlotType const kType,double const kValue,char const * kpNameFormat,... ); -// -//Description -// Sends a double precision floating point plot value to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). -// kValue [in] the value of the plot at this moment in time -// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. -#define TM_PLOT_F64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmPlotI32( HTELEMETRY cx,TmPlotType const kType,TmI32 const kValue,char const * kpNameFormat,... ); -// -//Description -// Sends an signed 32-bit value to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). -// kValue [in] the value of the plot at this moment in time -// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. -#define TM_PLOT_I32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmPlotU32( HTELEMETRY cx,TmPlotType const kType,TmU32 const kValue,char const * kpNameFormat,... ); -// -//Description -// Sends an unsigned 32-bit value to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). -// kValue [in] the value of the plot at this moment in time -// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. -#define TM_PLOT_U32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmPlotI64( HTELEMETRY cx,TmPlotType const kType,TmI64 const kValue,char const * kpNameFormat,... ); -// -//Description -// Sends an signed 64-bit value to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). -// kValue [in] the value of the plot at this moment in time -// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. -#define TM_PLOT_I64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmPlotU64( HTELEMETRY cx,TmPlotType const kType,TmU64 const kValue,char const * kpNameFormat,... ); -// -//Description -// Sends an unsigned 64-bit value to the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). -// kValue [in] the value of the plot at this moment in time -// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. -#define TM_PLOT_U64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) - - -//void tmBlob( HTELEMETRY cx,void const * kpData,int const kDataSize,char const * kpPluginIdentifier,char const * kpBlobName,... ); -// -//Description -// Sends an arbitrary application specified blob of binary data for storage on the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kpData [in] the actual blob data -// kDataSize [in] size of kpData in bytes -// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier). -// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers. -#define TM_BLOB( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ...) TELEMETRY_REQUIRED( tmBlob( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) ) - - -//void tmDisjointBlob( HTELEMETRY cx,int const kNumPieces,void const ** kpData,int const * kDataSizes,char const* kpPluginIdentifier,char const * kpBlobName,... ); -// -//Description -// Sends an arbitrary application specified blob of binary data for storage on the server. -// -//Parameters -// cx [in] handle to a valid Telemetry context -// kNumPieces [in] number of elements in kpData and kDataSizes -// kpData [in] array of actual data blobs -// kDataSizes [in] array of data blob sizes in bytes -// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier). -// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers. -#define TM_DISJOINT_BLOB( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ... ) TELEMETRY_REQUIRED( tmDisjointBlob( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) ) - - - - - - - - - - - - -#if !defined( RAD_TELEMETRY_ENABLED ) - -// -// Telemetry is disabled. -// +#define TelemetrySetLockName( _ctx, _location, _description ) class CTelemetryLock { @@ -973,13 +45,38 @@ public: ~CTelemetrySpikeDetector() { } }; -#define TelemetrySetLockName( _ctx, _location, _description ) - #else // -// Telemetry is enabled. +// Telemetry is enabled. Include the telemetry header. // +#include "../../thirdparty/telemetry/include/telemetry.h" +// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here. +#undef RADCOPYRIGHT + +struct TelemetryData +{ + HTELEMETRY tmContext[32]; + float flRDTSCToMilliSeconds; // Conversion from tmFastTime() (rdtsc) to milliseconds. + uint32 FrameCount; // Count of frames to capture before turning off. + char ServerAddress[128]; // Server name to connect to. + int playbacktick; // GetPlaybackTick() value from demo file (or 0 if not playing a demo). + uint32 DemoTickStart; // Start telemetry on demo tick # + uint32 DemoTickEnd; // End telemetry on demo tick # + uint32 Level; // Current Telemetry level (Use TelemetrySetLevel to modify) +}; +PLATFORM_INTERFACE TelemetryData g_Telemetry; + +PLATFORM_INTERFACE void TelemetryTick(); +PLATFORM_INTERFACE void TelemetrySetLevel( unsigned int Level ); + +#define TELEMETRY_LEVEL0 g_Telemetry.tmContext[0] // high level tmZone() +#define TELEMETRY_LEVEL1 g_Telemetry.tmContext[1] // lower level tmZone(), tmZoneFiltered() +#define TELEMETRY_LEVEL2 g_Telemetry.tmContext[2] // VPROF_0 +#define TELEMETRY_LEVEL3 g_Telemetry.tmContext[3] // VPROF_1 +#define TELEMETRY_LEVEL4 g_Telemetry.tmContext[4] // VPROF_2 +#define TELEMETRY_LEVEL5 g_Telemetry.tmContext[5] // VPROF_3 +#define TELEMETRY_LEVEL6 g_Telemetry.tmContext[6] // VPROF_4 #define TelemetrySetLockName( _ctx, _location, _description ) \ do \ @@ -1000,7 +97,7 @@ public: m_plocation = (const char *)plocation; m_description = description; TelemetrySetLockName( TELEMETRY_LEVEL1, m_plocation, m_description ); - TM_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, "%s", m_description ); + tmTryLock( TELEMETRY_LEVEL1, m_plocation, "%s", m_description ); } ~CTelemetryLock() { @@ -1008,14 +105,14 @@ public: } void Locked() { - TM_END_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS ); - TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked", m_description ); + tmEndTryLock( TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS ); + tmSetLockState( TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked", m_description ); } void Unlocked() { if( m_plocation ) { - TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_RELEASED, "%s Released", m_description ); + tmSetLockState( TELEMETRY_LEVEL1, m_plocation, TMLS_RELEASED, "%s Released", m_description ); m_plocation = NULL; } } @@ -1036,7 +133,7 @@ public: float time = ( tmFastTime() - time0 ) * g_Telemetry.flRDTSCToMilliSeconds; if( time >= m_threshold ) { - TM_MESSAGE( TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING, "(dota/spike)%s %.2fms %t", m_message, time, tmSendCallStack( TELEMETRY_LEVEL0, 0 ) ); + tmMessage( TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING, "(dota/spike)%s %.2fms %t", m_message, time, tmSendCallStack( TELEMETRY_LEVEL0, 0 ) ); } } diff --git a/public/tier1/KeyValues.h b/public/tier1/KeyValues.h index 2d46e377..eb214b45 100644 --- a/public/tier1/KeyValues.h +++ b/public/tier1/KeyValues.h @@ -174,7 +174,7 @@ public: const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ); const wchar_t *GetWString( const char *keyName = NULL, const wchar_t *defaultValue = L"" ); void *GetPtr( const char *keyName = NULL, void *defaultValue = (void*)0 ); - bool GetBool( const char *keyName = NULL, bool defaultValue = false ); + bool GetBool( const char *keyName = NULL, bool defaultValue = false, bool* optGotDefault = NULL ); Color GetColor( const char *keyName = NULL /* default value is all black */); bool IsEmpty(const char *keyName = NULL); diff --git a/public/tier1/UtlSortVector.h b/public/tier1/UtlSortVector.h index ec7d972d..5e49da52 100644 --- a/public/tier1/UtlSortVector.h +++ b/public/tier1/UtlSortVector.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // $Header: $ // $NoKeywords: $ @@ -45,31 +45,49 @@ public: template , class BaseVector = CUtlVector > class CUtlSortVector : public BaseVector { + typedef BaseVector BaseClass; public: - - // constructor + /// constructor CUtlSortVector( int nGrowSize = 0, int initSize = 0 ); CUtlSortVector( T* pMemory, int numElements ); - // inserts (copy constructs) an element in sorted order into the list + /// inserts (copy constructs) an element in sorted order into the list int Insert( const T& src ); - // Finds an element within the list using a binary search - int Find( const T& search ) const; - int FindLessOrEqual( const T& search ) const; - int FindLess( const T& search ) const; + /// inserts (copy constructs) an element in sorted order into the list if it isn't already in the list + int InsertIfNotFound( const T& src ); + + /// Finds an element within the list using a binary search. These are templatized based upon the key + /// in which case the less function must handle the Less function for key, T and T, key + template< typename TKey > + int Find( const TKey& search ) const; + template< typename TKey > + int FindLessOrEqual( const TKey& search ) const; + template< typename TKey > + int FindLess( const TKey& search ) const; - // Removes a particular element + /// Removes a particular element void Remove( const T& search ); void Remove( int i ); - // Allows methods to set a context to be used with the less function.. + /// Allows methods to set a context to be used with the less function.. void SetLessContext( void *pCtx ); - // Note that you can only use this index until sorting is redone!!! + /// A version of insertion that will produce an un-ordered list. + /// Note that you can only use this index until sorting is redone with RedoSort!!! int InsertNoSort( const T& src ); void RedoSort( bool bForceSort = false ); + /// Use this to insert at a specific insertion point; using FindLessOrEqual + /// is required for use this this. This will test that what you've inserted + /// produces a correctly ordered list. + int InsertAfter( int nElemIndex, const T &src ); + + /// finds a particular element using a linear search. Useful when used + /// in between calls to InsertNoSort and RedoSort + template< typename TKey > + int FindUnsorted( const TKey &src ) const; + protected: // No copy constructor CUtlSortVector( const CUtlSortVector & ); @@ -79,10 +97,9 @@ protected: int AddToTail(); int InsertBefore( int elem ); int InsertAfter( int elem ); + int InsertBefore( int elem, const T& src ); int AddToHead( const T& src ); int AddToTail( const T& src ); - int InsertBefore( int elem, const T& src ); - int InsertAfter( int elem, const T& src ); int AddMultipleToHead( int num ); int AddMultipleToTail( int num, const T *pToCopy=NULL ); int InsertMultipleBefore( int elem, int num, const T *pToCopy=NULL ); @@ -121,6 +138,9 @@ protected: bool m_bNeedsSort; private: + template< typename TKey > + int FindLessOrEqual( const TKey& search, bool *pFound ) const; + void QuickSort( LessFunc& less, int X, int I ); }; @@ -176,6 +196,43 @@ int CUtlSortVector::InsertNoSort( const T& src ) return lastElement; } +/// inserts (copy constructs) an element in sorted order into the list if it isn't already in the list +template +int CUtlSortVector::InsertIfNotFound( const T& src ) +{ + AssertFatal( !m_bNeedsSort ); + bool bFound; + int pos = FindLessOrEqual( src, &bFound ); + if ( bFound ) + return pos; + + ++pos; + this->GrowVector(); + this->ShiftElementsRight(pos); + CopyConstruct( &this->Element(pos), src ); + return pos; +} + +template +int CUtlSortVector::InsertAfter( int nIndex, const T &src ) +{ + int nInsertedIndex = this->BaseClass::InsertAfter( nIndex, src ); + +#ifdef DEBUG + LessFunc less; + if ( nInsertedIndex > 0 ) + { + Assert( less.Less( this->Element(nInsertedIndex-1), src, m_pLessContext ) ); + } + if ( nInsertedIndex < BaseClass::Count()-1 ) + { + Assert( less.Less( src, this->Element(nInsertedIndex+1), m_pLessContext ) ); + } +#endif + return nInsertedIndex; +} + + template void CUtlSortVector::QuickSort( LessFunc& less, int nLower, int nUpper ) { @@ -218,7 +275,8 @@ void CUtlSortVector::RedoSort( bool bForceSort /*= fals // finds a particular element //----------------------------------------------------------------------------- template -int CUtlSortVector::Find( const T& src ) const +template < typename TKey > +int CUtlSortVector::Find( const TKey& src ) const { AssertFatal( !m_bNeedsSort ); @@ -245,11 +303,34 @@ int CUtlSortVector::Find( const T& src ) const } +//----------------------------------------------------------------------------- +// finds a particular element using a linear search. Useful when used +// in between calls to InsertNoSort and RedoSort +//----------------------------------------------------------------------------- +template< class T, class LessFunc, class BaseVector > +template < typename TKey > +int CUtlSortVector::FindUnsorted( const TKey &src ) const +{ + LessFunc less; + int nCount = this->Count(); + for ( int i = 0; i < nCount; ++i ) + { + if ( less.Less( this->Element(i), src, m_pLessContext ) ) + continue; + if ( less.Less( src, this->Element(i), m_pLessContext ) ) + continue; + return i; + } + return -1; +} + + //----------------------------------------------------------------------------- // finds a particular element //----------------------------------------------------------------------------- template -int CUtlSortVector::FindLessOrEqual( const T& src ) const +template < typename TKey > +int CUtlSortVector::FindLessOrEqual( const TKey& src, bool *pFound ) const { AssertFatal( !m_bNeedsSort ); @@ -268,14 +349,26 @@ int CUtlSortVector::FindLessOrEqual( const T& src ) con } else { + *pFound = true; return mid; } } + + *pFound = false; return end; } template -int CUtlSortVector::FindLess( const T& src ) const +template < typename TKey > +int CUtlSortVector::FindLessOrEqual( const TKey& src ) const +{ + bool bFound; + return FindLessOrEqual( src, &bFound ); +} + +template +template < typename TKey > +int CUtlSortVector::FindLess( const TKey& src ) const { AssertFatal( !m_bNeedsSort ); diff --git a/public/tier1/bitbuf.h b/public/tier1/bitbuf.h index 04d77a03..b47d80d5 100644 --- a/public/tier1/bitbuf.h +++ b/public/tier1/bitbuf.h @@ -181,7 +181,7 @@ public: void WriteOneBitAt( int iBit, int nValue ); // Write signed or unsigned. Range is only checked in debug. - void WriteUBitLong( unsigned int data, int numbits, bool bCheckRange=true ) RESTRICT; + void WriteUBitLong( unsigned int data, int numbits, bool bCheckRange=true ); void WriteSBitLong( int data, int numbits ); // Tell it whether or not the data is unsigned. If it's signed, @@ -241,7 +241,7 @@ public: int GetNumBytesWritten() const; int GetNumBitsWritten() const; int GetMaxNumBits(); - int GetNumBitsLeft() RESTRICT; + int GetNumBitsLeft(); int GetNumBytesLeft(); unsigned char* GetData(); const unsigned char* GetData() const; @@ -250,7 +250,7 @@ public: bool CheckForOverflow(int nBits); inline bool IsOverflowed() const {return m_bOverflow;} - void SetOverflowFlag() RESTRICT; + void SetOverflowFlag(); public: @@ -292,7 +292,7 @@ inline int bf_write::GetMaxNumBits() return m_nDataBits; } -inline int bf_write::GetNumBitsLeft() RESTRICT +inline int bf_write::GetNumBitsLeft() { return m_nDataBits - m_iCurBit; } @@ -323,7 +323,7 @@ BITBUF_INLINE bool bf_write::CheckForOverflow(int nBits) return m_bOverflow; } -BITBUF_INLINE void bf_write::SetOverflowFlag() RESTRICT +BITBUF_INLINE void bf_write::SetOverflowFlag() { #ifdef DBGFLAG_ASSERT if ( m_bAssertOnOverflow ) @@ -635,7 +635,7 @@ public: public: int GetNumBytesLeft(); int GetNumBytesRead(); - int GetNumBitsLeft() RESTRICT; + int GetNumBitsLeft(); int GetNumBitsRead() const; // Has the buffer overflowed? @@ -645,7 +645,7 @@ public: inline bool SeekRelative(int iBitDelta); // Seek to an offset from the current position. // Called when the buffer is overflowed. - void SetOverflowFlag() RESTRICT; + void SetOverflowFlag(); public: @@ -678,7 +678,7 @@ inline int bf_read::GetNumBytesRead() return BitByte(m_iCurBit); } -inline int bf_read::GetNumBitsLeft() RESTRICT +inline int bf_read::GetNumBitsLeft() { return m_nDataBits - m_iCurBit; } diff --git a/public/tier1/byteswap.h b/public/tier1/byteswap.h index 4bda2b26..c7bc3c87 100644 --- a/public/tier1/byteswap.h +++ b/public/tier1/byteswap.h @@ -234,7 +234,7 @@ private: Assert( "Invalid size in CByteswap::LowLevelByteSwap" && 0 ); } #else - for( size_t i = 0; i < sizeof(T); i++ ) + for( int i = 0; i < sizeof(T); i++ ) { ((unsigned char* )&temp)[i] = ((unsigned char*)input)[sizeof(T)-(i+1)]; } diff --git a/public/tier1/convar.h b/public/tier1/convar.h index ba734947..fee4a1d5 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -66,7 +66,7 @@ void ConVar_PublishToVXConsole(); //----------------------------------------------------------------------------- // Called when a ConCommand needs to execute //----------------------------------------------------------------------------- -typedef void ( *FnCommandCallbackV1_t )( void ); +typedef void ( *FnCommandCallbackVoid_t )( void ); typedef void ( *FnCommandCallback_t )( const CCommand &command ); #define COMMAND_COMPLETION_MAXITEMS 64 @@ -142,7 +142,7 @@ public: virtual CVarDLLIdentifier_t GetDLLIdentifier() const; protected: - virtual void Create( const char *pName, const char *pHelpString = 0, + virtual void CreateBase( const char *pName, const char *pHelpString = 0, int flags = 0 ); // Used internally by OneTimeInit to initialize/shutdown @@ -270,7 +270,7 @@ friend class CCvar; public: typedef ConCommandBase BaseClass; - ConCommand( const char *pName, FnCommandCallbackV1_t callback, + ConCommand( const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); @@ -300,7 +300,7 @@ private: // Call this function when executing the command union { - FnCommandCallbackV1_t m_fnCommandCallbackV1; + FnCommandCallbackVoid_t m_fnCommandCallbackV1; FnCommandCallback_t m_fnCommandCallback; ICommandCallback *m_pCommandCallback; }; diff --git a/public/tier1/fmtstr.h b/public/tier1/fmtstr.h index baa870d0..0662aad4 100644 --- a/public/tier1/fmtstr.h +++ b/public/tier1/fmtstr.h @@ -31,28 +31,52 @@ int result; \ va_list arg_ptr; \ bool bTruncated = false; \ - static unsigned int scAsserted = 0; \ + static int scAsserted = 0; \ \ va_start(arg_ptr, lastArg); \ - result = Q_vsnprintfRet( (szBuf), nBufSize, (*(ppszFormat)), arg_ptr, &bTruncated ); \ + result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \ va_end(arg_ptr); \ \ + (szBuf)[(nBufSize)-1] = 0; \ if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \ { \ - Assert( !bTruncated ); \ + Warning( "FmtStrVSNPrintf truncated to %d without QUIET_TRUNCATION specified!\n", ( int )( nBufSize ) ); \ + AssertMsg( 0, "FmtStrVSNPrintf truncated without QUIET_TRUNCATION specified!\n" ); \ scAsserted++; \ } \ m_nLength = nPrevLen + result; \ } \ while (0) +// using macro to be compatable with GCC +#define FmtStrVSNPrintfNoLengthFixup( szBuf, nBufSize, bQuietTruncation, ppszFormat, nPrevLen, lastArg ) \ + do \ + { \ + int result; \ + va_list arg_ptr; \ + bool bTruncated = false; \ + static int scAsserted = 0; \ + \ + va_start(arg_ptr, lastArg); \ + result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \ + va_end(arg_ptr); \ + \ + (szBuf)[(nBufSize)-1] = 0; \ + if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \ + { \ + Warning( "FmtStrVSNPrintf truncated to %d without QUIET_TRUNCATION specified!\n", ( int )( nBufSize ) ); \ + AssertMsg( 0, "FmtStrVSNPrintf truncated without QUIET_TRUNCATION specified!\n" ); \ + scAsserted++; \ + } \ + } \ + while (0) //----------------------------------------------------------------------------- // // Purpose: String formatter with specified size // -template +template class CFmtStrN { public: @@ -80,14 +104,36 @@ public: // Explicit reformat const char *sprintf(PRINTF_FORMAT_STRING const char *pszFormat, ...) FMTFUNCTION( 2, 3 ) { - FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat, 0, pszFormat ); + InitQuietTruncation(); + FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat, 0, pszFormat ); + return m_szBuf; + } + + // Use this for va_list formatting + const char *sprintf_argv(const char *pszFormat, va_list arg_ptr) + { + int result; + bool bTruncated = false; + static int s_nWarned = 0; + + InitQuietTruncation(); + result = V_vsnprintfRet( m_szBuf, SIZE_BUF - 1, pszFormat, arg_ptr, &bTruncated ); + m_szBuf[SIZE_BUF - 1] = 0; + if ( bTruncated && !m_bQuietTruncation && ( s_nWarned < 5 ) ) + { + Warning( "CFmtStr truncated to %d without QUIET_TRUNCATION specified!\n", SIZE_BUF ); + AssertMsg( 0, "CFmtStr truncated without QUIET_TRUNCATION specified!\n" ); + s_nWarned++; + } + m_nLength = V_strlen( m_szBuf ); return m_szBuf; } // Use this for pass-through formatting void VSprintf(const char **ppszFormat, ...) { - FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat, 0, ppszFormat); + InitQuietTruncation(); + FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat, 0, ppszFormat ); } // Compatible API with CUtlString for converting to const char* @@ -97,14 +143,17 @@ public: operator const char *() const { return m_szBuf; } char *Access() { return m_szBuf; } - CFmtStrN & operator=( const char *pchValue ) + // Access template argument + static inline int GetMaxLength() { return SIZE_BUF-1; } + + CFmtStrN & operator=( const char *pchValue ) { V_strncpy( m_szBuf, pchValue, SIZE_BUF ); m_nLength = V_strlen( m_szBuf ); return *this; } - CFmtStrN & operator+=( const char *pchValue ) + CFmtStrN & operator+=( const char *pchValue ) { Append( pchValue ); return *this; @@ -112,13 +161,19 @@ public: int Length() const { return m_nLength; } + void SetLength( int nLength ) + { + m_nLength = Min( nLength, SIZE_BUF - 1 ); + m_szBuf[m_nLength] = '\0'; + } + void Clear() { m_szBuf[0] = 0; m_nLength = 0; } - void AppendFormat(PRINTF_FORMAT_STRING const char *pchFormat, ... ) FMTFUNCTION( 2, 3 ) + void AppendFormat( PRINTF_FORMAT_STRING const char *pchFormat, ... ) FMTFUNCTION( 2, 3 ) { char *pchEnd = m_szBuf + m_nLength; FmtStrVSNPrintf( pchEnd, SIZE_BUF - m_nLength, m_bQuietTruncation, &pchFormat, m_nLength, pchFormat ); @@ -163,14 +218,12 @@ public: void AppendIndent( uint32 unCount, char chIndent = '\t' ); + void SetQuietTruncation( bool bQuiet ) { m_bQuietTruncation = bQuiet; } + protected: virtual void InitQuietTruncation() { -#ifdef _DEBUG - m_bQuietTruncation = false; -#else - m_bQuietTruncation = true; // Force quiet for release builds -#endif + m_bQuietTruncation = QUIET_TRUNCATION; } bool m_bQuietTruncation; @@ -183,16 +236,14 @@ private: // Version which will not assert if strings are truncated -template -class CFmtStrQuietTruncationN : public CFmtStrN +template < int SIZE_BUF > +class CFmtStrQuietTruncationN : public CFmtStrN { -protected: - virtual void InitQuietTruncation() { this->m_bQuietTruncation = true; } }; -template< int SIZE_BUF > -void CFmtStrN::AppendIndent( uint32 unCount, char chIndent ) +template< int SIZE_BUF, bool QUIET_TRUNCATION > +void CFmtStrN< SIZE_BUF, QUIET_TRUNCATION >::AppendIndent( uint32 unCount, char chIndent ) { Assert( Length() + unCount < SIZE_BUF ); if( Length() + unCount >= SIZE_BUF ) @@ -204,8 +255,8 @@ void CFmtStrN::AppendIndent( uint32 unCount, char chIndent ) m_szBuf[ m_nLength ] = '\0'; } -template< int SIZE_BUF > -void CFmtStrN::AppendFormatV( const char *pchFormat, va_list args ) +template< int SIZE_BUF, bool QUIET_TRUNCATION > +void CFmtStrN< SIZE_BUF, QUIET_TRUNCATION >::AppendFormatV( const char *pchFormat, va_list args ) { int cubPrinted = V_vsnprintf( m_szBuf+Length(), SIZE_BUF - Length(), pchFormat, args ); m_nLength += cubPrinted; diff --git a/public/tier1/ilocalize.h b/public/tier1/ilocalize.h index a3dd6bb8..b0bece7f 100644 --- a/public/tier1/ilocalize.h +++ b/public/tier1/ilocalize.h @@ -401,6 +401,35 @@ public: } } + template < typename T, typename U, typename V, typename W, typename X, typename Y, typename Z > + CConstructLocalizedString( const locchar_t *loc_Format, T arg0, U arg1, V arg2, W arg3, X arg4, Y arg5, Z arg6) + { + COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); + COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); + COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); + COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); + COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); + COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); + COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); + + m_loc_Buffer[0] = '\0'; + + if ( loc_Format ) + { + ::ILocalize::ConstructString( m_loc_Buffer, + sizeof( m_loc_Buffer ), + loc_Format, + 7, + CLocalizedStringArg( arg0 ).GetLocArg(), + CLocalizedStringArg( arg1 ).GetLocArg(), + CLocalizedStringArg( arg2 ).GetLocArg(), + CLocalizedStringArg( arg3 ).GetLocArg(), + CLocalizedStringArg( arg4 ).GetLocArg(), + CLocalizedStringArg( arg5 ).GetLocArg(), + CLocalizedStringArg( arg6 ).GetLocArg() ); + } + } + CConstructLocalizedString( const locchar_t *loc_Format, KeyValues *pKeyValues ) { m_loc_Buffer[0] = '\0'; diff --git a/public/tier1/mempool.h b/public/tier1/mempool.h index 65eeb7c9..a5ddd0dd 100644 --- a/public/tier1/mempool.h +++ b/public/tier1/mempool.h @@ -30,19 +30,27 @@ typedef void (*MemoryPoolReportFunc_t)( PRINTF_FORMAT_STRING char const* pMsg, ... ); +// Ways a memory pool can grow when it needs to make a new blob: +enum MemoryPoolGrowType_t +{ + UTLMEMORYPOOL_GROW_NONE=0, // Don't allow new blobs. + UTLMEMORYPOOL_GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates + // get larger and larger each time it allocates one). + UTLMEMORYPOOL_GROW_SLOW=2 // New blob size is numElements. +}; + class CUtlMemoryPool { public: - // Ways the memory pool can grow when it needs to make a new blob. + // !KLUDGE! For legacy code support, import the global enum into this scope enum MemoryPoolGrowType_t { - GROW_NONE=0, // Don't allow new blobs. - GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates - // get larger and larger each time it allocates one). - GROW_SLOW=2 // New blob size is numElements. + GROW_NONE=UTLMEMORYPOOL_GROW_NONE, + GROW_FAST=UTLMEMORYPOOL_GROW_FAST, + GROW_SLOW=UTLMEMORYPOOL_GROW_SLOW }; - CUtlMemoryPool( int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 ); + CUtlMemoryPool( int blockSize, int numElements, int growMode = UTLMEMORYPOOL_GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 ); ~CUtlMemoryPool(); void* Alloc(); // Allocate the element size you specified in the constructor. @@ -103,7 +111,7 @@ protected: class CMemoryPoolMT : public CUtlMemoryPool { public: - CMemoryPoolMT(int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL) : CUtlMemoryPool( blockSize, numElements, growMode, pszAllocOwner) {} + CMemoryPoolMT(int blockSize, int numElements, int growMode = UTLMEMORYPOOL_GROW_FAST, const char *pszAllocOwner = NULL) : CUtlMemoryPool( blockSize, numElements, growMode, pszAllocOwner) {} void* Alloc() { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::Alloc(); } diff --git a/public/tier1/snappy-sinksource.h b/public/tier1/snappy-sinksource.h index c7c3df9d..2000a5f8 100644 --- a/public/tier1/snappy-sinksource.h +++ b/public/tier1/snappy-sinksource.h @@ -60,6 +60,7 @@ class Sink { // The default implementation always returns the scratch buffer. virtual char* GetAppendBuffer(size_t length, char* scratch); + private: // No copying Sink(const Sink&); diff --git a/public/tier1/snappy.h b/public/tier1/snappy.h index 1c9ad6bf..ad2d293f 100644 --- a/public/tier1/snappy.h +++ b/public/tier1/snappy.h @@ -49,17 +49,7 @@ #endif //_WIN32 #include -#include "tier0/platform.h" - -#define SNAPPY_MAJOR 1 -#define SNAPPY_MINOR 0 -#define SNAPPY_PATCHLEVEL 3 -#define SNAPPY_VERSION \ - ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) - -#define SNAPPY_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) +#include "snappy-stubs-public.h" namespace snappy { class Source; @@ -73,6 +63,13 @@ namespace snappy { // number of bytes written. size_t Compress(Source* source, Sink* sink); + // Find the uncompressed length of the given stream, as given by the header. + // Note that the true length could deviate from this; the stream could e.g. + // be truncated. + // + // Also note that this leaves "*source" in a state that is unsuitable for + // further operations, such as RawUncompress(). You will need to rewind + // or recreate the source yourself before attempting any further calls. bool GetUncompressedLength(Source* source, uint32* result); // ------------------------------------------------------------------------ @@ -134,6 +131,28 @@ namespace snappy { // returns false if the message is corrupted and could not be decrypted bool RawUncompress(Source* compressed, char* uncompressed); + // Given data in "compressed[0..compressed_length-1]" generated by + // calling the Snappy::Compress routine, this routine + // stores the uncompressed data to the iovec "iov". The number of physical + // buffers in "iov" is given by iov_cnt and their cumulative size + // must be at least GetUncompressedLength(compressed). The individual buffers + // in "iov" must not overlap with each other. + // + // returns false if the message is corrupted and could not be decrypted + bool RawUncompressToIOVec(const char* compressed, size_t compressed_length, + const struct iovec* iov, size_t iov_cnt); + + // Given data from the byte source 'compressed' generated by calling + // the Snappy::Compress routine, this routine stores the uncompressed + // data to the iovec "iov". The number of physical + // buffers in "iov" is given by iov_cnt and their cumulative size + // must be at least GetUncompressedLength(compressed). The individual buffers + // in "iov" must not overlap with each other. + // + // returns false if the message is corrupted and could not be decrypted + bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov, + size_t iov_cnt); + // Returns the maximal size of the compressed representation of // input data that is "source_bytes" bytes in length; size_t MaxCompressedLength(size_t source_bytes); @@ -152,20 +171,20 @@ namespace snappy { bool IsValidCompressedBuffer(const char* compressed, size_t compressed_length); - // *** DO NOT CHANGE THE VALUE OF kBlockSize *** + // The size of a compression block. Note that many parts of the compression + // code assumes that kBlockSize <= 65536; in particular, the hash table + // can only store 16-bit offsets, and EmitCopy() also assumes the offset + // is 65535 bytes or less. Note also that if you change this, it will + // affect the framing format (see framing_format.txt). // - // New Compression code chops up the input into blocks of at most - // the following size. This ensures that back-references in the - // output never cross kBlockSize block boundaries. This can be - // helpful in implementing blocked decompression. However the - // decompression code should not rely on this guarantee since older - // compression code may not obey it. - static const int kBlockLog = 15; - static const int kBlockSize = 1 << kBlockLog; + // Note that there might be older data around that is compressed with larger + // block sizes, so the decompression code should not rely on the + // non-existence of long backreferences. + static const int kBlockLog = 16; + static const size_t kBlockSize = 1 << kBlockLog; static const int kMaxHashTableBits = 14; - static const int kMaxHashTableSize = 1 << kMaxHashTableBits; - + static const size_t kMaxHashTableSize = 1 << kMaxHashTableBits; } // end namespace snappy diff --git a/public/tier1/strtools.h b/public/tier1/strtools.h index 6089a8f4..7182c193 100644 --- a/public/tier1/strtools.h +++ b/public/tier1/strtools.h @@ -337,6 +337,7 @@ bool Q_StripPrecedingAndTrailingWhitespaceW( wchar_t *pwch ); // like punctuation spaces, non-breaking spaces, composing characters, and so on bool Q_AggressiveStripPrecedingAndTrailingWhitespace( char *pch ); bool Q_AggressiveStripPrecedingAndTrailingWhitespaceW( wchar_t *pwch ); +bool Q_RemoveAllEvilCharacters( char *pch ); // Functions for converting hexidecimal character strings back into binary data etc. // @@ -765,6 +766,29 @@ private: }; +// Encodes a string (or binary data) in URL encoding format, see rfc1738 section 2.2. +// Dest buffer should be 3 times the size of source buffer to guarantee it has room to encode. +void Q_URLEncodeRaw( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ); + +// Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// Dest buffer should be at least as large as source buffer to gurantee room for decode. +// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. +// +// Returns the amount of space actually used in the output buffer. +size_t Q_URLDecodeRaw( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ); + +// Encodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces. +// This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data. +// Dest buffer should be 3 times the size of source buffer to guarantee it has room to encode. +void Q_URLEncode( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ); + +// Decodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces. +// This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data. +// Dest buffer should be at least as large as source buffer to gurantee room for decode. +// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. +// +// Returns the amount of space actually used in the output buffer. +size_t Q_URLDecode( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ); // NOTE: This is for backward compatability! diff --git a/public/tier1/utlblockmemory.h b/public/tier1/utlblockmemory.h index 925582f0..4e5998dc 100644 --- a/public/tier1/utlblockmemory.h +++ b/public/tier1/utlblockmemory.h @@ -249,15 +249,16 @@ void CUtlBlockMemory::ChangeSize( int nBlocks ) UTLBLOCKMEMORY_TRACK_ALLOC(); // this must stay after the recalculation of m_nBlocks, since it implicitly uses the new value - // free old blocks if shrinking - for ( int i = m_nBlocks; i < nBlocksOld; ++i ) - { - UTLBLOCKMEMORY_TRACK_FREE(); - free( (void*)m_pMemory[ i ] ); - } - if ( m_pMemory ) { + // free old blocks if shrinking + // Only possible if m_pMemory is non-NULL (and avoids PVS-Studio warning) + for ( int i = m_nBlocks; i < nBlocksOld; ++i ) + { + UTLBLOCKMEMORY_TRACK_FREE(); + free( (void*)m_pMemory[ i ] ); + } + MEM_ALLOC_CREDIT_CLASS(); m_pMemory = (T**)realloc( m_pMemory, m_nBlocks * sizeof(T*) ); Assert( m_pMemory ); diff --git a/public/tier1/utlmemory.h b/public/tier1/utlmemory.h index c937d5b1..4580b912 100644 --- a/public/tier1/utlmemory.h +++ b/public/tier1/utlmemory.h @@ -553,7 +553,7 @@ inline T& CUtlMemory::operator[]( I i ) // Avoid function calls in the asserts to improve debug build performance Assert( m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER ); //Assert( !IsReadOnly() ); Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[i]; + return m_pMemory[(uint32)i]; } template< class T, class I > @@ -561,7 +561,7 @@ inline const T& CUtlMemory::operator[]( I i ) const { // Avoid function calls in the asserts to improve debug build performance Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[i]; + return m_pMemory[(uint32)i]; } template< class T, class I > @@ -570,7 +570,7 @@ inline T& CUtlMemory::Element( I i ) // Avoid function calls in the asserts to improve debug build performance Assert( m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER ); //Assert( !IsReadOnly() ); Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[i]; + return m_pMemory[(uint32)i]; } template< class T, class I > @@ -578,7 +578,7 @@ inline const T& CUtlMemory::Element( I i ) const { // Avoid function calls in the asserts to improve debug build performance Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[i]; + return m_pMemory[(uint32)i]; } diff --git a/public/tier1/utlrbtree.h b/public/tier1/utlrbtree.h index 8184ac63..b2d147b2 100644 --- a/public/tier1/utlrbtree.h +++ b/public/tier1/utlrbtree.h @@ -217,6 +217,8 @@ public: void RemoveAll( ); void Purge(); + bool HasElement( T const &search ) const { return Find( search ) != InvalidIndex(); } + // Allocation, deletion void FreeNode( I i ); @@ -374,8 +376,8 @@ protected: template < class T, class I, typename L, class M > inline CUtlRBTree::CUtlRBTree( int growSize, int initSize, const LessFunc_t &lessfunc ) : -m_LessFunc( lessfunc ), m_Elements( growSize, initSize ), +m_LessFunc( lessfunc ), m_Root( InvalidIndex() ), m_NumElements( 0 ), m_FirstFree( InvalidIndex() ), @@ -386,8 +388,8 @@ m_LastAlloc( m_Elements.InvalidIterator() ) template < class T, class I, typename L, class M > inline CUtlRBTree::CUtlRBTree( const LessFunc_t &lessfunc ) : -m_LessFunc( lessfunc ), m_Elements( 0, 0 ), +m_LessFunc( lessfunc ), m_Root( InvalidIndex() ), m_NumElements( 0 ), m_FirstFree( InvalidIndex() ), diff --git a/public/tier1/utlstring.h b/public/tier1/utlstring.h index 26d98338..a57d069c 100644 --- a/public/tier1/utlstring.h +++ b/public/tier1/utlstring.h @@ -16,8 +16,7 @@ #include "limits.h" #if defined( OSX ) -#define wcsdup wcsdup_osx -inline wchar_t *wcsdup_osx(const wchar_t *pString) +inline wchar_t *wcsdup(const wchar_t *pString) { wchar_t *pMemory; @@ -32,98 +31,15 @@ inline wchar_t *wcsdup_osx(const wchar_t *pString) return NULL; } + +inline size_t strnlen(const char *s, size_t n) +{ + const char *p = (const char *)memchr(s, 0, n); + return (p ? p - s : n); +} + #endif -//----------------------------------------------------------------------------- -// Base class, containing simple memory management -//----------------------------------------------------------------------------- -class CUtlBinaryBlock -{ -public: - CUtlBinaryBlock( int growSize = 0, int initSize = 0 ); - - // NOTE: nInitialLength indicates how much of the buffer starts full - CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ); - CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ); - CUtlBinaryBlock( const CUtlBinaryBlock& src ); - - void Get( void *pValue, int nMaxLen ) const; - void Set( const void *pValue, int nLen ); - const void *Get( ) const; - void *Get( ); - - unsigned char& operator[]( int i ); - const unsigned char& operator[]( int i ) const; - - int Length() const; - void SetLength( int nLength ); // Undefined memory will result - bool IsEmpty() const; - void Clear(); - void Purge(); - - bool IsReadOnly() const; - - CUtlBinaryBlock &operator=( const CUtlBinaryBlock &src ); - - // Test for equality - bool operator==( const CUtlBinaryBlock &src ) const; - -private: - CUtlMemory m_Memory; - int m_nActualLength; -}; - - -//----------------------------------------------------------------------------- -// class inlines -//----------------------------------------------------------------------------- -inline const void *CUtlBinaryBlock::Get( ) const -{ - return m_Memory.Base(); -} - -inline void *CUtlBinaryBlock::Get( ) -{ - return m_Memory.Base(); -} - -inline int CUtlBinaryBlock::Length() const -{ - return m_nActualLength; -} - -inline unsigned char& CUtlBinaryBlock::operator[]( int i ) -{ - return m_Memory[i]; -} - -inline const unsigned char& CUtlBinaryBlock::operator[]( int i ) const -{ - return m_Memory[i]; -} - -inline bool CUtlBinaryBlock::IsReadOnly() const -{ - return m_Memory.IsReadOnly(); -} - -inline bool CUtlBinaryBlock::IsEmpty() const -{ - return Length() == 0; -} - -inline void CUtlBinaryBlock::Clear() -{ - SetLength( 0 ); -} - -inline void CUtlBinaryBlock::Purge() -{ - SetLength( 0 ); - m_Memory.Purge(); -} - - //----------------------------------------------------------------------------- // Simple string class. // NOTE: This is *not* optimal! Use in tools, but not runtime code @@ -140,95 +56,154 @@ public: public: CUtlString(); CUtlString( const char *pString ); + CUtlString( const char *pString, int length ); CUtlString( const CUtlString& string ); - // Attaches the string to external memory. Useful for avoiding a copy - CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ); - CUtlString( const void* pMemory, int nSizeInBytes ); +#ifdef MOVE_CONSTRUCTOR_SUPPORT + // Support moving of CUtlString objects. Long live C++11 + // This move constructor will get called when appropriate, such as when + // returning objects from functions, or otherwise copying from temporaries + // which are about to be destroyed. It can also be explicitly invoked with + // std::move(). + // Move constructor: + CUtlString( CUtlString&& rhs ) + { + // Move the string pointer from the source to this -- be sure to + // zero out the source to avoid double frees. + m_pString = rhs.m_pString; + rhs.m_pString = 0; + } + // Move assignment operator: + CUtlString& operator=( CUtlString&& rhs ) + { + // Move the string pointer from the source to this -- be sure to + // zero out the source to avoid double frees. + m_pString = rhs.m_pString; + rhs.m_pString = 0; + return *this; + } +#endif + + ~CUtlString(); const char *Get( ) const; void Set( const char *pValue ); - - void Clear() { Set( NULL ); } - - // Converts to c-strings operator const char*() const; + // Set directly and don't look for a null terminator in pValue. + // nChars does not include the nul and this will only copy + // at most nChars (even if pValue is longer). If nChars + // is >strlen(pValue) it will copy past the end, don't do it + // Does nothing if pValue == String() + void SetDirect( const char *pValue, int nChars ); + // for compatibility switching items from UtlSymbol const char *String() const { return Get(); } // Returns strlen int Length() const; + // IsEmpty() is more efficient than Length() == 0 bool IsEmpty() const; // Sets the length (used to serialize into the buffer ) // Note: If nLen != 0, then this adds an extra byte for a null-terminator. void SetLength( int nLen ); - char *Get(); + char *GetForModify(); + void Clear(); void Purge(); // Case Change void ToLower(); void ToUpper(); + void Append( const char *pAddition, int nChars ); void Append( const char *pchAddition ); - + void Append( const char chAddition ) { char temp[2] = { chAddition, 0 }; Append( temp ); } // Strips the trailing slash void StripTrailingSlash(); + void FixSlashes( char cSeparator = CORRECT_PATH_SEPARATOR ); + + // Trim whitespace + void TrimLeft( char cTarget ); + void TrimLeft( const char *szTargets = "\t\r\n " ); + void TrimRight( char cTarget ); + void TrimRight( const char *szTargets = "\t\r\n " ); + void Trim( char cTarget ); + void Trim( const char *szTargets = "\t\r\n " ); + + bool IsEqual_CaseSensitive( const char *src ) const; + bool IsEqual_CaseInsensitive( const char *src ) const; CUtlString &operator=( const CUtlString &src ); CUtlString &operator=( const char *src ); // Test for equality bool operator==( const CUtlString &src ) const; - bool operator==( const char *src ) const; bool operator!=( const CUtlString &src ) const { return !operator==( src ); } - bool operator!=( const char *src ) const { return !operator==( src ); } - - // If these are not defined, CUtlString as rhs will auto-convert - // to const char* and do logical operations on the raw pointers. Ugh. - inline friend bool operator==( const char *lhs, const CUtlString &rhs ) { return rhs.operator==( lhs ); } - inline friend bool operator!=( const char *lhs, const CUtlString &rhs ) { return rhs.operator!=( lhs ); } CUtlString &operator+=( const CUtlString &rhs ); CUtlString &operator+=( const char *rhs ); CUtlString &operator+=( char c ); CUtlString &operator+=( int rhs ); CUtlString &operator+=( double rhs ); - - // is valid? - bool IsValid() const; - bool MatchesPattern( const CUtlString &Pattern, int nFlags = 0 ); // case SENSITIVE, use * for wildcard in pattern string + CUtlString operator+( const char *pOther ) const; + CUtlString operator+( const CUtlString &other ) const; + CUtlString operator+( int rhs ) const; - int Format( PRINTF_FORMAT_STRING const char *pFormat, ... ); - void SetDirect( const char *pValue, int nChars ); + bool MatchesPattern( const CUtlString &Pattern, int nFlags = 0 ) const; // case SENSITIVE, use * for wildcard in pattern string + + char operator[]( int i ) const; + +#if ! defined(SWIG) + // Don't let SWIG see the PRINTF_FORMAT_STRING attribute or it will complain. + int Format( PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 2, 3 ); + int FormatV( PRINTF_FORMAT_STRING const char *pFormat, va_list marker ); +#else + int Format( const char *pFormat, ... ); + int FormatV( const char *pFormat, va_list marker ); +#endif // Defining AltArgumentType_t hints that associative container classes should // also implement Find/Insert/Remove functions that take const char* params. typedef const char *AltArgumentType_t; - // Take a piece out of the string. + // Get a copy of part of the string. // If you only specify nStart, it'll go from nStart to the end. // You can use negative numbers and it'll wrap around to the start. - CUtlString Slice( int32 nStart=0, int32 nEnd=INT_MAX ); + CUtlString Slice( int32 nStart=0, int32 nEnd=INT_MAX ) const; - // Grab a substring starting from the left or the right side. - CUtlString Left( int32 nChars ); - CUtlString Right( int32 nChars ); + // Get a substring starting from the left or the right side. + CUtlString Left( int32 nChars ) const; + CUtlString Right( int32 nChars ) const; - // Replace all instances of one character with another. - CUtlString Replace( char cFrom, char cTo ); + // Get a string with all instances of one character replaced with another. + CUtlString Replace( char cFrom, char cTo ) const; - // Calls right through to V_MakeAbsolutePath. - CUtlString AbsPath( const char *pStartingDir=NULL ); + // Replace all instances of specified string with another. + CUtlString Replace( const char *pszFrom, const char *pszTo ) const; + + // Get this string as an absolute path (calls right through to V_MakeAbsolutePath). + CUtlString AbsPath( const char *pStartingDir=NULL ) const; // Gets the filename (everything except the path.. c:\a\b\c\somefile.txt -> somefile.txt). - CUtlString UnqualifiedFilename(); - - // Strips off one directory. Uses V_StripLastDir but strips the last slash also! - CUtlString DirName(); + CUtlString UnqualifiedFilename() const; + // Gets a string with one directory removed. Uses V_StripLastDir but strips the last slash also! + CUtlString DirName() const; + + // Get a string with the extension removed (with V_StripExtension). + CUtlString StripExtension() const; + + // Get a string with the filename removed (uses V_UnqualifiedFileName and also strips the last slash) + CUtlString StripFilename() const; + + // Get a string with the base filename (with V_FileBase). + CUtlString GetBaseFilename() const; + + // Get a string with the file extension (with V_FileBase). + CUtlString GetExtension() const; + // Works like V_ComposeFileName. static CUtlString PathJoin( const char *pStr1, const char *pStr2 ); @@ -236,21 +211,93 @@ public: static int __cdecl SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 ); static int __cdecl SortCaseSensitive( const CUtlString *pString1, const CUtlString *pString2 ); + // Empty string for those times when you need to return an empty string and + // either don't want to pay the construction cost, or are returning a + // const CUtlString& and cannot just return "". + static const CUtlString &GetEmptyString(); + private: - CUtlBinaryBlock m_Storage; + // INTERNALS + // AllocMemory allocates enough space for length characters plus a terminating zero. + // Previous characters are preserved, the buffer is null-terminated, but new characters + // are not touched. + void *AllocMemory( uint32 length ); + + // If m_pString is not NULL, it points to the start of the string, and the memory allocation. + char *m_pString; }; +// // If these are not defined, CUtlConstString as rhs will auto-convert +// // to const char* and do logical operations on the raw pointers. Ugh. +// inline friend bool operator<( const T *lhs, const CUtlConstStringBase &rhs ) { return rhs.Compare( lhs ) > 0; } +// inline friend bool operator==( const T *lhs, const CUtlConstStringBase &rhs ) { return rhs.Compare( lhs ) == 0; } +// inline friend bool operator!=( const T *lhs, const CUtlConstStringBase &rhs ) { return rhs.Compare( lhs ) != 0; } + +inline bool operator==( const char *pString, const CUtlString &utlString ) +{ + return utlString.IsEqual_CaseSensitive( pString ); +} + +inline bool operator!=( const char *pString, const CUtlString &utlString ) +{ + return !utlString.IsEqual_CaseSensitive( pString ); +} + +inline bool operator==( const CUtlString &utlString, const char *pString ) +{ + return utlString.IsEqual_CaseSensitive( pString ); +} + +inline bool operator!=( const CUtlString &utlString, const char *pString ) +{ + return !utlString.IsEqual_CaseSensitive( pString ); +} + + + //----------------------------------------------------------------------------- // Inline methods //----------------------------------------------------------------------------- -inline bool CUtlString::IsEmpty() const +inline CUtlString::CUtlString() +: m_pString( NULL ) { - return Length() == 0; } -inline bool CUtlString::IsValid() const +inline CUtlString::CUtlString( const char *pString ) +: m_pString( NULL ) { - return ( String() != NULL ); + Set( pString ); +} + +inline CUtlString::CUtlString( const char *pString, int length ) +: m_pString( NULL ) +{ + SetDirect( pString, length ); +} + +inline CUtlString::CUtlString( const CUtlString& string ) +: m_pString( NULL ) +{ + Set( string.Get() ); +} + +inline CUtlString::~CUtlString() +{ + Purge(); +} + +inline int CUtlString::Length() const +{ + if (m_pString) + { + return V_strlen( m_pString ); + } + return 0; +} + +inline bool CUtlString::IsEmpty() const +{ + return !m_pString || m_pString[0] == 0; } inline int __cdecl CUtlString::SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 ) @@ -263,6 +310,14 @@ inline int __cdecl CUtlString::SortCaseSensitive( const CUtlString *pString1, co return V_strcmp( pString1->String(), pString2->String() ); } +// Converts to c-strings +inline CUtlString::operator const char*() const +{ + return Get(); +} + + + //----------------------------------------------------------------------------- // Purpose: Implementation of low-level string functionality for character types. //----------------------------------------------------------------------------- @@ -332,6 +387,7 @@ public: void Clear() { Set( NULL ); } const T *Get() const { return m_pString ? m_pString : StringFuncs::EmptyString(); } + operator const T*() const { return m_pString ? m_pString : StringFuncs::EmptyString(); } bool IsEmpty() const { return m_pString == NULL; } // Note: empty strings are never stored by Set @@ -397,5 +453,8 @@ typedef CUtlConstStringBase CUtlConstWideString; template < typename T > struct UTLConstStringCaselessStringLessFunctor { bool operator()( const CUtlConstStringBase& a, const char *b ) const { return StringFuncs::CaselessCompare( a.Get(), b ) < 0; } }; template < typename T > struct UTLConstStringCaselessStringEqualFunctor { bool operator()( const CUtlConstStringBase& a, const char *b ) const { return StringFuncs::CaselessCompare( a.Get(), b ) == 0; } }; +// Helper function for CUtlMaps with a CUtlString key +inline bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs ) { return V_strcmp( lhs.Get(), rhs.Get() ) < 0; } +inline bool UtlStringCaseInsensitiveLessFunc( const CUtlString &lhs, const CUtlString &rhs ) { return V_stricmp( lhs.Get(), rhs.Get() ) < 0; } #endif // UTLSTRING_H diff --git a/public/tier1/utlvector.h b/public/tier1/utlvector.h index 4901c367..7bbf8aa8 100644 --- a/public/tier1/utlvector.h +++ b/public/tier1/utlvector.h @@ -80,6 +80,12 @@ public: int Count() const; int Size() const; // don't use me! + /// are there no elements? For compatibility with lists. + inline bool IsEmpty( void ) const + { + return ( Count() == 0 ); + } + // Is element index valid? bool IsValidIndex( int i ) const; static int InvalidIndex(); @@ -579,6 +585,19 @@ inline CUtlVector& CUtlVector::operator=( const CUtlVector &ot return *this; } +#ifdef STAGING_ONLY +inline void StagingUtlVectorBoundsCheck( int i, int size ) +{ + if ( (unsigned)i >= (unsigned)size ) + { + Msg( "Array access error: %d / %d\n", i, size ); + DebuggerBreak(); + } +} + +#else +#define StagingUtlVectorBoundsCheck( _i, _size ) +#endif //----------------------------------------------------------------------------- // element access @@ -588,6 +607,7 @@ inline T& CUtlVector::operator[]( int i ) { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); + StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -596,6 +616,7 @@ inline const T& CUtlVector::operator[]( int i ) const { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); + StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -604,6 +625,7 @@ inline T& CUtlVector::Element( int i ) { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); + StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -612,6 +634,7 @@ inline const T& CUtlVector::Element( int i ) const { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); + StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -619,6 +642,7 @@ template< typename T, class A > inline T& CUtlVector::Head() { Assert( m_Size > 0 ); + StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ 0 ]; } @@ -626,6 +650,7 @@ template< typename T, class A > inline const T& CUtlVector::Head() const { Assert( m_Size > 0 ); + StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ 0 ]; } @@ -633,6 +658,7 @@ template< typename T, class A > inline T& CUtlVector::Tail() { Assert( m_Size > 0 ); + StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ m_Size - 1 ]; } @@ -640,6 +666,7 @@ template< typename T, class A > inline const T& CUtlVector::Tail() const { Assert( m_Size > 0 ); + StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ m_Size - 1 ]; } diff --git a/public/tier2/p4helpers.h b/public/tier2/p4helpers.h index db341b92..d023ac25 100644 --- a/public/tier2/p4helpers.h +++ b/public/tier2/p4helpers.h @@ -36,6 +36,9 @@ public: // Is the file in perforce? virtual bool IsFileInPerforce(); + // Changes the file to the specified filetype. + virtual bool SetFileType( const CUtlString& desiredFileType ); + protected: // The filename that this class instance represents CUtlString m_sFilename; @@ -53,6 +56,7 @@ public: virtual bool Edit( void ) { return true; } virtual bool Add( void ) { return true; } virtual bool IsFileInPerforce() { return false; } + virtual bool SetFileType(const CUtlString& desiredFileType) { return true; } }; @@ -122,16 +126,35 @@ protected: class CP4AutoEditAddFile { public: - explicit CP4AutoEditAddFile( char const *szFilename ) : m_spImpl( g_p4factory->AccessFile( szFilename ) ) + explicit CP4AutoEditAddFile( char const *szFilename ) + : m_spImpl( g_p4factory->AccessFile( szFilename ) ) + , m_bHasDesiredFileType( false ) { m_spImpl->Edit(); } - ~CP4AutoEditAddFile( void ) { m_spImpl->Add(); } + + explicit CP4AutoEditAddFile( char const *szFilename, const char *szFiletype ) + : m_spImpl( g_p4factory->AccessFile( szFilename ) ) + , m_sFileType(szFiletype) + , m_bHasDesiredFileType( true ) + { + m_spImpl->Edit(); + m_spImpl->SetFileType( m_sFileType ); + } + + ~CP4AutoEditAddFile( void ) + { + m_spImpl->Add(); + if ( m_bHasDesiredFileType ) + m_spImpl->SetFileType( m_sFileType ); + } CP4File * File() const { return m_spImpl.Get(); } protected: CPlainAutoPtr< CP4File > m_spImpl; + CUtlString m_sFileType; + bool m_bHasDesiredFileType; }; diff --git a/public/togl/linuxwin/cglmprogram.h b/public/togl/linuxwin/cglmprogram.h index ca32af00..5731d22d 100644 --- a/public/togl/linuxwin/cglmprogram.h +++ b/public/togl/linuxwin/cglmprogram.h @@ -202,7 +202,7 @@ public: uint nWidth = nWidthHeight & 0xFFFF, nHeight = nWidthHeight >> 16; // Apply half pixel offset to output vertices to account for the pixel center difference between D3D9 and OpenGL. // We output vertices in clip space, which ranges from [-1,1], so 1.0/width in clip space transforms into .5/width in screenspace, see: "Viewports and Clipping (Direct3D 9)" in the DXSDK - float v[4] = { 1.0f / nWidth, 1.0f / nHeight, nWidth, nHeight }; + float v[4] = { 1.0f / (float)nWidth, 1.0f / (float)nHeight, (float)nWidth, (float)nHeight }; if ( m_locVertexScreenParams >= 0 ) gGL->glUniform4fv( m_locVertexScreenParams, 1, v ); } diff --git a/public/togl/osx/glmgrbasics.h b/public/togl/osx/glmgrbasics.h index 559bc10f..ed0b5e07 100644 --- a/public/togl/osx/glmgrbasics.h +++ b/public/togl/osx/glmgrbasics.h @@ -17,7 +17,7 @@ #include #include #include -#include +//#include //#include #elif defined(LINUX) #include @@ -112,8 +112,8 @@ void GLMEndPIXEvent( void ); //=============================================================================== // knob twiddling -float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value -float GLMKnobToggle( char *knobname ); +//float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value +//float GLMKnobToggle( char *knobname ); //=============================================================================== // other stuff diff --git a/public/toolframework/itoolentity.h b/public/toolframework/itoolentity.h index 7e1199db..8aacdd8e 100644 --- a/public/toolframework/itoolentity.h +++ b/public/toolframework/itoolentity.h @@ -32,6 +32,9 @@ class CBaseAnimating; class CTakeDamageInfo; class ITempEntsSystem; class IEntityFactoryDictionary; +class CBaseTempEntity; +class CGlobalEntityList; +class IEntityFindFilter; //----------------------------------------------------------------------------- @@ -217,13 +220,35 @@ public: virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore ) = 0; virtual ITempEntsSystem *GetTempEntsSystem( void ) = 0; + virtual CBaseTempEntity *GetTempEntList( void ) = 0; + + virtual CGlobalEntityList *GetEntityList( void ) = 0; + virtual bool IsEntityPtr( void *pTest ) = 0; + virtual CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ) = 0; + virtual CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL ) = 0; + virtual CBaseEntity *FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ) = 0; + virtual CBaseEntity *FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName ) = 0; + virtual CBaseEntity *FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName ) = 0; + virtual CBaseEntity *FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; + virtual CBaseEntity *FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; + virtual CBaseEntity *FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ) = 0; + virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius ) = 0; + virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecMins, const Vector &vecMaxs ) = 0; + virtual CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; + virtual CBaseEntity *FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; + virtual CBaseEntity *FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; + virtual CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold ) = 0; + virtual CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname ) = 0; + virtual CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; }; typedef IServerTools IServerTools001; +typedef IServerTools IServerTools002; #define VSERVERTOOLS_INTERFACE_VERSION_1 "VSERVERTOOLS001" -#define VSERVERTOOLS_INTERFACE_VERSION "VSERVERTOOLS002" -#define VSERVERTOOLS_INTERFACE_VERSION_INT 2 +#define VSERVERTOOLS_INTERFACE_VERSION_2 "VSERVERTOOLS002" +#define VSERVERTOOLS_INTERFACE_VERSION "VSERVERTOOLS003" +#define VSERVERTOOLS_INTERFACE_VERSION_INT 3 //----------------------------------------------------------------------------- // Purpose: Client side tool interace (right now just handles IClientRenderables). diff --git a/public/vallocator.h b/public/vallocator.h index 598e69f6..3fa6166a 100644 --- a/public/vallocator.h +++ b/public/vallocator.h @@ -53,16 +53,16 @@ public: inline void* operator new(size_t size, void *ptr, DummyAllocatorHelper *asdf) { - asdf=asdf; // compiler warning. - size=size; + (void)asdf; // Suppress unused-variable compiler warnings. + (void)size; return ptr; } inline void operator delete(void *ptrToDelete, void *ptr, DummyAllocatorHelper *asdf) { - asdf=asdf; // compiler warning. - ptr=ptr; - ptrToDelete=ptrToDelete; + (void)asdf; // Suppress unused-variable compiler warnings. + (void)ptr; + (void)ptrToDelete; } // Use these to manually construct and destruct lists of objects. diff --git a/public/vgui/ISurface.h b/public/vgui/ISurface.h index fa2a1a39..dc8d32b6 100644 --- a/public/vgui/ISurface.h +++ b/public/vgui/ISurface.h @@ -19,7 +19,6 @@ #include "appframework/IAppSystem.h" #include "mathlib/vector2d.h" // must be before the namespace line -#include #include "IVguiMatInfo.h" @@ -384,10 +383,10 @@ public: virtual const char *GetWebkitHTMLUserAgentString() = 0; - virtual IHTMLChromeController *AccessChromeHTMLController() = 0; + virtual void *Deprecated_AccessChromeHTMLController() = 0; // the origin of the viewport on the framebuffer (Which might not be 0,0 for stereo) - virtual void SetFullscreenViewportAndRenderTarget( int x, int y, int w, int h, ITexture *pRenderTarget ) = 0; + virtual void SetFullscreenViewport( int x, int y, int w, int h ) = 0; // this uses NULL for the render target. virtual void GetFullscreenViewport( int & x, int & y, int & w, int & h ) = 0; virtual void PushFullscreenViewport() = 0; virtual void PopFullscreenViewport() = 0; diff --git a/public/vgui/IVGui.h b/public/vgui/IVGui.h index e512538a..b680f802 100644 --- a/public/vgui/IVGui.h +++ b/public/vgui/IVGui.h @@ -99,6 +99,9 @@ public: // enables VR mode virtual void SetVRMode( bool bVRMode ) = 0; virtual bool GetVRMode() = 0; + + // add a tick signal like above, but to the head of the list of tick signals + virtual void AddTickSignalToHead( VPANEL panel, int intervalMilliseconds = 0 ) = 0; }; #define VGUI_IVGUI_INTERFACE_VERSION "VGUI_ivgui008" diff --git a/public/vgui_controls/HTML.h b/public/vgui_controls/HTML.h index 3eed7694..e53893f7 100644 --- a/public/vgui_controls/HTML.h +++ b/public/vgui_controls/HTML.h @@ -18,8 +18,11 @@ #include #include #include -#include #include +#ifndef VERSION_SAFE_STEAM_API_INTERFACES +#define VERSION_SAFE_STEAM_API_INTERFACES +#endif +#include "steam/steam_api.h" class HTMLComboBoxHost; namespace vgui @@ -31,7 +34,7 @@ namespace vgui // It can load any valid URL (i.e local files or web pages), you cannot dynamically change the // content however (internally to the control that is). //----------------------------------------------------------------------------- -class HTML: public Panel, public IHTMLResponses +class HTML: public Panel { DECLARE_CLASS_SIMPLE( HTML, Panel ); // TODO::STYLE @@ -145,60 +148,53 @@ public: #endif // DBGFLAG_VALIDATE void PaintComboBox(); - int BrowserGetIndex() { return m_iBrowser; } + ISteamHTMLSurface *SteamHTMLSurface() { return m_SteamAPIContext.SteamHTMLSurface(); } + + void OnHTMLMouseMoved( int x, int y ) + { + if ( m_SteamAPIContext.SteamHTMLSurface() ) + m_SteamAPIContext.SteamHTMLSurface()->MouseMove( m_unBrowserHandle, x, y ); + } + protected: virtual void ApplySchemeSettings( IScheme *pScheme ); friend class HTMLComboBoxHost; vgui::Menu *m_pContextMenu; -private: - // IHTMLResponses callbacks from the browser engine - virtual void BrowserSetIndex( int idx ) { m_iBrowser = idx; BrowserResize(); SendPendingHTMLMessages(); } - virtual void BrowserReady( const CMsgBrowserReady *pCmd ); - virtual void BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ); - virtual void BrowserStartRequest( const CMsgStartRequest *pCmd ); - virtual void BrowserURLChanged( const CMsgURLChanged *pCmd ); - virtual void BrowserFinishedRequest( const CMsgFinishedRequest *pCmd ); - virtual void BrowserShowPopup( const CMsgShowPopup *pCmd ); - virtual void BrowserHidePopup( const CMsgHidePopup *pCmd ); - virtual void BrowserOpenNewTab( const CMsgOpenNewTab *pCmd ); - virtual void BrowserPopupHTMLWindow( const CMsgPopupHTMLWindow *pCmd ); - virtual void BrowserSetHTMLTitle( const CMsgSetHTMLTitle *pCmd ); - virtual void BrowserLoadingResource( const CMsgLoadingResource *pCmd ); - virtual void BrowserStatusText( const CMsgStatusText *pCmd ); - virtual void BrowserSetCursor( const CMsgSetCursor *pCmd ); - virtual void BrowserFileLoadDialog( const CMsgFileLoadDialog *pCmd ); - virtual void BrowserShowToolTip( const CMsgShowToolTip *pCmd ); - virtual void BrowserUpdateToolTip( const CMsgUpdateToolTip *pCmd ); - virtual void BrowserHideToolTip( const CMsgHideToolTip *pCmd ); - virtual void BrowserSearchResults( const CMsgSearchResults *pCmd ); - virtual void BrowserClose( const CMsgClose *pCmd ); - virtual void BrowserHorizontalScrollBarSizeResponse( const CMsgHorizontalScrollBarSizeResponse *pCmd ); - virtual void BrowserVerticalScrollBarSizeResponse( const CMsgVerticalScrollBarSizeResponse *pCmd ); - virtual void BrowserGetZoomResponse( const CMsgGetZoomResponse *pCmd ); - virtual void BrowserLinkAtPositionResponse( const CMsgLinkAtPositionResponse *pCmd ); - virtual void BrowserZoomToElementAtPositionResponse( const CMsgZoomToElementAtPositionResponse *pCmd ); - virtual void BrowserJSAlert( const CMsgJSAlert *pCmd ); - virtual void BrowserJSConfirm( const CMsgJSConfirm *pCmd ); - virtual void BrowserCanGoBackandForward( const CMsgCanGoBackAndForward *pCmd ); - virtual void BrowserOpenSteamURL( const CMsgOpenSteamURL *pCmd ); - virtual void BrowserSizePopup( const CMsgSizePopup *pCmd ); - void SendPendingHTMLMessages(); - /*virtual void BrowserResourceResponse( const CMsgResourceResponse *pCmd );*/ - virtual void BrowserScalePageToValueResponse( const CMsgScalePageToValueResponse *pCmd ){} - virtual void BrowserRequestFullScreen( const CMsgRequestFullScreen *pCmd ) {} - virtual void BrowserExitFullScreen( const CMsgExitFullScreen *pCmd ) {} - virtual void BrowserGetCookiesForURLResponse( const CMsgGetCookiesForURLResponse *pCmd ){} - virtual void BrowserNodeGotFocus( const CMsgNodeHasFocus *pCmd ){} - virtual void BrowserSavePageToJPEGResponse( const CMsgSavePageToJPEGResponse *pCmd ) {} - virtual void BrowserFocusedNodeValueResponse( const CMsgFocusedNodeTextResponse *pCmd ) {} - virtual void _DeserializeAndDispatch( HTMLCommandBuffer_t *pCmd ); +private: + STEAM_CALLBACK( HTML, BrowserNeedsPaint, HTML_NeedsPaint_t, m_NeedsPaint ); + STEAM_CALLBACK( HTML, BrowserComboNeedsPaint, HTML_ComboNeedsPaint_t, m_ComboNeedsPaint ); + STEAM_CALLBACK( HTML, BrowserStartRequest, HTML_StartRequest_t, m_StartRequest ); + STEAM_CALLBACK( HTML, BrowserURLChanged, HTML_URLChanged_t, m_URLChanged ); + STEAM_CALLBACK( HTML, BrowserFinishedRequest, HTML_FinishedRequest_t, m_FinishedRequest ); + STEAM_CALLBACK( HTML, BrowserShowPopup, HTML_ShowPopup_t, m_ShowPopup ); + STEAM_CALLBACK( HTML, BrowserHidePopup, HTML_HidePopup_t, m_HidePopup ); + STEAM_CALLBACK( HTML, BrowserSizePopup, HTML_SizePopup_t, m_SizePopup ); + + STEAM_CALLBACK( HTML, BrowserOpenNewTab, HTML_OpenLinkInNewTab_t, m_LinkInNewTab ); + STEAM_CALLBACK( HTML, BrowserSetHTMLTitle, HTML_ChangedTitle_t, m_ChangeTitle ); + STEAM_CALLBACK( HTML, BrowserPopupHTMLWindow, HTML_NewWindow_t, m_NewWindow ); + STEAM_CALLBACK( HTML, BrowserFileLoadDialog, HTML_FileOpenDialog_t, m_FileLoadDialog ); + STEAM_CALLBACK( HTML, BrowserSearchResults, HTML_SearchResults_t, m_SearchResults ); + STEAM_CALLBACK( HTML, BrowserClose, HTML_CloseBrowser_t, m_CloseBrowser ); + STEAM_CALLBACK( HTML, BrowserHorizontalScrollBarSizeResponse, HTML_HorizontalScroll_t, m_HorizScroll ); + STEAM_CALLBACK( HTML, BrowserVerticalScrollBarSizeResponse, HTML_VerticalScroll_t, m_VertScroll ); + STEAM_CALLBACK( HTML, BrowserLinkAtPositionResponse, HTML_LinkAtPosition_t, m_LinkAtPosResp ); + STEAM_CALLBACK( HTML, BrowserJSAlert, HTML_JSAlert_t, m_JSAlert ); + STEAM_CALLBACK( HTML, BrowserJSConfirm, HTML_JSConfirm_t, m_JSConfirm ); + STEAM_CALLBACK( HTML, BrowserCanGoBackandForward, HTML_CanGoBackAndForward_t, m_CanGoBackForward ); + STEAM_CALLBACK( HTML, BrowserSetCursor, HTML_SetCursor_t, m_SetCursor ); + STEAM_CALLBACK( HTML, BrowserStatusText, HTML_StatusText_t, m_StatusText ); + STEAM_CALLBACK( HTML, BrowserShowToolTip, HTML_ShowToolTip_t, m_ShowTooltip ); + STEAM_CALLBACK( HTML, BrowserUpdateToolTip, HTML_UpdateToolTip_t, m_UpdateTooltip ); + STEAM_CALLBACK( HTML, BrowserHideToolTip, HTML_HideToolTip_t, m_HideTooltip ); + + void OnBrowserReady( HTML_BrowserReady_t *pBrowserReady, bool bIOFailure ); void PostURL(const char *URL, const char *pchPostData, bool force); virtual void BrowserResize(); - virtual void CalcScrollBars(int w,int h); void UpdateSizeAndScrollBars(); MESSAGE_FUNC( OnSliderMoved, "ScrollBarSliderMoved" ); MESSAGE_FUNC_CHARPTR( OnFileSelected, "FileSelected", fullpath ); @@ -207,8 +203,6 @@ private: MESSAGE_FUNC_PTR( OnEditNewLine, "TextNewLine", panel ); MESSAGE_FUNC_INT( DismissJSDialog, "DismissJSDialog", result ); - void UpdateCachedHTMLValues(); - vgui::Panel *m_pInteriorPanel; vgui::ScrollBar *_hbar,*_vbar; vgui::DHANDLE m_hFileOpenDialog; @@ -256,7 +250,6 @@ private: }; CUtlVector m_CustomURLHandlers; - int m_iBrowser; // our browser handle int m_iHTMLTextureID; // vgui texture id // Track the texture width and height requested so we can tell // when the size has changed and reallocate the texture. @@ -290,16 +283,12 @@ private: ScrollData_t() { m_bVisible = false; - m_nX = m_nY = m_nWide = m_nTall = m_nMax = m_nScroll = 0; + m_nMax = m_nScroll = 0; } bool operator==( ScrollData_t const &src ) const { return m_bVisible == src.m_bVisible && - m_nX == src.m_nX && - m_nY == src.m_nY && - m_nWide == src.m_nWide && - m_nTall == src.m_nTall && m_nMax == src.m_nMax && m_nScroll == src.m_nScroll; } @@ -311,10 +300,6 @@ private: bool m_bVisible; // is the scroll bar visible - int m_nX; /// where cef put the scroll bar - int m_nY; - int m_nWide; - int m_nTall; // how many pixels of scroll in the current scroll knob int m_nMax; // most amount of pixels we can scroll int m_nScroll; // currently scrolled amount of pixels float m_flZoom; // zoom level this scroll bar is for @@ -340,7 +325,10 @@ private: } }; CUtlVector m_vecHCursor; - CUtlVector m_vecPendingMessages; + + CSteamAPIContext m_SteamAPIContext; + HHTMLBrowser m_unBrowserHandle; + CCallResult< HTML, HTML_BrowserReady_t > m_SteamCallResultBrowserReady; }; } // namespace vgui diff --git a/public/vgui_controls/ImagePanel.h b/public/vgui_controls/ImagePanel.h index 9540d5bc..05d250aa 100644 --- a/public/vgui_controls/ImagePanel.h +++ b/public/vgui_controls/ImagePanel.h @@ -75,6 +75,7 @@ private: char *m_pszImageName; char *m_pszFillColorName; char *m_pszDrawColorName; + bool m_bPositionImage; bool m_bCenterImage; bool m_bScaleImage; bool m_bTileImage; diff --git a/public/vgui_controls/Panel.h b/public/vgui_controls/Panel.h index 23af650c..1a89f19a 100644 --- a/public/vgui_controls/Panel.h +++ b/public/vgui_controls/Panel.h @@ -624,6 +624,8 @@ public: void SetParentNeedsCursorMoveEvents( bool bNeedsEvents ) { m_bParentNeedsCursorMoveEvents = bNeedsEvents; } bool ParentNeedsCursorMoveEvents() const { return m_bParentNeedsCursorMoveEvents; } + int ComputePos( const char *pszInput, int &nPos, const int& nSize, const int& nParentSize, const bool& bX ); + // For 360: support directional navigation between UI controls via dpad enum NAV_DIRECTION { ND_UP, ND_DOWN, ND_LEFT, ND_RIGHT, ND_BACK, ND_NONE }; virtual Panel* NavigateUp(); @@ -725,15 +727,23 @@ protected: private: enum BuildModeFlags_t { - BUILDMODE_EDITABLE = 0x01, - BUILDMODE_DELETABLE = 0x02, - BUILDMODE_SAVE_XPOS_RIGHTALIGNED = 0x04, - BUILDMODE_SAVE_XPOS_CENTERALIGNED = 0x08, - BUILDMODE_SAVE_YPOS_BOTTOMALIGNED = 0x10, - BUILDMODE_SAVE_YPOS_CENTERALIGNED = 0x20, - BUILDMODE_SAVE_WIDE_FULL = 0x40, - BUILDMODE_SAVE_TALL_FULL = 0x80, - BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT = 0x100, + BUILDMODE_EDITABLE = 1 << 0, + BUILDMODE_DELETABLE = 1 << 1, + BUILDMODE_SAVE_XPOS_RIGHTALIGNED = 1 << 2, + BUILDMODE_SAVE_XPOS_CENTERALIGNED = 1 << 3, + BUILDMODE_SAVE_YPOS_BOTTOMALIGNED = 1 << 4, + BUILDMODE_SAVE_YPOS_CENTERALIGNED = 1 << 5, + BUILDMODE_SAVE_WIDE_FULL = 1 << 6, + BUILDMODE_SAVE_TALL_FULL = 1 << 7, + BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT = 1 << 8, + BUILDMODE_SAVE_WIDE_PROPORTIONAL = 1 << 9, + BUILDMODE_SAVE_TALL_PROPORTIONAL = 1 << 10, + BUILDMODE_SAVE_XPOS_PROPORTIONAL_SELF = 1 << 11, + BUILDMODE_SAVE_YPOS_PROPORTIONAL_SELF = 1 << 12, + BUILDMODE_SAVE_WIDE_PROPORTIONAL_TALL = 1 << 13, + BUILDMODE_SAVE_TALL_PROPORTIONAL_WIDE = 1 << 14, + BUILDMODE_SAVE_XPOS_PROPORTIONAL_PARENT = 1 << 15, + BUILDMODE_SAVE_YPOS_PROPORTIONAL_PARENT = 1 << 16 }; enum PanelFlags_t @@ -759,6 +769,9 @@ private: ALL_FLAGS = 0xFFFF, }; + int ComputeWide( KeyValues *inResourceData, int nParentWide, int nParentTall, bool bComputingForTall ); + int ComputeTall( KeyValues *inResourceData, int nParentWide, int nParentTall, bool bComputingForWide ); + // used to get the Panel * for users with only IClientPanel virtual Panel *GetPanel() { return this; } diff --git a/public/vgui_controls/PanelListPanel.h b/public/vgui_controls/PanelListPanel.h index 392feb3d..1c1d92bf 100644 --- a/public/vgui_controls/PanelListPanel.h +++ b/public/vgui_controls/PanelListPanel.h @@ -24,8 +24,8 @@ namespace vgui //----------------------------------------------------------------------------- // Purpose: A list of variable height child panels -// each list item consists of a label-panel pair. Height of the item is -// determined from the lable. +// each list item consists of a label-panel pair. Height of the item is +// determined from the label. //----------------------------------------------------------------------------- class PanelListPanel : public EditablePanel { @@ -83,6 +83,8 @@ public: return &m_SortedItems; } + int ComputeVPixelsNeeded(); + protected: // overrides virtual void OnSizeChanged(int wide, int tall); @@ -92,7 +94,7 @@ protected: virtual void OnMouseWheeled(int delta); private: - int ComputeVPixelsNeeded(); + enum { DEFAULT_HEIGHT = 24, PANELBUFFER = 5 }; diff --git a/public/zip_utils.cpp b/public/zip_utils.cpp index 964edcb7..de9f9d3a 100644 --- a/public/zip_utils.cpp +++ b/public/zip_utils.cpp @@ -615,7 +615,9 @@ void CZipFile::ParseFromBuffer( void *buffer, int bufferlength ) ZIP_EndOfCentralDirRecord rec = { 0 }; +#ifdef DBGFLAG_ASSERT bool bFoundEndOfCentralDirRecord = false; +#endif unsigned int offset = fileLen - sizeof( ZIP_EndOfCentralDirRecord ); // If offset is ever greater than startOffset then it means that it has // wrapped. This used to be a tautological >= 0 test. @@ -626,7 +628,9 @@ void CZipFile::ParseFromBuffer( void *buffer, int bufferlength ) buf.GetObjects( &rec ); if ( rec.signature == PKID( 5, 6 ) ) { +#ifdef DBGFLAG_ASSERT bFoundEndOfCentralDirRecord = true; +#endif // Set any xzip configuration if ( rec.commentLength ) diff --git a/raytrace/trace2.cpp b/raytrace/trace2.cpp index f7f4ed7e..c70747e6 100644 --- a/raytrace/trace2.cpp +++ b/raytrace/trace2.cpp @@ -186,7 +186,7 @@ void RayTracingEnvironment::RenderScene( AndNotSIMD(no_hit_mask,intens.x)); intens.y=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask), AndNotSIMD(no_hit_mask,intens.y)); - intens.z=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask), + intens.z=OrSIMD(AndSIMD(BackgroundColor.z,no_hit_mask), AndNotSIMD(no_hit_mask,intens.z)); MapLinearIntensities(intens,dest,dest+1,dest+stride,dest+stride+1); diff --git a/tier1/KeyValues.cpp b/tier1/KeyValues.cpp index 7163f8fb..96c80b5e 100644 --- a/tier1/KeyValues.cpp +++ b/tier1/KeyValues.cpp @@ -729,7 +729,7 @@ void KeyValues::WriteConvertedString( IBaseFileSystem *filesystem, FileHandle_t j++; } - INTERNALWRITE(convertedString, strlen(convertedString)); + INTERNALWRITE(convertedString, Q_strlen(convertedString)); } @@ -1352,8 +1352,11 @@ const char *KeyValues::GetString( const char *keyName, const char *defaultValue Q_snprintf( buf, sizeof( buf ), "%f", dat->m_flValue ); SetString( keyName, buf ); break; - case TYPE_INT: case TYPE_PTR: + Q_snprintf( buf, sizeof( buf ), "%lld", (int64)(size_t)dat->m_pValue ); + SetString( keyName, buf ); + break; + case TYPE_INT: Q_snprintf( buf, sizeof( buf ), "%d", dat->m_iValue ); SetString( keyName, buf ); break; @@ -1402,8 +1405,11 @@ const wchar_t *KeyValues::GetWString( const char *keyName, const wchar_t *defaul swprintf(wbuf, Q_ARRAYSIZE(wbuf), L"%f", dat->m_flValue); SetWString( keyName, wbuf); break; - case TYPE_INT: case TYPE_PTR: + swprintf( wbuf, Q_ARRAYSIZE(wbuf), L"%lld", (int64)(size_t)dat->m_pValue ); + SetWString( keyName, wbuf ); + break; + case TYPE_INT: swprintf( wbuf, Q_ARRAYSIZE(wbuf), L"%d", dat->m_iValue ); SetWString( keyName, wbuf ); break; @@ -1445,10 +1451,17 @@ const wchar_t *KeyValues::GetWString( const char *keyName, const wchar_t *defaul //----------------------------------------------------------------------------- // Purpose: Get a bool interpretation of the key. //----------------------------------------------------------------------------- -bool KeyValues::GetBool( const char *keyName, bool defaultValue ) +bool KeyValues::GetBool( const char *keyName, bool defaultValue, bool* optGotDefault ) { if ( FindKey( keyName ) ) + { + if ( optGotDefault ) + (*optGotDefault) = false; return 0 != GetInt( keyName, 0 ); + } + + if ( optGotDefault ) + (*optGotDefault) = true; return defaultValue; } @@ -1586,7 +1599,7 @@ void KeyValues::SetWString( const char *keyName, const wchar_t *value ) } // allocate memory for the new value and copy it in - int len = wcslen( value ); + int len = Q_wcslen( value ); dat->m_wsValue = new wchar_t[len + 1]; Q_memcpy( dat->m_wsValue, value, (len+1) * sizeof(wchar_t) ); @@ -1832,7 +1845,7 @@ KeyValues *KeyValues::MakeCopy( void ) const { if ( m_wsValue ) { - int len = wcslen( m_wsValue ); + int len = Q_wcslen( m_wsValue ); newKeyValue->m_wsValue = new wchar_t[len+1]; Q_memcpy( newKeyValue->m_wsValue, m_wsValue, (len+1)*sizeof(wchar_t)); } @@ -1956,9 +1969,8 @@ void KeyValues::ParseIncludedKeys( char const *resourceName, const char *filetoi Q_strncpy( fullpath, resourceName, sizeof( fullpath ) ); // Strip off characters back to start or first / - bool done = false; int len = Q_strlen( fullpath ); - while ( !done ) + for (;;) { if ( len <= 0 ) { @@ -2652,13 +2664,13 @@ bool KeyValues::ReadAsBinary( CUtlBuffer &buffer, int nStackDepth ) void *KeyValues::operator new( size_t iAllocSize ) { MEM_ALLOC_CREDIT(); - return KeyValuesSystem()->AllocKeyValuesMemory(iAllocSize); + return KeyValuesSystem()->AllocKeyValuesMemory( (int)iAllocSize ); } void *KeyValues::operator new( size_t iAllocSize, int nBlockUse, const char *pFileName, int nLine ) { MemAlloc_PushAllocDbgInfo( pFileName, nLine ); - void *p = KeyValuesSystem()->AllocKeyValuesMemory(iAllocSize); + void *p = KeyValuesSystem()->AllocKeyValuesMemory( (int)iAllocSize ); MemAlloc_PopAllocDbgInfo(); return p; } diff --git a/tier1/bitbuf.cpp b/tier1/bitbuf.cpp index 5a37d24f..4c457aa4 100644 --- a/tier1/bitbuf.cpp +++ b/tier1/bitbuf.cpp @@ -849,7 +849,7 @@ void bf_read::SetDebugName( const char *pName ) m_pDebugName = pName; } -void bf_read::SetOverflowFlag() RESTRICT +void bf_read::SetOverflowFlag() { if ( m_bAssertOnOverflow ) { diff --git a/tier1/characterset.cpp b/tier1/characterset.cpp index a9a5ac94..2481a348 100644 --- a/tier1/characterset.cpp +++ b/tier1/characterset.cpp @@ -34,7 +34,7 @@ void CharacterSetBuild( characterset_t *pSetBuffer, const char *pszSetString ) while ( pszSetString[i] ) { - pSetBuffer->set[ pszSetString[i] ] = 1; + pSetBuffer->set[ (unsigned)pszSetString[i] ] = 1; i++; } diff --git a/tier1/convar.cpp b/tier1/convar.cpp index a0648e5a..cce9462d 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -116,7 +116,7 @@ ConCommandBase::ConCommandBase( void ) //----------------------------------------------------------------------------- ConCommandBase::ConCommandBase( const char *pName, const char *pHelpString /*=0*/, int flags /*= 0*/ ) { - Create( pName, pHelpString, flags ); + CreateBase( pName, pHelpString, flags ); } //----------------------------------------------------------------------------- @@ -153,16 +153,14 @@ CVarDLLIdentifier_t ConCommandBase::GetDLLIdentifier() const // *pHelpString - // flags - //----------------------------------------------------------------------------- -void ConCommandBase::Create( const char *pName, const char *pHelpString /*= 0*/, int flags /*= 0*/ ) +void ConCommandBase::CreateBase( const char *pName, const char *pHelpString /*= 0*/, int flags /*= 0*/ ) { - static char *empty_string = ""; - m_bRegistered = false; // Name should be static data Assert( pName ); m_pszName = pName; - m_pszHelpString = pHelpString ? pHelpString : empty_string; + m_pszHelpString = pHelpString ? pHelpString : ""; m_nFlags = flags; @@ -269,7 +267,7 @@ char *ConCommandBase::CopyString( const char *from ) int len; char *to; - len = strlen( from ); + len = V_strlen( from ); if ( len <= 0 ) { to = new char[1]; @@ -507,7 +505,7 @@ int DefaultCompletionFunc( const char *partial, char commands[ COMMAND_COMPLETIO // m_bIsNewConCommand = true; //} -ConCommand::ConCommand( const char *pName, FnCommandCallbackV1_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) +ConCommand::ConCommand( const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) { // Set the callback m_fnCommandCallbackV1 = callback; @@ -517,7 +515,7 @@ ConCommand::ConCommand( const char *pName, FnCommandCallbackV1_t callback, const m_bHasCompletionCallback = completionFunc != 0 ? true : false; // Setup the rest - BaseClass::Create( pName, pHelpString, flags ); + BaseClass::CreateBase( pName, pHelpString, flags ); } ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) @@ -530,7 +528,7 @@ ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const c m_bUsingCommandCallbackInterface = false; // Setup the rest - BaseClass::Create( pName, pHelpString, flags ); + BaseClass::CreateBase( pName, pHelpString, flags ); } ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ ) @@ -543,7 +541,7 @@ ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const ch m_bUsingCommandCallbackInterface = true; // Setup the rest - BaseClass::Create( pName, pHelpString, flags ); + BaseClass::CreateBase( pName, pHelpString, flags ); } //----------------------------------------------------------------------------- @@ -951,7 +949,7 @@ void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*= // Name should be static data SetDefault( pDefaultValue ); - m_StringLength = strlen( m_pszDefaultValue ) + 1; + m_StringLength = V_strlen( m_pszDefaultValue ) + 1; m_pszString = new char[m_StringLength]; memcpy( m_pszString, m_pszDefaultValue, m_StringLength ); @@ -963,6 +961,7 @@ void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*= m_fnChangeCallback = callback; m_fValue = ( float )atof( m_pszString ); + m_nValue = atoi( m_pszString ); // dont convert from float to int and lose bits // Bounds Check, should never happen, if it does, no big deal if ( m_bHasMin && ( m_fValue < m_fMinVal ) ) @@ -975,9 +974,7 @@ void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*= Assert( 0 ); } - m_nValue = ( int )m_fValue; - - BaseClass::Create( pName, pHelpString, flags ); + BaseClass::CreateBase( pName, pHelpString, flags ); } //----------------------------------------------------------------------------- @@ -1052,8 +1049,7 @@ const char *ConVar::GetDefault( void ) const void ConVar::SetDefault( const char *pszDefault ) { - static char *empty_string = ""; - m_pszDefaultValue = pszDefault ? pszDefault : empty_string; + m_pszDefaultValue = pszDefault ? pszDefault : ""; Assert( m_pszDefaultValue ); } diff --git a/tier1/generichash.cpp b/tier1/generichash.cpp index 4e46c271..c70ed95d 100644 --- a/tier1/generichash.cpp +++ b/tier1/generichash.cpp @@ -142,12 +142,12 @@ unsigned FASTCALL HashStringCaselessConventional( const char *pszKey ) //----------------------------------------------------------------------------- unsigned FASTCALL HashInt( const int n ) { - register unsigned even, odd; + unsigned even, odd; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; + odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -159,16 +159,16 @@ unsigned FASTCALL HashInt( const int n ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash4( const void *pKey ) { - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; + const uint32 * p = (const uint32 *) pKey; + unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; + odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -181,16 +181,16 @@ unsigned FASTCALL Hash4( const void *pKey ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash8( const void *pKey ) { - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; + const uint32 * p = (const uint32 *) pKey; + unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; + odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -209,16 +209,16 @@ unsigned FASTCALL Hash8( const void *pKey ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash12( const void *pKey ) { - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; + const uint32 * p = (const uint32 *) pKey; + unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; + odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -243,16 +243,16 @@ unsigned FASTCALL Hash12( const void *pKey ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash16( const void *pKey ) { - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; + const uint32 * p = (const uint32 *) pKey; + unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; + odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -364,7 +364,7 @@ uint32 MurmurHash2( const void * key, int len, uint32 seed ) #define TOLOWERU( c ) ( ( uint32 ) ( ( ( c >= 'A' ) && ( c <= 'Z' ) )? c + 32 : c ) ) uint32 MurmurHash2LowerCase( char const *pString, uint32 nSeed ) { - int nLen = strlen( pString ); + int nLen = ( int )strlen( pString ); char *p = ( char * ) stackalloc( nLen + 1 ); for( int i = 0; i < nLen ; i++ ) { diff --git a/tier1/ilocalize.cpp b/tier1/ilocalize.cpp index 9e63253b..4f2d00ad 100644 --- a/tier1/ilocalize.cpp +++ b/tier1/ilocalize.cpp @@ -114,7 +114,7 @@ void ConstructStringVArgsInternal_Impl(T *unicodeOutput, int unicodeBufferSizeIn } else { - AssertMsg( argindex < numFormatParameters, "ConstructStringVArgsInternal_Impl() - Found a %s# escape sequence whose index was more than the number of args." ); + AssertMsg( argindex < numFormatParameters, "ConstructStringVArgsInternal_Impl() - Found a %%s# escape sequence whose index was more than the number of args." ); //copy it over, char by char *outputPos = *searchPos; diff --git a/tier1/interface.cpp b/tier1/interface.cpp index 2e956510..c791260c 100644 --- a/tier1/interface.cpp +++ b/tier1/interface.cpp @@ -143,6 +143,7 @@ static void *Sys_GetProcAddress( const char *pModuleName, const char *pName ) #endif } +#if !defined(LINUX) static void *Sys_GetProcAddress( HMODULE hModule, const char *pName ) { #ifdef WIN32 @@ -151,6 +152,7 @@ static void *Sys_GetProcAddress( HMODULE hModule, const char *pName ) return (void *)dlsym( (void *)hModule, pName ); #endif } +#endif bool Sys_IsDebuggerPresent() { @@ -540,3 +542,26 @@ void CDllDemandLoader::Unload() m_hModule = 0; } } + +#if defined( STAGING_ONLY ) && defined( _WIN32 ) + +typedef USHORT( WINAPI RtlCaptureStackBackTrace_FUNC )( + ULONG frames_to_skip, + ULONG frames_to_capture, + PVOID *backtrace, + PULONG backtrace_hash ); + +extern "C" int backtrace( void **buffer, int size ) +{ + HMODULE hNTDll = GetModuleHandleA( "ntdll.dll" ); + static RtlCaptureStackBackTrace_FUNC * const pfnRtlCaptureStackBackTrace = + ( RtlCaptureStackBackTrace_FUNC * )GetProcAddress( hNTDll, "RtlCaptureStackBackTrace" ); + + if ( !pfnRtlCaptureStackBackTrace ) + return 0; + + return (int)pfnRtlCaptureStackBackTrace( 2, size, buffer, 0 ); +} + +#endif // STAGING_ONLY && _WIN32 + diff --git a/tier1/mempool.cpp b/tier1/mempool.cpp index c6985a0d..1a3b2a2b 100644 --- a/tier1/mempool.cpp +++ b/tier1/mempool.cpp @@ -32,7 +32,7 @@ void CUtlMemoryPool::SetErrorReportFunc( MemoryPoolReportFunc_t func ) CUtlMemoryPool::CUtlMemoryPool( int blockSize, int numElements, int growMode, const char *pszAllocOwner, int nAlignment ) { #ifdef _X360 - if( numElements > 0 && growMode != GROW_NONE ) + if( numElements > 0 && growMode != UTLMEMORYPOOL_GROW_NONE ) { numElements = 1; } @@ -157,18 +157,18 @@ void CUtlMemoryPool::AddNewBlob() int sizeMultiplier; - if( m_GrowMode == GROW_SLOW ) + if( m_GrowMode == UTLMEMORYPOOL_GROW_SLOW ) { sizeMultiplier = 1; } else { - if ( m_GrowMode == GROW_NONE ) + if ( m_GrowMode == UTLMEMORYPOOL_GROW_NONE ) { // Can only have one allocation when we're in this mode if( m_NumBlobs != 0 ) { - Assert( !"CUtlMemoryPool::AddNewBlob: mode == GROW_NONE" ); + Assert( !"CUtlMemoryPool::AddNewBlob: mode == UTLMEMORYPOOL_GROW_NONE" ); return; } } @@ -231,10 +231,10 @@ void *CUtlMemoryPool::Alloc( size_t amount ) if( !m_pHeadOfFreeList ) { - // returning NULL is fine in GROW_NONE - if( m_GrowMode == GROW_NONE ) + // returning NULL is fine in UTLMEMORYPOOL_GROW_NONE + if( m_GrowMode == UTLMEMORYPOOL_GROW_NONE ) { - //Assert( !"CUtlMemoryPool::Alloc: tried to make new blob with GROW_NONE" ); + //Assert( !"CUtlMemoryPool::Alloc: tried to make new blob with UTLMEMORYPOOL_GROW_NONE" ); return NULL; } diff --git a/tier1/pathmatch.cpp b/tier1/pathmatch.cpp index af07d70f..81a4b420 100644 --- a/tier1/pathmatch.cpp +++ b/tier1/pathmatch.cpp @@ -316,6 +316,7 @@ inline __attribute__ ((always_inline)) static int utf8casecmp_loop(const uint32_ } } +#ifdef UTF8_PATHMATCH static int utf8casecmp(const char *str1, const char *str2) { uint32_t *folded1 = fold_utf8(str1); @@ -325,6 +326,7 @@ static int utf8casecmp(const char *str1, const char *str2) delete[] folded2; return retval; } +#endif // Simple object to help make sure a DIR* from opendir // gets closed when it goes out of scope. diff --git a/tier1/snappy-internal.h b/tier1/snappy-internal.h index 9166547a..7c8f9d17 100644 --- a/tier1/snappy-internal.h +++ b/tier1/snappy-internal.h @@ -50,7 +50,7 @@ class WorkingMemory { uint16 small_table_[1<<10]; // 2KB uint16* large_table_; // Allocated only when needed - SNAPPY_DISALLOW_COPY_AND_ASSIGN(WorkingMemory); + DISALLOW_COPY_AND_ASSIGN(WorkingMemory); }; // Flat array compression that does not emit the "uncompressed length" @@ -85,7 +85,7 @@ char* CompressFragment(const char* input, static inline int FindMatchLength(const char* s1, const char* s2, const char* s2_limit) { - DCHECK_GE(s2_limit, s2); + assert(s2_limit >= s2); int matched = 0; // Find out how long the match is. We loop over the data 64 bits at a @@ -122,7 +122,7 @@ static inline int FindMatchLength(const char* s1, const char* s2, const char* s2_limit) { // Implementation based on the x86-64 version, above. - DCHECK_GE(s2_limit, s2); + assert(s2_limit >= s2); int matched = 0; while (s2 <= s2_limit - 4 && diff --git a/tier1/snappy-sinksource.cpp b/tier1/snappy-sinksource.cpp index 1267f390..06965164 100644 --- a/tier1/snappy-sinksource.cpp +++ b/tier1/snappy-sinksource.cpp @@ -36,7 +36,8 @@ Source::~Source() { } Sink::~Sink() { } -char* Sink::GetAppendBuffer(size_t, char* scratch) { +char* Sink::GetAppendBuffer(size_t length, char* scratch) { + (void)length; return scratch; } @@ -64,9 +65,10 @@ void UncheckedByteArraySink::Append(const char* data, size_t n) { dest_ += n; } -char* UncheckedByteArraySink::GetAppendBuffer(size_t, char*) { +char* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) { + (void)scratch; + (void)len; return dest_; } - } diff --git a/tier1/snappy-stubs-internal.h b/tier1/snappy-stubs-internal.h index 98f3219e..f78d2f39 100644 --- a/tier1/snappy-stubs-internal.h +++ b/tier1/snappy-stubs-internal.h @@ -37,18 +37,18 @@ #include "tier0/platform.h" -// don't use iostream, this make us fail to run under OS X 10.5 -//#include #include #include #include #include -#ifdef HAVE_SYS_MMAN +#ifdef HAVE_SYS_MMAN_H #include #endif +#include "snappy-stubs-public.h" + #if defined(__x86_64__) // Enable 64-bit optimized versions of some routines. @@ -65,13 +65,13 @@ // header file is never used from any public header files. using namespace std; -// We only define ARRAYSIZE if it isn't already defined, because this definition -// is not very good. -#ifndef ARRAYSIZE // The size of an array, if known at compile-time. // Will give unexpected results if used on a pointer. -#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) +// We undefine it first, since some compilers already have a definition. +#ifdef ARRAYSIZE +#undef ARRAYSIZE #endif +#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) // Static prediction hints. #ifdef HAVE_BUILTIN_EXPECT @@ -87,117 +87,19 @@ using namespace std; // version (anyone who wants to regenerate it can just do the call // themselves within main()). #define DEFINE_bool(flag_name, default_value, description) \ - bool FLAGS_ ## flag_name = default_value; + bool FLAGS_ ## flag_name = default_value #define DECLARE_bool(flag_name) \ - extern bool FLAGS_ ## flag_name; -#define REGISTER_MODULE_INITIALIZER(name, code) - -#define SNAPPY_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) + extern bool FLAGS_ ## flag_name namespace snappy { static const uint32 kuint32max = static_cast(0xFFFFFFFF); static const int64 kint64max = static_cast(0x7FFFFFFFFFFFFFFFLL); -// Logging. - -#define LOG(level) LogMessage() -#define VLOG(level) true ? (void)0 : \ - snappy::LogMessageVoidify() & snappy::LogMessage() - -class LogMessage { - public: - LogMessage() { } - ~LogMessage() { - fprintf( stderr, "\n" ); - //cerr << endl; - } - - LogMessage& operator<<(const std::string& msg) { - //cerr << msg; - fprintf( stderr, "%s", msg.c_str() ); - - return *this; - } - LogMessage& operator<<(int x) { - fprintf( stderr, "%d", x ); - //cerr << x; - return *this; - } -}; - -// Asserts, both versions activated in debug mode only, -// and ones that are always active. - -#define CRASH_UNLESS(condition) \ - PREDICT_TRUE(condition) ? (void)0 : \ - snappy::LogMessageVoidify() & snappy::LogMessageCrash() - -class LogMessageCrash : public LogMessage { - public: - LogMessageCrash() { } -#if _MSC_VER == 1700 || _MSC_VER == 1800 -// Bogus warning from VS 2012 and VS 2013: -// warning C4722: 'snappy::LogMessageCrash::~LogMessageCrash' : destructor never returns, potential memory leak -#pragma warning(push) -#pragma warning(disable : 4722) -#endif - ~LogMessageCrash() { - fprintf( stderr, "\n" ); -// cerr << endl; - abort(); - } -}; -#if _MSC_VER == 1700 || _MSC_VER == 1800 -#pragma warning(pop) -#endif - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". - -class LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(const LogMessage&) { } -}; - -#define CHECK(cond) CRASH_UNLESS(cond) -#define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b)) -#define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b)) -#define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b)) -#define CHECK_NE(a, b) CRASH_UNLESS((a) != (b)) -#define CHECK_LT(a, b) CRASH_UNLESS((a) < (b)) -#define CHECK_GT(a, b) CRASH_UNLESS((a) > (b)) - -#ifdef NDEBUG - -#define DCHECK(cond) CRASH_UNLESS(true) -#define DCHECK_LE(a, b) CRASH_UNLESS(true) -#define DCHECK_GE(a, b) CRASH_UNLESS(true) -#define DCHECK_EQ(a, b) CRASH_UNLESS(true) -#define DCHECK_NE(a, b) CRASH_UNLESS(true) -#define DCHECK_LT(a, b) CRASH_UNLESS(true) -#define DCHECK_GT(a, b) CRASH_UNLESS(true) - -#else - -#define DCHECK(cond) CHECK(cond) -#define DCHECK_LE(a, b) CHECK_LE(a, b) -#define DCHECK_GE(a, b) CHECK_GE(a, b) -#define DCHECK_EQ(a, b) CHECK_EQ(a, b) -#define DCHECK_NE(a, b) CHECK_NE(a, b) -#define DCHECK_LT(a, b) CHECK_LT(a, b) -#define DCHECK_GT(a, b) CHECK_GT(a, b) - -#endif - // Potentially unaligned loads and stores. +// x86 and PowerPC can simply do these loads and stores native. + #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) #define UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) @@ -208,6 +110,49 @@ class LogMessageVoidify { #define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) #define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast(_p) = (_val)) +// ARMv7 and newer support native unaligned accesses, but only of 16-bit +// and 32-bit values (not 64-bit); older versions either raise a fatal signal, +// do an unaligned read and rotate the words around a bit, or do the reads very +// slowly (trip through kernel mode). There's no simple #define that says just +// “ARMv7 or higher”, so we have to filter away all ARMv5 and ARMv6 +// sub-architectures. +// +// This is a mess, but there's not much we can do about it. + +#elif defined(__arm__) && \ + !defined(__ARM_ARCH_4__) && \ + !defined(__ARM_ARCH_4T__) && \ + !defined(__ARM_ARCH_5__) && \ + !defined(__ARM_ARCH_5T__) && \ + !defined(__ARM_ARCH_5TE__) && \ + !defined(__ARM_ARCH_5TEJ__) && \ + !defined(__ARM_ARCH_6__) && \ + !defined(__ARM_ARCH_6J__) && \ + !defined(__ARM_ARCH_6K__) && \ + !defined(__ARM_ARCH_6Z__) && \ + !defined(__ARM_ARCH_6ZK__) && \ + !defined(__ARM_ARCH_6T2__) + +#define UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) +#define UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) + +#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) +#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) + +// TODO(user): NEON supports unaligned 64-bit loads and stores. +// See if that would be more efficient on platforms supporting it, +// at least for copies. + +inline uint64 UNALIGNED_LOAD64(const void *p) { + uint64 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UNALIGNED_STORE64(void *p, uint64 v) { + memcpy(p, &v, sizeof v); +} + #else // These functions are provided for architectures that don't support @@ -245,9 +190,31 @@ inline void UNALIGNED_STORE64(void *p, uint64 v) { #endif +// This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64 +// on some platforms, in particular ARM. +inline void UnalignedCopy64(const void *src, void *dst) { + if (sizeof(void *) == 8) { + UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src)); + } else { + const char *src_char = reinterpret_cast(src); + char *dst_char = reinterpret_cast(dst); + + UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char)); + UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4)); + } +} + // The following guarantees declaration of the byte swap functions. #ifdef WORDS_BIGENDIAN +#ifdef HAVE_SYS_BYTEORDER_H +#include +#endif + +#ifdef HAVE_SYS_ENDIAN_H +#include +#endif + #ifdef _MSC_VER #include #define bswap_16(x) _byteswap_ushort(x) @@ -261,8 +228,38 @@ inline void UNALIGNED_STORE64(void *p, uint64 v) { #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) -#else +#elif defined(HAVE_BYTESWAP_H) #include + +#elif defined(bswap32) +// FreeBSD defines bswap{16,32,64} in (already #included). +#define bswap_16(x) bswap16(x) +#define bswap_32(x) bswap32(x) +#define bswap_64(x) bswap64(x) + +#elif defined(BSWAP_64) +// Solaris 10 defines BSWAP_{16,32,64} in (already #included). +#define bswap_16(x) BSWAP_16(x) +#define bswap_32(x) BSWAP_32(x) +#define bswap_64(x) BSWAP_64(x) + +#else + +inline uint16 bswap_16(uint16 x) { + return (x << 8) | (x >> 8); +} + +inline uint32 bswap_32(uint32 x) { + x = ((x & 0xff00ff00UL) >> 8) | ((x & 0x00ff00ffUL) << 8); + return (x >> 16) | (x << 16); +} + +inline uint64 bswap_64(uint64 x) { + x = ((x & 0xff00ff00ff00ff00ULL) >> 8) | ((x & 0x00ff00ff00ff00ffULL) << 8); + x = ((x & 0xffff0000ffff0000ULL) >> 16) | ((x & 0x0000ffff0000ffffULL) << 16); + return (x >> 32) | (x << 32); +} + #endif #endif // WORDS_BIGENDIAN @@ -332,7 +329,7 @@ class Bits { static int FindLSBSetNonZero64(uint64 n); private: - SNAPPY_DISALLOW_COPY_AND_ASSIGN(Bits); + DISALLOW_COPY_AND_ASSIGN(Bits); }; #ifdef HAVE_BUILTIN_CTZ diff --git a/tier1/snappy.cpp b/tier1/snappy.cpp index d633ca3e..eb1bbd0d 100644 --- a/tier1/snappy.cpp +++ b/tier1/snappy.cpp @@ -37,8 +37,17 @@ #include #ifdef _WIN32 + #pragma warning(disable:4018) // warning C4018: '<' : signed/unsigned mismatch #pragma warning(disable:4389) // warning C4389: '==' : signed/unsigned mismatch + +/* Define like size_t, omitting the "unsigned" */ +#ifdef _WIN64 +typedef __int64 ssize_t; +#else +typedef int ssize_t; +#endif + #endif //_WIN32 namespace snappy { @@ -86,6 +95,7 @@ enum { COPY_2_BYTE_OFFSET = 2, COPY_4_BYTE_OFFSET = 3 }; +static const int kMaximumTagLength = 5; // COPY_4_BYTE_OFFSET plus the actual offset. // Copy "len" bytes from "src" to "op", one byte at a time. Used for // handling COPY operations where the input and output regions may @@ -98,8 +108,8 @@ enum { // ababababababababababab // Note that this does not match the semantics of either memcpy() // or memmove(). -static inline void IncrementalCopy(const char* src, char* op, int len) { - DCHECK_GT(len, 0); +static inline void IncrementalCopy(const char* src, char* op, ssize_t len) { + assert(len > 0); do { *op++ = *src++; } while (--len > 0); @@ -140,22 +150,22 @@ namespace { const int kMaxIncrementCopyOverflow = 10; -} // namespace - -static inline void IncrementalCopyFastPath(const char* src, char* op, int len) { +inline void IncrementalCopyFastPath(const char* src, char* op, ssize_t len) { while (op - src < 8) { - UNALIGNED_STORE64(op, UNALIGNED_LOAD64(src)); + UnalignedCopy64(src, op); len -= op - src; op += op - src; } while (len > 0) { - UNALIGNED_STORE64(op, UNALIGNED_LOAD64(src)); + UnalignedCopy64(src, op); src += 8; op += 8; len -= 8; } } +} // namespace + static inline char* EmitLiteral(char* op, const char* literal, int len, @@ -176,8 +186,8 @@ static inline char* EmitLiteral(char* op, // - The output will always have 32 spare bytes (see // MaxCompressedLength). if (allow_fast_path && len <= 16) { - UNALIGNED_STORE64(op, UNALIGNED_LOAD64(literal)); - UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(literal + 8)); + UnalignedCopy64(literal, op); + UnalignedCopy64(literal + 8, op + 8); return op + len; } } else { @@ -198,25 +208,25 @@ static inline char* EmitLiteral(char* op, return op + len; } -static inline char* EmitCopyLessThan64(char* op, int offset, int len) { - DCHECK_LE(len, 64); - DCHECK_GE(len, 4); - DCHECK_LT(offset, 65536); +static inline char* EmitCopyLessThan64(char* op, size_t offset, int len) { + assert(len <= 64); + assert(len >= 4); + assert(offset < 65536); if ((len < 12) && (offset < 2048)) { - int len_minus_4 = len - 4; + size_t len_minus_4 = len - 4; assert(len_minus_4 < 8); // Must fit in 3 bits - *op++ = COPY_1_BYTE_OFFSET | ((len_minus_4) << 2) | ((offset >> 8) << 5); + *op++ = (char)(COPY_1_BYTE_OFFSET + ((len_minus_4) << 2) + ((offset >> 8) << 5)); *op++ = offset & 0xff; } else { - *op++ = COPY_2_BYTE_OFFSET | ((len-1) << 2); - LittleEndian::Store16(op, offset); + *op++ = COPY_2_BYTE_OFFSET + ((len-1) << 2); + LittleEndian::Store16(op, (snappy::uint16)offset); op += 2; } return op; } -static inline char* EmitCopy(char* op, int offset, int len) { +static inline char* EmitCopy(char* op, size_t offset, int len) { // Emit 64 byte copies but make sure to keep at least four bytes reserved while (len >= 68) { op = EmitCopyLessThan64(op, offset, 64); @@ -253,12 +263,10 @@ uint16* WorkingMemory::GetHashTable(size_t input_size, int* table_size) { // compression, and if the input is short, we won't need that // many hash table entries anyway. assert(kMaxHashTableSize >= 256); - int htsize = 256; + size_t htsize = 256; while (htsize < kMaxHashTableSize && htsize < input_size) { htsize <<= 1; } - CHECK_EQ(0, htsize & (htsize - 1)) << ": must be power of two"; - CHECK_LE(htsize, kMaxHashTableSize) << ": hash table too large"; uint16* table; if (htsize <= ARRAYSIZE(small_table_)) { @@ -270,22 +278,55 @@ uint16* WorkingMemory::GetHashTable(size_t input_size, int* table_size) { table = large_table_; } - *table_size = htsize; + *table_size = (int)htsize; memset(table, 0, htsize * sizeof(*table)); return table; } } // end namespace internal -// For 0 <= offset <= 4, GetUint32AtOffset(UNALIGNED_LOAD64(p), offset) will +// For 0 <= offset <= 4, GetUint32AtOffset(GetEightBytesAt(p), offset) will // equal UNALIGNED_LOAD32(p + offset). Motivation: On x86-64 hardware we have // empirically found that overlapping loads such as // UNALIGNED_LOAD32(p) ... UNALIGNED_LOAD32(p+1) ... UNALIGNED_LOAD32(p+2) // are slower than UNALIGNED_LOAD64(p) followed by shifts and casts to uint32. +// +// We have different versions for 64- and 32-bit; ideally we would avoid the +// two functions and just inline the UNALIGNED_LOAD64 call into +// GetUint32AtOffset, but GCC (at least not as of 4.6) is seemingly not clever +// enough to avoid loading the value multiple times then. For 64-bit, the load +// is done when GetEightBytesAt() is called, whereas for 32-bit, the load is +// done at GetUint32AtOffset() time. + +#ifdef ARCH_K8 + +typedef uint64 EightBytesReference; + +static inline EightBytesReference GetEightBytesAt(const char* ptr) { + return UNALIGNED_LOAD64(ptr); +} + static inline uint32 GetUint32AtOffset(uint64 v, int offset) { - DCHECK(0 <= offset && offset <= 4) << offset; + assert(offset >= 0); + assert(offset <= 4); return v >> (LittleEndian::IsLittleEndian() ? 8 * offset : 32 - 8 * offset); } +#else + +typedef const char* EightBytesReference; + +static inline EightBytesReference GetEightBytesAt(const char* ptr) { + return ptr; +} + +static inline uint32 GetUint32AtOffset(const char* v, int offset) { + assert(offset >= 0); + assert(offset <= 4); + return UNALIGNED_LOAD32(v + offset); +} + +#endif + // Flat array compression that does not emit the "uncompressed length" // prefix. Compresses "input" string to the "*op" buffer. // @@ -298,29 +339,29 @@ static inline uint32 GetUint32AtOffset(uint64 v, int offset) { // Returns an "end" pointer into "op" buffer. // "end - op" is the compressed size of "input". namespace internal { -char* CompressFragment(const char* const input, - const size_t input_size, +char* CompressFragment(const char* input, + size_t input_size, char* op, uint16* table, const int table_size) { // "ip" is the input pointer, and "op" is the output pointer. const char* ip = input; - CHECK_LE(input_size, kBlockSize); - CHECK_EQ(table_size & (table_size - 1), 0) << ": table must be power of two"; + assert(input_size <= kBlockSize); + assert((table_size & (table_size - 1)) == 0); // table must be power of two const int shift = 32 - Bits::Log2Floor(table_size); - DCHECK_EQ(kuint32max >> shift, table_size - 1); + assert(static_cast(kuint32max >> shift) == table_size - 1); const char* ip_end = input + input_size; const char* base_ip = ip; // Bytes in [next_emit, ip) will be emitted as literal bytes. Or // [next_emit, ip_end) after the main loop. const char* next_emit = ip; - const int kInputMarginBytes = 15; + const size_t kInputMarginBytes = 15; if (PREDICT_TRUE(input_size >= kInputMarginBytes)) { const char* ip_limit = input + input_size - kInputMarginBytes; for (uint32 next_hash = Hash(++ip, shift); ; ) { - DCHECK_LT(next_emit, ip); + assert(next_emit < ip); // The body of this loop calls EmitLiteral once and then EmitCopy one or // more times. (The exception is that when we're close to exhausting // the input we goto emit_remainder.) @@ -353,7 +394,7 @@ char* CompressFragment(const char* const input, do { ip = next_ip; uint32 hash = next_hash; - DCHECK_EQ(hash, Hash(ip, shift)); + assert(hash == Hash(ip, shift)); uint32 bytes_between_hash_lookups = skip++ >> 5; next_ip = ip + bytes_between_hash_lookups; if (PREDICT_FALSE(next_ip > ip_limit)) { @@ -361,8 +402,8 @@ char* CompressFragment(const char* const input, } next_hash = Hash(next_ip, shift); candidate = base_ip + table[hash]; - DCHECK_GE(candidate, base_ip); - DCHECK_LT(candidate, ip); + assert(candidate >= base_ip); + assert(candidate < ip); table[hash] = ip - base_ip; } while (PREDICT_TRUE(UNALIGNED_LOAD32(ip) != @@ -371,7 +412,7 @@ char* CompressFragment(const char* const input, // Step 2: A 4-byte match has been found. We'll later see if more // than 4 bytes match. But, prior to the match, input // bytes [next_emit, ip) are unmatched. Emit them as "literal bytes." - DCHECK_LE(next_emit + 16, ip_end); + assert(next_emit + 16 <= ip_end); op = EmitLiteral(op, next_emit, ip - next_emit, true); // Step 3: Call EmitCopy, and then see if another EmitCopy could @@ -382,7 +423,7 @@ char* CompressFragment(const char* const input, // though we don't yet know how big the literal will be. We handle that // by proceeding to the next iteration of the main loop. We also can exit // this loop via goto if we get close to exhausting the input. - uint64 input_bytes = 0; + EightBytesReference input_bytes; uint32 candidate_bytes = 0; do { @@ -391,8 +432,8 @@ char* CompressFragment(const char* const input, const char* base = ip; int matched = 4 + FindMatchLength(candidate + 4, ip + 4, ip_end); ip += matched; - int offset = base - candidate; - DCHECK_EQ(0, memcmp(base, candidate, matched)); + size_t offset = base - candidate; + assert(0 == memcmp(base, candidate, matched)); op = EmitCopy(op, offset, matched); // We could immediately start working at ip now, but to improve // compression we first update table[Hash(ip - 1, ...)]. @@ -401,7 +442,7 @@ char* CompressFragment(const char* const input, if (PREDICT_FALSE(ip >= ip_limit)) { goto emit_remainder; } - input_bytes = UNALIGNED_LOAD64(insert_tail); + input_bytes = GetEightBytesAt(insert_tail); uint32 prev_hash = HashBytes(GetUint32AtOffset(input_bytes, 0), shift); table[prev_hash] = ip - base_ip - 1; uint32 cur_hash = HashBytes(GetUint32AtOffset(input_bytes, 1), shift); @@ -439,12 +480,31 @@ char* CompressFragment(const char* const input, // bool CheckLength() const; // // // Called repeatedly during decompression -// bool Append(const char* ip, uint32 length, bool allow_fast_path); -// bool AppendFromSelf(uint32 offset, uint32 length); -// }; +// bool Append(const char* ip, size_t length); +// bool AppendFromSelf(uint32 offset, size_t length); // -// "allow_fast_path" is a parameter that says if there is at least 16 -// readable bytes in "ip". It is currently only used by SnappyArrayWriter. +// // The rules for how TryFastAppend differs from Append are somewhat +// // convoluted: +// // +// // - TryFastAppend is allowed to decline (return false) at any +// // time, for any reason -- just "return false" would be +// // a perfectly legal implementation of TryFastAppend. +// // The intention is for TryFastAppend to allow a fast path +// // in the common case of a small append. +// // - TryFastAppend is allowed to read up to bytes +// // from the input buffer, whereas Append is allowed to read +// // . However, if it returns true, it must leave +// // at least five (kMaximumTagLength) bytes in the input buffer +// // afterwards, so that there is always enough space to read the +// // next tag without checking for a refill. +// // - TryFastAppend must always return decline (return false) +// // if is 61 or more, as in this case the literal length is not +// // decoded fully. In practice, this should not be a big problem, +// // as it is unlikely that one would implement a fast path accepting +// // this much data. +// // +// bool TryFastAppend(const char* ip, size_t available, size_t length); +// }; // ----------------------------------------------------------------------- // Lookup table for decompression code. Generated by ComputeTable() below. @@ -511,9 +571,9 @@ static uint16 MakeEntry(unsigned int extra, unsigned int len, unsigned int copy_offset) { // Check that all of the fields fit within the allocated space - DCHECK_EQ(extra, extra & 0x7); // At most 3 bits - DCHECK_EQ(copy_offset, copy_offset & 0x7); // At most 3 bits - DCHECK_EQ(len, len & 0x7f); // At most 7 bits + assert(extra == (extra & 0x7)); // At most 3 bits + assert(copy_offset == (copy_offset & 0x7)); // At most 3 bits + assert(len == (len & 0x7f)); // At most 7 bits return len | (copy_offset << 8) | (extra << 11); } @@ -571,9 +631,15 @@ static void ComputeTable() { } // Check that each entry was initialized exactly once. - CHECK_EQ(assigned, 256); + if (assigned != 256) { + fprintf(stderr, "ComputeTable: assigned only %d of 256\n", assigned); + abort(); + } for (int i = 0; i < 256; i++) { - CHECK_NE(dst[i], 0xffff); + if (dst[i] == 0xffff) { + fprintf(stderr, "ComputeTable: did not assign byte %d\n", i); + abort(); + } } if (FLAGS_snappy_dump_decompression_table) { @@ -588,10 +654,13 @@ static void ComputeTable() { // Check that computed table matched recorded table for (int i = 0; i < 256; i++) { - CHECK_EQ(dst[i], char_table[i]); + if (dst[i] != char_table[i]) { + fprintf(stderr, "ComputeTable: byte %d: computed (%x), expect (%x)\n", + i, static_cast(dst[i]), static_cast(char_table[i])); + abort(); + } } } -REGISTER_MODULE_INITIALIZER(snappy, ComputeTable()); #endif /* !NDEBUG */ // Helper class for decompression @@ -602,7 +671,7 @@ class SnappyDecompressor { const char* ip_limit_; // Points just past buffered bytes uint32 peeked_; // Bytes peeked from reader (need to skip) bool eof_; // Hit end of input without an error? - char scratch_[5]; // Temporary buffer for PeekFast() boundaries + char scratch_[kMaximumTagLength]; // See RefillTag(). // Ensure that all of the tag metadata for the next tag is available // in [ip_..ip_limit_-1]. Also ensures that [ip,ip+4] is readable even @@ -634,7 +703,7 @@ class SnappyDecompressor { // On succcess, stores the length in *result and returns true. // On failure, returns false. bool ReadUncompressedLength(uint32* result) { - DCHECK(ip_ == NULL); // Must not have read anything yet + assert(ip_ == NULL); // Must not have read anything yet // Length is encoded in 1..5 bytes *result = 0; uint32 shift = 0; @@ -659,40 +728,63 @@ class SnappyDecompressor { template void DecompressAllTags(Writer* writer) { const char* ip = ip_; - for ( ;; ) { - if (ip_limit_ - ip < 5) { - ip_ = ip; - if (!RefillTag()) return; - ip = ip_; - } + // We could have put this refill fragment only at the beginning of the loop. + // However, duplicating it at the end of each branch gives the compiler more + // scope to optimize the expression based on the local + // context, which overall increases speed. + #define MAYBE_REFILL() \ + if (ip_limit_ - ip < kMaximumTagLength) { \ + ip_ = ip; \ + if (!RefillTag()) return; \ + ip = ip_; \ + } + + MAYBE_REFILL(); + for ( ;; ) { const unsigned char c = *(reinterpret_cast(ip++)); - const uint32 entry = char_table[c]; - const uint32 trailer = LittleEndian::Load32(ip) & wordmask[entry >> 11]; - ip += entry >> 11; - const uint32 length = entry & 0xff; if ((c & 0x3) == LITERAL) { - uint32 literal_length = length + trailer; - uint32 avail = ip_limit_ - ip; + size_t literal_length = (c >> 2) + 1u; + if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length)) { + assert(literal_length < 61); + ip += literal_length; + // NOTE(user): There is no MAYBE_REFILL() here, as TryFastAppend() + // will not return true unless there's already at least five spare + // bytes in addition to the literal. + continue; + } + if (PREDICT_FALSE(literal_length >= 61)) { + // Long literal. + const size_t literal_length_length = literal_length - 60; + literal_length = + (LittleEndian::Load32(ip) & wordmask[literal_length_length]) + 1; + ip += literal_length_length; + } + + size_t avail = ip_limit_ - ip; while (avail < literal_length) { - bool allow_fast_path = (avail >= 16); - if (!writer->Append(ip, avail, allow_fast_path)) return; + if (!writer->Append(ip, avail)) return; literal_length -= avail; reader_->Skip(peeked_); size_t n; ip = reader_->Peek(&n); - avail = (uint32)n; - peeked_ = avail; + avail = n; + peeked_ = (snappy::uint32)avail; if (avail == 0) return; // Premature end of input ip_limit_ = ip + avail; } - bool allow_fast_path = (avail >= 16); - if (!writer->Append(ip, literal_length, allow_fast_path)) { + if (!writer->Append(ip, literal_length)) { return; } ip += literal_length; + MAYBE_REFILL(); } else { + const uint32 entry = char_table[c]; + const uint32 trailer = LittleEndian::Load32(ip) & wordmask[entry >> 11]; + const uint32 length = entry & 0xff; + ip += entry >> 11; + // copy_offset/256 is encoded in bits 8..10. By just fetching // those bits, we get copy_offset (since the bit-field starts at // bit 8). @@ -700,8 +792,11 @@ class SnappyDecompressor { if (!writer->AppendFromSelf(copy_offset + trailer, length)) { return; } + MAYBE_REFILL(); } } + +#undef MAYBE_REFILL } }; @@ -712,7 +807,7 @@ bool SnappyDecompressor::RefillTag() { reader_->Skip(peeked_); // All peeked bytes are used up size_t n; ip = reader_->Peek(&n); - peeked_ = (uint32)n; + peeked_ = (snappy::uint32)n; if (n == 0) { eof_ = true; return false; @@ -721,11 +816,11 @@ bool SnappyDecompressor::RefillTag() { } // Read the tag character - DCHECK_LT(ip, ip_limit_); + assert(ip < ip_limit_); const unsigned char c = *(reinterpret_cast(ip)); const uint32 entry = char_table[c]; const uint32 needed = (entry >> 11) + 1; // +1 byte for 'c' - DCHECK_LE(needed, sizeof(scratch_)); + assert(needed <= sizeof(scratch_)); // Read more bytes from reader if needed uint32 nbuf = ip_limit_ - ip; @@ -741,15 +836,15 @@ bool SnappyDecompressor::RefillTag() { size_t length; const char* src = reader_->Peek(&length); if (length == 0) return false; - uint32 to_add = min(needed - nbuf, (uint32)length); + uint32 to_add = Min(needed - nbuf, (uint32)length); memcpy(scratch_ + nbuf, src, to_add); nbuf += to_add; reader_->Skip(to_add); } - DCHECK_EQ(nbuf, needed); + assert(nbuf == needed); ip_ = scratch_; ip_limit_ = scratch_ + needed; - } else if (nbuf < 5) { + } else if (nbuf < kMaximumTagLength) { // Have enough bytes, but move into scratch_ so that we do not // read past end of input memmove(scratch_, ip, nbuf); @@ -765,23 +860,23 @@ bool SnappyDecompressor::RefillTag() { } template -static bool InternalUncompress(Source* r, - Writer* writer, - uint32 max_len) { +static bool InternalUncompress(Source* r, Writer* writer) { // Read the uncompressed length from the front of the compressed input SnappyDecompressor decompressor(r); uint32 uncompressed_len = 0; if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false; - // Protect against possible DoS attack - if (static_cast(uncompressed_len) > max_len) { - return false; - } + return InternalUncompressAllTags(&decompressor, writer, uncompressed_len); +} +template +static bool InternalUncompressAllTags(SnappyDecompressor* decompressor, + Writer* writer, + uint32 uncompressed_len) { writer->SetExpectedLength(uncompressed_len); // Process the entire input - decompressor.DecompressAllTags(writer); - return (decompressor.eof() && writer->CheckLength()); + decompressor->DecompressAllTags(writer); + return (decompressor->eof() && writer->CheckLength()); } bool GetUncompressedLength(Source* source, uint32* result) { @@ -791,9 +886,9 @@ bool GetUncompressedLength(Source* source, uint32* result) { size_t Compress(Source* reader, Sink* writer) { size_t written = 0; - int N = (int)reader->Available(); + size_t N = reader->Available(); char ulength[Varint::kMax32]; - char* p = Varint::Encode32(ulength, N); + char* p = Varint::Encode32(ulength, (snappy::uint32)N); writer->Append(ulength, p-ulength); written += (p - ulength); @@ -805,11 +900,11 @@ size_t Compress(Source* reader, Sink* writer) { // Get next block to compress (without copying if possible) size_t fragment_size; const char* fragment = reader->Peek(&fragment_size); - DCHECK_NE(fragment_size, 0) << ": premature end of input"; - const int num_to_read = min(N, kBlockSize); + assert(fragment_size != 0); // premature end of input + const size_t num_to_read = min(N, kBlockSize); size_t bytes_read = fragment_size; - int pending_advance = 0; + size_t pending_advance = 0; if (bytes_read >= num_to_read) { // Buffer returned by reader is large enough pending_advance = num_to_read; @@ -827,23 +922,23 @@ size_t Compress(Source* reader, Sink* writer) { while (bytes_read < num_to_read) { fragment = reader->Peek(&fragment_size); - size_t n = min(fragment_size, num_to_read - bytes_read); + size_t n = Min(fragment_size, num_to_read - bytes_read); memcpy(scratch + bytes_read, fragment, n); bytes_read += n; reader->Skip(n); } - DCHECK_EQ(bytes_read, num_to_read); + assert(bytes_read == num_to_read); fragment = scratch; fragment_size = num_to_read; } - DCHECK_EQ(fragment_size, num_to_read); + assert(fragment_size == num_to_read); // Get encoding table for compression int table_size; uint16* table = wmem.GetHashTable(num_to_read, &table_size); // Compress input_fragment and append to dest - const size_t max_output = MaxCompressedLength(num_to_read); + const int max_output = (int)MaxCompressedLength(num_to_read); // Need a scratch buffer for the output, in case the byte sink doesn't // have room for us directly. @@ -870,6 +965,183 @@ size_t Compress(Source* reader, Sink* writer) { return written; } +// ----------------------------------------------------------------------- +// IOVec interfaces +// ----------------------------------------------------------------------- + +// A type that writes to an iovec. +// Note that this is not a "ByteSink", but a type that matches the +// Writer template argument to SnappyDecompressor::DecompressAllTags(). +class SnappyIOVecWriter { + private: + const struct iovec* output_iov_; + const size_t output_iov_count_; + + // We are currently writing into output_iov_[curr_iov_index_]. + int curr_iov_index_; + + // Bytes written to output_iov_[curr_iov_index_] so far. + size_t curr_iov_written_; + + // Total bytes decompressed into output_iov_ so far. + size_t total_written_; + + // Maximum number of bytes that will be decompressed into output_iov_. + size_t output_limit_; + + inline char* GetIOVecPointer(int index, size_t offset) { + return reinterpret_cast(output_iov_[index].iov_base) + + offset; + } + + public: + // Does not take ownership of iov. iov must be valid during the + // entire lifetime of the SnappyIOVecWriter. + inline SnappyIOVecWriter(const struct iovec* iov, size_t iov_count) + : output_iov_(iov), + output_iov_count_(iov_count), + curr_iov_index_(0), + curr_iov_written_(0), + total_written_(0), + output_limit_((size_t)-1) { + } + + inline void SetExpectedLength(size_t len) { + output_limit_ = len; + } + + inline bool CheckLength() const { + return total_written_ == output_limit_; + } + + inline bool Append(const char* ip, size_t len) { + if (total_written_ + len > output_limit_) { + return false; + } + + while (len > 0) { + assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len); + if (curr_iov_written_ >= output_iov_[curr_iov_index_].iov_len) { + // This iovec is full. Go to the next one. + if (curr_iov_index_ + 1 >= output_iov_count_) { + return false; + } + curr_iov_written_ = 0; + ++curr_iov_index_; + } + + const size_t to_write = Min( + len, output_iov_[curr_iov_index_].iov_len - curr_iov_written_); + memcpy(GetIOVecPointer(curr_iov_index_, curr_iov_written_), + ip, + to_write); + curr_iov_written_ += to_write; + total_written_ += to_write; + ip += to_write; + len -= to_write; + } + + return true; + } + + inline bool TryFastAppend(const char* ip, size_t available, size_t len) { + const size_t space_left = output_limit_ - total_written_; + if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16 && + output_iov_[curr_iov_index_].iov_len - curr_iov_written_ >= 16) { + // Fast path, used for the majority (about 95%) of invocations. + char* ptr = GetIOVecPointer(curr_iov_index_, curr_iov_written_); + UnalignedCopy64(ip, ptr); + UnalignedCopy64(ip + 8, ptr + 8); + curr_iov_written_ += len; + total_written_ += len; + return true; + } + + return false; + } + + inline bool AppendFromSelf(size_t offset, size_t len) { + if (offset > total_written_ || offset == 0) { + return false; + } + const size_t space_left = output_limit_ - total_written_; + if (len > space_left) { + return false; + } + + // Locate the iovec from which we need to start the copy. + int from_iov_index = curr_iov_index_; + size_t from_iov_offset = curr_iov_written_; + while (offset > 0) { + if (from_iov_offset >= offset) { + from_iov_offset -= offset; + break; + } + + offset -= from_iov_offset; + --from_iov_index; + assert(from_iov_index >= 0); + from_iov_offset = output_iov_[from_iov_index].iov_len; + } + + // Copy bytes starting from the iovec pointed to by from_iov_index to + // the current iovec. + while (len > 0) { + assert(from_iov_index <= curr_iov_index_); + if (from_iov_index != curr_iov_index_) { + const size_t to_copy = Min( + output_iov_[from_iov_index].iov_len - from_iov_offset, + len); + Append(GetIOVecPointer(from_iov_index, from_iov_offset), to_copy); + len -= to_copy; + if (len > 0) { + ++from_iov_index; + from_iov_offset = 0; + } + } else { + assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len); + size_t to_copy = Min(output_iov_[curr_iov_index_].iov_len - + curr_iov_written_, + len); + if (to_copy == 0) { + // This iovec is full. Go to the next one. + if (curr_iov_index_ + 1 >= output_iov_count_) { + return false; + } + ++curr_iov_index_; + curr_iov_written_ = 0; + continue; + } + if (to_copy > len) { + to_copy = len; + } + IncrementalCopy(GetIOVecPointer(from_iov_index, from_iov_offset), + GetIOVecPointer(curr_iov_index_, curr_iov_written_), + to_copy); + curr_iov_written_ += to_copy; + from_iov_offset += to_copy; + total_written_ += to_copy; + len -= to_copy; + } + } + + return true; + } + +}; + +bool RawUncompressToIOVec(const char* compressed, size_t compressed_length, + const struct iovec* iov, size_t iov_cnt) { + ByteArraySource reader(compressed, compressed_length); + return RawUncompressToIOVec(&reader, iov, iov_cnt); +} + +bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov, + size_t iov_cnt) { + SnappyIOVecWriter output(iov, iov_cnt); + return InternalUncompress(compressed, &output); +} + // ----------------------------------------------------------------------- // Flat array interfaces // ----------------------------------------------------------------------- @@ -897,34 +1169,51 @@ class SnappyArrayWriter { return op_ == op_limit_; } - inline bool Append(const char* ip, uint32 len, bool allow_fast_path) { + inline bool Append(const char* ip, size_t len) { char* op = op_; - const int space_left = op_limit_ - op; - if (allow_fast_path && len <= 16 && space_left >= 16) { - // Fast path, used for the majority (about 90%) of dynamic invocations. - UNALIGNED_STORE64(op, UNALIGNED_LOAD64(ip)); - UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(ip + 8)); - } else { - if (space_left < len) { - return false; - } - memcpy(op, ip, len); + const size_t space_left = op_limit_ - op; + if (space_left < len) { + return false; } + memcpy(op, ip, len); op_ = op + len; return true; } - inline bool AppendFromSelf(uint32 offset, uint32 len) { + inline bool TryFastAppend(const char* ip, size_t available, size_t len) { char* op = op_; - const int space_left = op_limit_ - op; + const size_t space_left = op_limit_ - op; + if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16) { + // Fast path, used for the majority (about 95%) of invocations. + UnalignedCopy64(ip, op); + UnalignedCopy64(ip + 8, op + 8); + op_ = op + len; + return true; + } else { + return false; + } + } - if (op - base_ <= offset - 1u) { // -1u catches offset==0 + inline bool AppendFromSelf(size_t offset, size_t len) { + char* op = op_; + const size_t space_left = op_limit_ - op; + + // Check if we try to append from before the start of the buffer. + // Normally this would just be a check for "produced < offset", + // but "produced <= offset - 1u" is equivalent for every case + // except the one where offset==0, where the right side will wrap around + // to a very big number. This is convenient, as offset==0 is another + // invalid case that we also want to catch, so that we do not go + // into an infinite loop. + assert(op >= base_); + size_t produced = op - base_; + if (produced <= offset - 1u) { return false; } if (len <= 16 && offset >= 8 && space_left >= 16) { // Fast path, used for the majority (70-80%) of dynamic invocations. - UNALIGNED_STORE64(op, UNALIGNED_LOAD64(op - offset)); - UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(op - offset + 8)); + UnalignedCopy64(op - offset, op); + UnalignedCopy64(op - offset + 8, op + 8); } else { if (space_left >= len + kMaxIncrementCopyOverflow) { IncrementalCopyFastPath(op - offset, op, len); @@ -948,7 +1237,7 @@ bool RawUncompress(const char* compressed, size_t n, char* uncompressed) { bool RawUncompress(Source* compressed, char* uncompressed) { SnappyArrayWriter output(uncompressed); - return InternalUncompress(compressed, &output, kuint32max); + return InternalUncompress(compressed, &output); } bool Uncompress(const char* compressed, size_t n, string* uncompressed) { @@ -956,9 +1245,9 @@ bool Uncompress(const char* compressed, size_t n, string* uncompressed) { if (!GetUncompressedLength(compressed, n, &ulength)) { return false; } - // Protect against possible DoS attack - if ((static_cast(ulength) + uncompressed->size()) > - uncompressed->max_size()) { + // On 32-bit builds: max_size() < kuint32max. Check for that instead + // of crashing (e.g., consider externally specified compressed data). + if (ulength > uncompressed->max_size()) { return false; } STLStringResizeUninitialized(uncompressed, ulength); @@ -980,12 +1269,17 @@ class SnappyDecompressionValidator { inline bool CheckLength() const { return expected_ == produced_; } - inline bool Append(const char* ip, uint32 len, bool allow_fast_path) { + inline bool Append(const char* ip, size_t len) { produced_ += len; return produced_ <= expected_; } - inline bool AppendFromSelf(uint32 offset, uint32 len) { - if (produced_ <= offset - 1u) return false; // -1u catches offset==0 + inline bool TryFastAppend(const char* ip, size_t available, size_t length) { + return false; + } + inline bool AppendFromSelf(size_t offset, size_t len) { + // See SnappyArrayWriter::AppendFromSelf for an explanation of + // the "offset - 1u" trick. + if (produced_ <= offset - 1u) return false; produced_ += len; return produced_ <= expected_; } @@ -994,7 +1288,7 @@ class SnappyDecompressionValidator { bool IsValidCompressedBuffer(const char* compressed, size_t n) { ByteArraySource reader(compressed, n); SnappyDecompressionValidator writer; - return InternalUncompress(&reader, &writer, kuint32max); + return InternalUncompress(&reader, &writer); } void RawCompress(const char* input, diff --git a/tier1/splitstring.cpp b/tier1/splitstring.cpp index d2694328..3850dc5b 100644 --- a/tier1/splitstring.cpp +++ b/tier1/splitstring.cpp @@ -70,7 +70,8 @@ void CSplitString::Construct( const char *pString, const char **pSeparators, int else { // Copy the rest of the string - if ( int nTokenLength = strlen( pCurPos ) ) + int nTokenLength = strlen( pCurPos ); + if ( nTokenLength ) { ////////////////////////////////////////////////////////////////////////// // There's no need to cut this token, because there's no separator after it. diff --git a/tier1/strtools.cpp b/tier1/strtools.cpp index 5e7fd002..7a4f45dc 100644 --- a/tier1/strtools.cpp +++ b/tier1/strtools.cpp @@ -1190,6 +1190,7 @@ bool Q_IsMeanSpaceW( wchar_t wch ) case L'\x200B': // ZERO-WIDTH SPACE case L'\x200C': // ZERO-WIDTH NON-JOINER case L'\x200D': // ZERO WIDTH JOINER + case L'\x200E': // LEFT-TO-RIGHT MARK case L'\x2028': // LINE SEPARATOR case L'\x2029': // PARAGRAPH SEPARATOR case L'\x202F': // NARROW NO-BREAK SPACE @@ -1240,6 +1241,48 @@ static wchar_t *StripWhitespaceWorker( int cchLength, wchar_t *pwch, bool *pbStr return pwch; } +//----------------------------------------------------------------------------- +// Purpose: Strips all evil characters (ie. zero-width no-break space) +// from a string. +//----------------------------------------------------------------------------- +bool Q_RemoveAllEvilCharacters( char *pch ) +{ + // convert to unicode + int cch = Q_strlen( pch ); + int cubDest = (cch + 1 ) * sizeof( wchar_t ); + wchar_t *pwch = (wchar_t *)stackalloc( cubDest ); + int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ); + + bool bStrippedWhitespace = false; + + // Walk through and skip over evil characters + int nWalk = 0; + for( int i=0; i 0 ) { - cchResult = 0; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUTF8 ); iconv_close( conv_t ); if ( (int)cchResult < 0 ) @@ -1463,7 +1505,6 @@ int V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, char *pUCS2, in char *pOut = pUCS2; if ( conv_t > 0 ) { - cchResult = 0; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUCS2 ); iconv_close( conv_t ); if ( (int)cchResult < 0 ) @@ -1510,7 +1551,6 @@ int V_UCS2ToUTF8( const ucs2 *pUCS2, char *pUTF8, int cubDestSizeInBytes ) char *pOut = (char *)pUTF8; if ( conv_t > 0 ) { - cchResult = 0; const size_t nBytesToWrite = nMaxUTF8; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUTF8 ); @@ -1556,7 +1596,6 @@ int V_UTF8ToUCS2( const char *pUTF8, int cubSrcInBytes, ucs2 *pUCS2, int cubDest char *pOut = (char *)pUCS2; if ( conv_t > 0 ) { - cchResult = 0; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUTF8 ); iconv_close( conv_t ); if ( (int)cchResult < 0 ) @@ -1824,7 +1863,18 @@ void V_DefaultExtension( char *path, const char *extension, int pathStringLength void V_SetExtension( char *path, const char *extension, int pathStringLength ) { V_StripExtension( path, path, pathStringLength ); - V_DefaultExtension( path, extension, pathStringLength ); + + // We either had an extension and stripped it, or didn't have an extension + // at all. Either way, we need to concatenate our extension now. + + // extension is not required to start with '.', so if it's not there, + // then append that first. + if ( extension[0] != '.' ) + { + V_strncat( path, ".", pathStringLength, COPY_ALL_CHARACTERS ); + } + + V_strncat( path, extension, pathStringLength, COPY_ALL_CHARACTERS ); } //----------------------------------------------------------------------------- @@ -2663,6 +2713,217 @@ char *V_AddBackSlashesToSpecialChars( char const *pSrc ) *( pOut++ ) = 0; return pRet; } + +//----------------------------------------------------------------------------- +// Purpose: Helper for converting a numeric value to a hex digit, value should be 0-15. +//----------------------------------------------------------------------------- +char cIntToHexDigit( int nValue ) +{ + Assert( nValue >= 0 && nValue <= 15 ); + return "0123456789ABCDEF"[ nValue & 15 ]; +} + +//----------------------------------------------------------------------------- +// Purpose: Helper for converting a hex char value to numeric, return -1 if the char +// is not a valid hex digit. +//----------------------------------------------------------------------------- +int iHexCharToInt( char cValue ) +{ + int32 iValue = cValue; + if ( (uint32)( iValue - '0' ) < 10 ) + return iValue - '0'; + + iValue |= 0x20; + if ( (uint32)( iValue - 'a' ) < 6 ) + return iValue - 'a' + 10; + + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: Internal implementation of encode, works in the strict RFC manner, or +// with spaces turned to + like HTML form encoding. +//----------------------------------------------------------------------------- +void Q_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace ) +{ + if ( nDestLen < 3*nSourceLen ) + { + pchDest[0] = '\0'; + AssertMsg( false, "Target buffer for Q_URLEncode needs to be 3 times larger than source to guarantee enough space\n" ); + return; + } + + int iDestPos = 0; + for ( int i=0; i < nSourceLen; ++i ) + { + // We allow only a-z, A-Z, 0-9, period, underscore, and hyphen to pass through unescaped. + // These are the characters allowed by both the original RFC 1738 and the latest RFC 3986. + // Current specs also allow '~', but that is forbidden under original RFC 1738. + if ( !( pchSource[i] >= 'a' && pchSource[i] <= 'z' ) && !( pchSource[i] >= 'A' && pchSource[i] <= 'Z' ) && !(pchSource[i] >= '0' && pchSource[i] <= '9' ) + && pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.' + ) + { + if ( bUsePlusForSpace && pchSource[i] == ' ' ) + { + pchDest[iDestPos++] = '+'; + } + else + { + pchDest[iDestPos++] = '%'; + uint8 iValue = pchSource[i]; + if ( iValue == 0 ) + { + pchDest[iDestPos++] = '0'; + pchDest[iDestPos++] = '0'; + } + else + { + char cHexDigit1 = cIntToHexDigit( iValue % 16 ); + iValue /= 16; + char cHexDigit2 = cIntToHexDigit( iValue ); + pchDest[iDestPos++] = cHexDigit2; + pchDest[iDestPos++] = cHexDigit1; + } + } + } + else + { + pchDest[iDestPos++] = pchSource[i]; + } + } + + // Null terminate + pchDest[iDestPos++] = 0; +} + + +//----------------------------------------------------------------------------- +// Purpose: Internal implementation of decode, works in the strict RFC manner, or +// with spaces turned to + like HTML form encoding. +// +// Returns the amount of space used in the output buffer. +//----------------------------------------------------------------------------- +size_t Q_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace ) +{ + if ( nDecodeDestLen < nEncodedSourceLen ) + { + AssertMsg( false, "Q_URLDecode needs a dest buffer at least as large as the source" ); + return 0; + } + + int iDestPos = 0; + for( int i=0; i < nEncodedSourceLen; ++i ) + { + if ( bUsePlusForSpace && pchEncodedSource[i] == '+' ) + { + pchDecodeDest[ iDestPos++ ] = ' '; + } + else if ( pchEncodedSource[i] == '%' ) + { + // Percent signifies an encoded value, look ahead for the hex code, convert to numeric, and use that + + // First make sure we have 2 more chars + if ( i < nEncodedSourceLen - 2 ) + { + char cHexDigit1 = pchEncodedSource[i+1]; + char cHexDigit2 = pchEncodedSource[i+2]; + + // Turn the chars into a hex value, if they are not valid, then we'll + // just place the % and the following two chars direct into the string, + // even though this really shouldn't happen, who knows what bad clients + // may do with encoding. + bool bValid = false; + int iValue = iHexCharToInt( cHexDigit1 ); + if ( iValue != -1 ) + { + iValue *= 16; + int iValue2 = iHexCharToInt( cHexDigit2 ); + if ( iValue2 != -1 ) + { + iValue += iValue2; + pchDecodeDest[ iDestPos++ ] = iValue; + bValid = true; + } + } + + if ( !bValid ) + { + pchDecodeDest[ iDestPos++ ] = '%'; + pchDecodeDest[ iDestPos++ ] = cHexDigit1; + pchDecodeDest[ iDestPos++ ] = cHexDigit2; + } + } + + // Skip ahead + i += 2; + } + else + { + pchDecodeDest[ iDestPos++ ] = pchEncodedSource[i]; + } + } + + // We may not have extra room to NULL terminate, since this can be used on raw data, but if we do + // go ahead and do it as this can avoid bugs. + if ( iDestPos < nDecodeDestLen ) + { + pchDecodeDest[iDestPos] = 0; + } + + return (size_t)iDestPos; +} + +//----------------------------------------------------------------------------- +// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version of the call isn't a strict RFC implementation, but uses + for space as is +// the standard in HTML form encoding, despite it not being part of the RFC. +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +//----------------------------------------------------------------------------- +void Q_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ) +{ + return Q_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version of the call isn't a strict RFC implementation, but uses + for space as is +// the standard in HTML form encoding, despite it not being part of the RFC. +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. +//----------------------------------------------------------------------------- +size_t Q_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ) +{ + return Q_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version will not encode space as + (which HTML form encoding uses despite not being part of the RFC) +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +//----------------------------------------------------------------------------- +void Q_URLEncodeRaw( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ) +{ + return Q_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, false ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version will not recognize + as a space (which HTML form encoding uses despite not being part of the RFC) +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. +//----------------------------------------------------------------------------- +size_t Q_URLDecodeRaw( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ) +{ + return Q_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, false ); +} + #if defined( LINUX ) || defined( _PS3 ) extern "C" void qsort_s( void *base, size_t num, size_t width, int (*compare )(void *, const void *, const void *), void * context ); #endif diff --git a/tier1/tier1.vpc b/tier1/tier1.vpc index 9ff36c83..667d8b02 100644 --- a/tier1/tier1.vpc +++ b/tier1/tier1.vpc @@ -72,6 +72,7 @@ $Project "tier1" $File "utlbufferutil.cpp" $File "utlstring.cpp" $File "utlsymbol.cpp" + $File "utlbinaryblock.cpp" $File "pathmatch.cpp" [$LINUXALL] $File "snappy.cpp" $File "snappy-sinksource.cpp" @@ -147,6 +148,7 @@ $Project "tier1" $File "$SRCDIR\public\tier1\utlsymbol.h" $File "$SRCDIR\public\tier1\utlsymbollarge.h" $File "$SRCDIR\public\tier1\utlvector.h" + $File "$SRCDIR\public\tier1\utlbinaryblock.h" $File "$SRCDIR\common\xbox\xboxstubs.h" [$WINDOWS] } } diff --git a/tier1/utlbufferutil.cpp b/tier1/utlbufferutil.cpp index 127e7ccd..f37e4b05 100644 --- a/tier1/utlbufferutil.cpp +++ b/tier1/utlbufferutil.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "tier1/utlbinaryblock.h" #include "tier1/utlstring.h" #include "tier1/strtools.h" #include "tier1/characterset.h" @@ -552,7 +553,7 @@ bool Unserialize( CUtlBuffer &buf, CUtlString &dest ) { int nLen = buf.PeekDelimitedStringLength( s_pConv ); dest.SetLength( nLen - 1 ); // -1 because the length returned includes space for \0 - buf.GetDelimitedString( s_pConv, dest.Get(), nLen ); + buf.GetDelimitedString( s_pConv, dest.GetForModify(), nLen ); return buf.IsValid(); } diff --git a/tier1/utlstring.cpp b/tier1/utlstring.cpp index 10920db9..300766b9 100644 --- a/tier1/utlstring.cpp +++ b/tier1/utlstring.cpp @@ -4,6 +4,9 @@ // //============================================================================= +#define __STDC_LIMIT_MACROS +#include + #include "tier1/utlstring.h" #include "tier1/strtools.h" #include @@ -11,312 +14,256 @@ // NOTE: This has to be the last file included! #include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- -// Base class, containing simple memory management -//----------------------------------------------------------------------------- -CUtlBinaryBlock::CUtlBinaryBlock( int growSize, int initSize ) -{ - MEM_ALLOC_CREDIT(); - m_Memory.Init( growSize, initSize ); - - m_nActualLength = 0; -} - -CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes ) -{ - m_nActualLength = nInitialLength; -} - -CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes ) -{ - m_nActualLength = nSizeInBytes; -} - -CUtlBinaryBlock::CUtlBinaryBlock( const CUtlBinaryBlock& src ) -{ - Set( src.Get(), src.Length() ); -} - -void CUtlBinaryBlock::Get( void *pValue, int nLen ) const -{ - Assert( nLen > 0 ); - if ( m_nActualLength < nLen ) - { - nLen = m_nActualLength; - } - - if ( nLen > 0 ) - { - memcpy( pValue, m_Memory.Base(), nLen ); - } -} - -void CUtlBinaryBlock::SetLength( int nLength ) -{ - MEM_ALLOC_CREDIT(); - Assert( !m_Memory.IsReadOnly() ); - - m_nActualLength = nLength; - if ( nLength > m_Memory.NumAllocated() ) - { - int nOverFlow = nLength - m_Memory.NumAllocated(); - m_Memory.Grow( nOverFlow ); - - // If the reallocation failed, clamp length - if ( nLength > m_Memory.NumAllocated() ) - { - m_nActualLength = m_Memory.NumAllocated(); - } - } - -#ifdef _DEBUG - if ( m_Memory.NumAllocated() > m_nActualLength ) - { - memset( ( ( char * )m_Memory.Base() ) + m_nActualLength, 0xEB, m_Memory.NumAllocated() - m_nActualLength ); - } -#endif -} - - -void CUtlBinaryBlock::Set( const void *pValue, int nLen ) -{ - Assert( !m_Memory.IsReadOnly() ); - - if ( !pValue ) - { - nLen = 0; - } - - SetLength( nLen ); - - if ( m_nActualLength ) - { - if ( ( ( const char * )m_Memory.Base() ) >= ( ( const char * )pValue ) + nLen || - ( ( const char * )m_Memory.Base() ) + m_nActualLength <= ( ( const char * )pValue ) ) - { - memcpy( m_Memory.Base(), pValue, m_nActualLength ); - } - else - { - memmove( m_Memory.Base(), pValue, m_nActualLength ); - } - } -} - - -CUtlBinaryBlock &CUtlBinaryBlock::operator=( const CUtlBinaryBlock &src ) -{ - Assert( !m_Memory.IsReadOnly() ); - Set( src.Get(), src.Length() ); - return *this; -} - - -bool CUtlBinaryBlock::operator==( const CUtlBinaryBlock &src ) const -{ - if ( src.Length() != Length() ) - return false; - - return !memcmp( src.Get(), Get(), Length() ); -} - - //----------------------------------------------------------------------------- // Simple string class. //----------------------------------------------------------------------------- -CUtlString::CUtlString() -{ -} - -CUtlString::CUtlString( const char *pString ) -{ - Set( pString ); -} - -CUtlString::CUtlString( const CUtlString& string ) -{ - Set( string.Get() ); -} - -// Attaches the string to external memory. Useful for avoiding a copy -CUtlString::CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Storage( pMemory, nSizeInBytes, nInitialLength ) -{ -} - -CUtlString::CUtlString( const void* pMemory, int nSizeInBytes ) : m_Storage( pMemory, nSizeInBytes ) -{ -} - //----------------------------------------------------------------------------- -// Purpose: Set directly and don't look for a null terminator in pValue. +// Either allocates or reallocates memory to the length +// +// Allocated space for length characters. It automatically adds space for the +// nul and the cached length at the start of the memory block. Will adjust +// m_pString and explicitly set the nul at the end before returning. +void *CUtlString::AllocMemory( uint32 length ) +{ + void *pMemoryBlock; + if ( m_pString ) + { + pMemoryBlock = realloc( m_pString, length + 1 ); + } + else + { + pMemoryBlock = malloc( length + 1 ); + } + m_pString = (char*)pMemoryBlock; + m_pString[ length ] = 0; + + return pMemoryBlock; +} + //----------------------------------------------------------------------------- void CUtlString::SetDirect( const char *pValue, int nChars ) { - Assert( !m_Storage.IsReadOnly() ); - m_Storage.Set( pValue, nChars + 1 ); + if ( pValue && nChars > 0 ) + { + if ( pValue == m_pString ) + { + AssertMsg( nChars == Q_strlen(m_pString), "CUtlString::SetDirect does not support resizing strings in place." ); + return; // Do nothing. Realloc in AllocMemory might move pValue's location resulting in a bad memcpy. + } + + Assert( nChars <= Min( strnlen(pValue, nChars) + 1, nChars ) ); + AllocMemory( nChars ); + Q_memcpy( m_pString, pValue, nChars ); + } + else + { + Purge(); + } - // Make sure to null terminate the copied string - *(((char *)m_Storage.Get()) + nChars) = NULL; } void CUtlString::Set( const char *pValue ) { - Assert( !m_Storage.IsReadOnly() ); - int nLen = pValue ? Q_strlen(pValue) + 1 : 0; - m_Storage.Set( pValue, nLen ); -} - - -// Returns strlen -int CUtlString::Length() const -{ - return m_Storage.Length() ? m_Storage.Length() - 1 : 0; + int length = pValue ? V_strlen( pValue ) : 0; + SetDirect( pValue, length ); } // Sets the length (used to serialize into the buffer ) void CUtlString::SetLength( int nLen ) { - Assert( !m_Storage.IsReadOnly() ); - - // Add 1 to account for the NULL - m_Storage.SetLength( nLen > 0 ? nLen + 1 : 0 ); + if ( nLen > 0 ) + { +#ifdef _DEBUG + int prevLen = m_pString ? Length() : 0; +#endif + AllocMemory( nLen ); +#ifdef _DEBUG + if ( nLen > prevLen ) + { + V_memset( m_pString + prevLen, 0xEB, nLen - prevLen ); + } +#endif + } + else + { + Purge(); + } } const char *CUtlString::Get( ) const { - if ( m_Storage.Length() == 0 ) + if (!m_pString) { return ""; } - - return reinterpret_cast< const char* >( m_Storage.Get() ); + return m_pString; } -// Converts to c-strings -CUtlString::operator const char*() const +char *CUtlString::GetForModify() { - return Get(); -} - -char *CUtlString::Get() -{ - Assert( !m_Storage.IsReadOnly() ); - - if ( m_Storage.Length() == 0 ) + if ( !m_pString ) { // In general, we optimise away small mallocs for empty strings // but if you ask for the non-const bytes, they must be writable // so we can't return "" here, like we do for the const version - jd - m_Storage.SetLength( 1 ); - m_Storage[ 0 ] = '\0'; + void *pMemoryBlock = malloc( 1 ); + m_pString = (char *)pMemoryBlock; + *m_pString = 0; } - return reinterpret_cast< char* >( m_Storage.Get() ); + return m_pString; +} + +char CUtlString::operator[]( int i ) const +{ + if ( !m_pString ) + return '\0'; + + if ( i >= Length() ) + { + return '\0'; + } + + return m_pString[i]; +} + +void CUtlString::Clear() +{ + Purge(); } void CUtlString::Purge() { - m_Storage.Purge(); + free( m_pString ); + m_pString = NULL; +} + +bool CUtlString::IsEqual_CaseSensitive( const char *src ) const +{ + if ( !src ) + { + return (Length() == 0); + } + return ( V_strcmp( Get(), src ) == 0 ); +} + +bool CUtlString::IsEqual_CaseInsensitive( const char *src ) const +{ + if ( !src ) + { + return (Length() == 0); + } + return ( V_stricmp( Get(), src ) == 0 ); } void CUtlString::ToLower() { - for( int nLength = Length() - 1; nLength >= 0; nLength-- ) + if ( !m_pString ) { - m_Storage[ nLength ] = tolower( m_Storage[ nLength ] ); + return; } -} + V_strlower( m_pString ); +} void CUtlString::ToUpper() { - for( int nLength = Length() - 1; nLength >= 0; nLength-- ) + if ( !m_pString ) { - m_Storage[ nLength ] = toupper( m_Storage[ nLength ] ); + return; } -} + V_strupr( m_pString ); +} CUtlString &CUtlString::operator=( const CUtlString &src ) { - Assert( !m_Storage.IsReadOnly() ); - m_Storage = src.m_Storage; + SetDirect( src.Get(), src.Length() ); return *this; } CUtlString &CUtlString::operator=( const char *src ) { - Assert( !m_Storage.IsReadOnly() ); Set( src ); return *this; } bool CUtlString::operator==( const CUtlString &src ) const { - return m_Storage == src.m_Storage; -} + if ( IsEmpty() ) + { + if ( src.IsEmpty() ) + { + return true; + } -bool CUtlString::operator==( const char *src ) const -{ - return ( strcmp( Get(), src ) == 0 ); + return false; + } + else + { + if ( src.IsEmpty() ) + { + return false; + } + + return Q_strcmp( m_pString, src.m_pString ) == 0; + } } CUtlString &CUtlString::operator+=( const CUtlString &rhs ) { - Assert( !m_Storage.IsReadOnly() ); - const int lhsLength( Length() ); const int rhsLength( rhs.Length() ); + + if (!rhsLength) + { + return *this; + } + const int requestedLength( lhsLength + rhsLength ); - SetLength( requestedLength ); - const int allocatedLength( Length() ); - const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); - memcpy( Get() + lhsLength, rhs.Get(), copyLength ); - m_Storage[ allocatedLength ] = '\0'; + AllocMemory( requestedLength ); + Q_memcpy( m_pString + lhsLength, rhs.m_pString, rhsLength ); return *this; } CUtlString &CUtlString::operator+=( const char *rhs ) { - Assert( !m_Storage.IsReadOnly() ); - const int lhsLength( Length() ); - const int rhsLength( Q_strlen( rhs ) ); + const int rhsLength( V_strlen( rhs ) ); const int requestedLength( lhsLength + rhsLength ); - SetLength( requestedLength ); - const int allocatedLength( Length() ); - const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); - memcpy( Get() + lhsLength, rhs, copyLength ); - m_Storage[ allocatedLength ] = '\0'; + if (!requestedLength) + { + return *this; + } + + AllocMemory( requestedLength ); + Q_memcpy( m_pString + lhsLength, rhs, rhsLength ); return *this; } CUtlString &CUtlString::operator+=( char c ) { - Assert( !m_Storage.IsReadOnly() ); + const int lhsLength( Length() ); + + AllocMemory( lhsLength + 1 ); + m_pString[ lhsLength ] = c; - int nLength = Length(); - SetLength( nLength + 1 ); - m_Storage[ nLength ] = c; - m_Storage[ nLength+1 ] = '\0'; return *this; } CUtlString &CUtlString::operator+=( int rhs ) { - Assert( !m_Storage.IsReadOnly() ); Assert( sizeof( rhs ) == 4 ); char tmpBuf[ 12 ]; // Sufficient for a signed 32 bit integer [ -2147483648 to +2147483647 ] - Q_snprintf( tmpBuf, sizeof( tmpBuf ), "%d", rhs ); + V_snprintf( tmpBuf, sizeof( tmpBuf ), "%d", rhs ); tmpBuf[ sizeof( tmpBuf ) - 1 ] = '\0'; return operator+=( tmpBuf ); @@ -324,16 +271,14 @@ CUtlString &CUtlString::operator+=( int rhs ) CUtlString &CUtlString::operator+=( double rhs ) { - Assert( !m_Storage.IsReadOnly() ); - char tmpBuf[ 256 ]; // How big can doubles be??? Dunno. - Q_snprintf( tmpBuf, sizeof( tmpBuf ), "%lg", rhs ); + V_snprintf( tmpBuf, sizeof( tmpBuf ), "%lg", rhs ); tmpBuf[ sizeof( tmpBuf ) - 1 ] = '\0'; return operator+=( tmpBuf ); } -bool CUtlString::MatchesPattern( const CUtlString &Pattern, int nFlags ) +bool CUtlString::MatchesPattern( const CUtlString &Pattern, int nFlags ) const { const char *pszSource = String(); const char *pszPattern = Pattern.String(); @@ -413,31 +358,27 @@ bool CUtlString::MatchesPattern( const CUtlString &Pattern, int nFlags ) int CUtlString::Format( const char *pFormat, ... ) { - Assert( !m_Storage.IsReadOnly() ); - - char tmpBuf[ 4096 ]; //< Nice big 4k buffer, as much memory as my first computer had, a Radio Shack Color Computer - va_list marker; va_start( marker, pFormat ); -#ifdef _WIN32 - int len = _vsnprintf( tmpBuf, sizeof( tmpBuf ) - 1, pFormat, marker ); -#elif POSIX - int len = vsnprintf( tmpBuf, sizeof( tmpBuf ) - 1, pFormat, marker ); -#else -#error "define vsnprintf type." -#endif + int len = FormatV( pFormat, marker ); va_end( marker ); - // Len > maxLen represents an overflow on POSIX, < 0 is an overflow on windows - if( len < 0 || len >= sizeof( tmpBuf ) - 1 ) - { - len = sizeof( tmpBuf ) - 1; - tmpBuf[sizeof( tmpBuf ) - 1] = 0; - } + return len; +} +//-------------------------------------------------------------------------------------------------- +// This can be called from functions that take varargs. +//-------------------------------------------------------------------------------------------------- + +int CUtlString::FormatV( const char *pFormat, va_list marker ) +{ + char tmpBuf[ 4096 ]; //< Nice big 4k buffer, as much memory as my first computer had, a Radio Shack Color Computer + + //va_start( marker, pFormat ); + int len = V_vsprintf_safe( tmpBuf, pFormat, marker ); + //va_end( marker ); Set( tmpBuf ); - return len; } @@ -450,88 +391,322 @@ void CUtlString::StripTrailingSlash() return; int nLastChar = Length() - 1; - char c = m_Storage[ nLastChar ]; + char c = m_pString[ nLastChar ]; if ( c == '\\' || c == '/' ) { - m_Storage[ nLastChar ] = 0; - m_Storage.SetLength( m_Storage.Length() - 1 ); + SetLength( nLastChar ); } } -CUtlString CUtlString::Slice( int32 nStart, int32 nEnd ) +void CUtlString::FixSlashes( char cSeparator/*=CORRECT_PATH_SEPARATOR*/ ) { - if ( nStart < 0 ) - nStart = Length() - (-nStart % Length()); - else if ( nStart >= Length() ) - nStart = Length(); + if ( m_pString ) + { + V_FixSlashes( m_pString, cSeparator ); + } +} - if ( nEnd == 0x7FFFFFFF ) - nEnd = Length(); +//----------------------------------------------------------------------------- +// Trim functions +//----------------------------------------------------------------------------- +void CUtlString::TrimLeft( char cTarget ) +{ + int nIndex = 0; + + if ( IsEmpty() ) + { + return; + } + + while( m_pString[nIndex] == cTarget ) + { + ++nIndex; + } + + // We have some whitespace to remove + if ( nIndex > 0 ) + { + memcpy( m_pString, &m_pString[nIndex], Length() - nIndex ); + SetLength( Length() - nIndex ); + } +} + + +void CUtlString::TrimLeft( const char *szTargets ) +{ + int i; + + if ( IsEmpty() ) + { + return; + } + + for( i = 0; m_pString[i] != 0; i++ ) + { + bool bWhitespace = false; + + for( int j = 0; szTargets[j] != 0; j++ ) + { + if ( m_pString[i] == szTargets[j] ) + { + bWhitespace = true; + break; + } + } + + if ( !bWhitespace ) + { + break; + } + } + + // We have some whitespace to remove + if ( i > 0 ) + { + memcpy( m_pString, &m_pString[i], Length() - i ); + SetLength( Length() - i ); + } +} + + +void CUtlString::TrimRight( char cTarget ) +{ + const int nLastCharIndex = Length() - 1; + int nIndex = nLastCharIndex; + + while ( nIndex >= 0 && m_pString[nIndex] == cTarget ) + { + --nIndex; + } + + // We have some whitespace to remove + if ( nIndex < nLastCharIndex ) + { + m_pString[nIndex + 1] = 0; + SetLength( nIndex + 2 ); + } +} + + +void CUtlString::TrimRight( const char *szTargets ) +{ + const int nLastCharIndex = Length() - 1; + int i; + + for( i = nLastCharIndex; i > 0; i-- ) + { + bool bWhitespace = false; + + for( int j = 0; szTargets[j] != 0; j++ ) + { + if ( m_pString[i] == szTargets[j] ) + { + bWhitespace = true; + break; + } + } + + if ( !bWhitespace ) + { + break; + } + } + + // We have some whitespace to remove + if ( i < nLastCharIndex ) + { + m_pString[i + 1] = 0; + SetLength( i + 2 ); + } +} + + +void CUtlString::Trim( char cTarget ) +{ + TrimLeft( cTarget ); + TrimRight( cTarget ); +} + + +void CUtlString::Trim( const char *szTargets ) +{ + TrimLeft( szTargets ); + TrimRight( szTargets ); +} + + +CUtlString CUtlString::Slice( int32 nStart, int32 nEnd ) const +{ + int length = Length(); + if ( length == 0 ) + { + return CUtlString(); + } + + if ( nStart < 0 ) + nStart = length - (-nStart % length); + else if ( nStart >= length ) + nStart = length; + + if ( nEnd == INT32_MAX ) + nEnd = length; else if ( nEnd < 0 ) - nEnd = Length() - (-nEnd % Length()); - else if ( nEnd >= Length() ) - nEnd = Length(); + nEnd = length - (-nEnd % length); + else if ( nEnd >= length ) + nEnd = length; if ( nStart >= nEnd ) - return CUtlString( "" ); + return CUtlString(); const char *pIn = String(); CUtlString ret; - ret.m_Storage.SetLength( nEnd - nStart + 1 ); - char *pOut = (char*)ret.m_Storage.Get(); - - memcpy( ret.m_Storage.Get(), &pIn[nStart], nEnd - nStart ); - pOut[nEnd - nStart] = 0; - + ret.SetDirect( pIn + nStart, nEnd - nStart ); return ret; } // Grab a substring starting from the left or the right side. -CUtlString CUtlString::Left( int32 nChars ) +CUtlString CUtlString::Left( int32 nChars ) const { return Slice( 0, nChars ); } -CUtlString CUtlString::Right( int32 nChars ) +CUtlString CUtlString::Right( int32 nChars ) const { return Slice( -nChars ); } -CUtlString CUtlString::Replace( char cFrom, char cTo ) +CUtlString CUtlString::Replace( char cFrom, char cTo ) const { + if (!m_pString) + { + return CUtlString(); + } + CUtlString ret = *this; int len = ret.Length(); for ( int i=0; i < len; i++ ) { - if ( ret.m_Storage[i] == cFrom ) - ret.m_Storage[i] = cTo; + if ( ret.m_pString[i] == cFrom ) + ret.m_pString[i] = cTo; } return ret; } -CUtlString CUtlString::AbsPath( const char *pStartingDir ) +CUtlString CUtlString::Replace( const char *pszFrom, const char *pszTo ) const +{ + Assert( pszTo ); // Can be 0 length, but not null + Assert( pszFrom && *pszFrom ); // Must be valid and have one character. + + + const char *pos = V_strstr( String(), pszFrom ); + if ( !pos ) + { + return *this; + } + + const char *pFirstFound = pos; + + // count number of search string + int nSearchCount = 0; + int nSearchLength = V_strlen( pszFrom ); + while ( pos ) + { + nSearchCount++; + int nSrcOffset = ( pos - String() ) + nSearchLength; + pos = V_strstr( String() + nSrcOffset, pszFrom ); + } + + // allocate the new string + int nReplaceLength = V_strlen( pszTo ); + int nAllocOffset = nSearchCount * ( nReplaceLength - nSearchLength ); + size_t srcLength = Length(); + CUtlString strDest; + size_t destLength = srcLength + nAllocOffset; + strDest.SetLength( destLength ); + + // find and replace the search string + pos = pFirstFound; + int nDestOffset = 0; + int nSrcOffset = 0; + while ( pos ) + { + // Found an instance + int nCurrentSearchOffset = pos - String(); + int nCopyLength = nCurrentSearchOffset - nSrcOffset; + V_strncpy( strDest.GetForModify() + nDestOffset, String() + nSrcOffset, nCopyLength + 1 ); + nDestOffset += nCopyLength; + V_strncpy( strDest.GetForModify() + nDestOffset, pszTo, nReplaceLength + 1 ); + nDestOffset += nReplaceLength; + + nSrcOffset = nCurrentSearchOffset + nSearchLength; + pos = V_strstr( String() + nSrcOffset, pszFrom ); + } + + // making sure that the left over string from the source is the same size as the left over dest buffer + Assert( destLength - nDestOffset == srcLength - nSrcOffset ); + if ( destLength - nDestOffset > 0 ) + { + V_strncpy( strDest.GetForModify() + nDestOffset, String() + nSrcOffset, destLength - nDestOffset + 1 ); + } + + return strDest; +} + +CUtlString CUtlString::AbsPath( const char *pStartingDir ) const { char szNew[MAX_PATH]; V_MakeAbsolutePath( szNew, sizeof( szNew ), this->String(), pStartingDir ); return CUtlString( szNew ); } -CUtlString CUtlString::UnqualifiedFilename() +CUtlString CUtlString::UnqualifiedFilename() const { const char *pFilename = V_UnqualifiedFileName( this->String() ); return CUtlString( pFilename ); } -CUtlString CUtlString::DirName() +CUtlString CUtlString::DirName() const { CUtlString ret( this->String() ); - V_StripLastDir( (char*)ret.m_Storage.Get(), ret.m_Storage.Length() ); - V_StripTrailingSlash( (char*)ret.m_Storage.Get() ); + V_StripLastDir( (char*)ret.Get(), ret.Length() + 1 ); + V_StripTrailingSlash( (char*)ret.Get() ); return ret; } +CUtlString CUtlString::StripExtension() const +{ + char szTemp[MAX_PATH]; + V_StripExtension( String(), szTemp, sizeof( szTemp ) ); + return CUtlString( szTemp ); +} + +CUtlString CUtlString::StripFilename() const +{ + const char *pFilename = V_UnqualifiedFileName( Get() ); // NOTE: returns 'Get()' on failure, never NULL + int nCharsToCopy = pFilename - Get(); + CUtlString result; + result.SetDirect( Get(), nCharsToCopy ); + result.StripTrailingSlash(); + return result; +} + +CUtlString CUtlString::GetBaseFilename() const +{ + char szTemp[MAX_PATH]; + V_FileBase( String(), szTemp, sizeof( szTemp ) ); + return CUtlString( szTemp ); +} + +CUtlString CUtlString::GetExtension() const +{ + char szTemp[MAX_PATH]; + V_ExtractFileExtension( String(), szTemp, sizeof( szTemp ) ); + return CUtlString( szTemp ); +} + + CUtlString CUtlString::PathJoin( const char *pStr1, const char *pStr2 ) { char szPath[MAX_PATH]; @@ -539,10 +714,54 @@ CUtlString CUtlString::PathJoin( const char *pStr1, const char *pStr2 ) return CUtlString( szPath ); } +CUtlString CUtlString::operator+( const char *pOther ) const +{ + CUtlString s = *this; + s += pOther; + return s; +} + +CUtlString CUtlString::operator+( const CUtlString &other ) const +{ + CUtlString s = *this; + s += other; + return s; +} + +CUtlString CUtlString::operator+( int rhs ) const +{ + CUtlString ret = *this; + ret += rhs; + return ret; +} + //----------------------------------------------------------------------------- // Purpose: concatenate the provided string to our current content //----------------------------------------------------------------------------- void CUtlString::Append( const char *pchAddition ) { - *this += pchAddition; + (*this) += pchAddition; +} + +void CUtlString::Append( const char *pchAddition, int nChars ) +{ + nChars = Min( nChars, V_strlen( pchAddition ) ); + + const int lhsLength( Length() ); + const int rhsLength( nChars ); + const int requestedLength( lhsLength + rhsLength ); + + AllocMemory( requestedLength ); + const int allocatedLength( requestedLength ); + const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); + memcpy( GetForModify() + lhsLength, pchAddition, copyLength ); + m_pString[ allocatedLength ] = '\0'; +} + +// Shared static empty string. +const CUtlString &CUtlString::GetEmptyString() +{ + static const CUtlString s_emptyString; + + return s_emptyString; } diff --git a/tier1/utlsymbol.cpp b/tier1/utlsymbol.cpp index d759f1eb..7d862b85 100644 --- a/tier1/utlsymbol.cpp +++ b/tier1/utlsymbol.cpp @@ -227,7 +227,7 @@ CUtlSymbol CUtlSymbolTable::AddString( const char* pString ) if (id.IsValid()) return id; - int len = strlen(pString) + 1; + int len = V_strlen(pString) + 1; // Find a pool with space for this string, or allocate a new one. int iPool = FindPoolWithSpace( len ); diff --git a/utils/captioncompiler/captioncompiler.cpp b/utils/captioncompiler/captioncompiler.cpp index 44e1578f..c9c6c6da 100644 --- a/utils/captioncompiler/captioncompiler.cpp +++ b/utils/captioncompiler/captioncompiler.cpp @@ -91,7 +91,7 @@ void vprint( int depth, const char *fmt, ... ) } } - ::printf( string ); + ::printf( "%s", string ); OutputDebugString( string ); if ( fp ) diff --git a/utils/glview/glview.vpc b/utils/glview/glview.vpc index 3045d128..1ee021a8 100644 --- a/utils/glview/glview.vpc +++ b/utils/glview/glview.vpc @@ -20,7 +20,6 @@ $Configuration $Linker { $AdditionalDependencies "$BASE glu32.lib opengl32.lib odbc32.lib odbccp32.lib winmm.lib" - $AdditionalDependencies "$BASE glaux.lib" [!$VS2010] } } diff --git a/utils/vbsp/staticprop.cpp b/utils/vbsp/staticprop.cpp index 810465b3..830c0e10 100644 --- a/utils/vbsp/staticprop.cpp +++ b/utils/vbsp/staticprop.cpp @@ -54,6 +54,8 @@ struct StaticPropBuild_t float m_flForcedFadeScale; unsigned short m_nMinDXLevel; unsigned short m_nMaxDXLevel; + int m_LightmapResolutionX; + int m_LightmapResolutionY; }; @@ -516,6 +518,9 @@ static void AddStaticPropToLump( StaticPropBuild_t const& build ) } } + propLump.m_nLightmapResolutionX = build.m_LightmapResolutionX; + propLump.m_nLightmapResolutionY = build.m_LightmapResolutionY; + // Add the leaves to the leaf lump for (int j = 0; j < leafList.Size(); ++j) { @@ -523,6 +528,7 @@ static void AddStaticPropToLump( StaticPropBuild_t const& build ) insert.m_Leaf = leafList[j]; s_StaticPropLeafLump.AddToTail( insert ); } + } @@ -619,6 +625,18 @@ void EmitStaticProps() build.m_Flags |= STATIC_PROP_SCREEN_SPACE_FADE; } + if (IntForKey( &entities[i], "generatelightmaps") == 0) + { + build.m_Flags |= STATIC_PROP_NO_PER_TEXEL_LIGHTING; + build.m_LightmapResolutionX = 0; + build.m_LightmapResolutionY = 0; + } + else + { + build.m_LightmapResolutionX = IntForKey( &entities[i], "lightmapresolutionx" ); + build.m_LightmapResolutionY = IntForKey( &entities[i], "lightmapresolutiony" ); + } + const char *pKey = ValueForKey( &entities[i], "fadescale" ); if ( pKey && pKey[0] ) { diff --git a/utils/vice/vice.cpp b/utils/vice/vice.cpp index 0ed9c32e..cf7f236a 100644 --- a/utils/vice/vice.cpp +++ b/utils/vice/vice.cpp @@ -49,7 +49,7 @@ static void Pause( void ) static void Exit(const char *msg) { - fprintf( stderr, msg ); + fprintf( stderr, "%s", msg ); Pause(); exit( -1 ); } diff --git a/utils/vrad/disp_vrad.cpp b/utils/vrad/disp_vrad.cpp index e1ef3a2e..a0dde329 100644 --- a/utils/vrad/disp_vrad.cpp +++ b/utils/vrad/disp_vrad.cpp @@ -46,7 +46,7 @@ int FindNeighborCornerVert( CCoreDispInfo *pDisp, const Vector &vTest ) } -int GetAllNeighbors( const CCoreDispInfo *pDisp, int iNeighbors[512] ) +int GetAllNeighbors( const CCoreDispInfo *pDisp, int (&iNeighbors)[512] ) { int nNeighbors = 0; @@ -57,7 +57,7 @@ int GetAllNeighbors( const CCoreDispInfo *pDisp, int iNeighbors[512] ) for ( int i=0; i < pCorner->m_nNeighbors; i++ ) { - if ( nNeighbors < _ARRAYSIZE( iNeighbors ) ) + if ( nNeighbors < ARRAYSIZE( iNeighbors ) ) iNeighbors[nNeighbors++] = pCorner->m_Neighbors[i]; } } diff --git a/utils/vrad/lightmap.cpp b/utils/vrad/lightmap.cpp index bc3d254e..71fc34e7 100644 --- a/utils/vrad/lightmap.cpp +++ b/utils/vrad/lightmap.cpp @@ -3548,30 +3548,51 @@ static void LinearToBumpedLightmap( // Convert a RGBExp32 to a RGBA8888 // This matches the engine's conversion, so the lighting result is consistent. //----------------------------------------------------------------------------- -void ConvertRGBExp32ToRGBA8888( const ColorRGBExp32 *pSrc, unsigned char *pDst ) +void ConvertRGBExp32ToRGBA8888( const ColorRGBExp32 *pSrc, unsigned char *pDst, Vector* _optOutLinear ) { Vector linearColor; - Vector vertexColor; // convert from ColorRGBExp32 to linear space linearColor[0] = TexLightToLinear( ((ColorRGBExp32 *)pSrc)->r, ((ColorRGBExp32 *)pSrc)->exponent ); linearColor[1] = TexLightToLinear( ((ColorRGBExp32 *)pSrc)->g, ((ColorRGBExp32 *)pSrc)->exponent ); linearColor[2] = TexLightToLinear( ((ColorRGBExp32 *)pSrc)->b, ((ColorRGBExp32 *)pSrc)->exponent ); + ConvertLinearToRGBA8888( &linearColor, pDst ); + if ( _optOutLinear ) + *_optOutLinear = linearColor; +} + +//----------------------------------------------------------------------------- +// Converts a RGBExp32 to a linear color value. +//----------------------------------------------------------------------------- +void ConvertRGBExp32ToLinear(const ColorRGBExp32 *pSrc, Vector* pDst) +{ + + (*pDst)[0] = TexLightToLinear(((ColorRGBExp32 *)pSrc)->r, ((ColorRGBExp32 *)pSrc)->exponent); + (*pDst)[1] = TexLightToLinear(((ColorRGBExp32 *)pSrc)->g, ((ColorRGBExp32 *)pSrc)->exponent); + (*pDst)[2] = TexLightToLinear(((ColorRGBExp32 *)pSrc)->b, ((ColorRGBExp32 *)pSrc)->exponent); +} + +//----------------------------------------------------------------------------- +// Converts a linear color value (suitable for combining linearly) to an RBGA8888 value expected by the engine. +//----------------------------------------------------------------------------- +void ConvertLinearToRGBA8888(const Vector *pSrcLinear, unsigned char *pDst) +{ + Vector vertexColor; + // convert from linear space to lightmap space // cannot use mathlib routine directly because it doesn't match // the colorspace version found in the engine, which *is* the same sequence here - vertexColor[0] = LinearToVertexLight( linearColor[0] ); - vertexColor[1] = LinearToVertexLight( linearColor[1] ); - vertexColor[2] = LinearToVertexLight( linearColor[2] ); + vertexColor[0] = LinearToVertexLight((*pSrcLinear)[0]); + vertexColor[1] = LinearToVertexLight((*pSrcLinear)[1]); + vertexColor[2] = LinearToVertexLight((*pSrcLinear)[2]); // this is really a color normalization with a floor - ColorClamp( vertexColor ); + ColorClamp(vertexColor); // final [0..255] scale - pDst[0] = RoundFloatToByte( vertexColor[0] * 255.0f ); - pDst[1] = RoundFloatToByte( vertexColor[1] * 255.0f ); - pDst[2] = RoundFloatToByte( vertexColor[2] * 255.0f ); + pDst[0] = RoundFloatToByte(vertexColor[0] * 255.0f); + pDst[1] = RoundFloatToByte(vertexColor[1] * 255.0f); + pDst[2] = RoundFloatToByte(vertexColor[2] * 255.0f); pDst[3] = 255; } - diff --git a/utils/vrad/vrad.cpp b/utils/vrad/vrad.cpp index 8100dc3f..7d4a1ca4 100644 --- a/utils/vrad/vrad.cpp +++ b/utils/vrad/vrad.cpp @@ -34,7 +34,7 @@ every surface must be divided into at least two patches each axis */ CUtlVector g_Patches; -CUtlVector g_FacePatches; // constains all patches, children first +CUtlVector g_FacePatches; // contains all patches, children first CUtlVector faceParents; // contains only root patches, use next parent to iterate CUtlVector clusterChildren; CUtlVector emitlight; @@ -60,6 +60,8 @@ bool g_bDumpRtEnv = false; bool bRed2Black = true; bool g_bFastAmbient = false; bool g_bNoSkyRecurse = false; +bool g_bDumpPropLightmaps = false; + int junk; @@ -2404,16 +2406,21 @@ int ParseCommandLine( int argc, char **argv, bool *onlydetail ) { g_bLargeDispSampleRadius = true; } + else if (!Q_stricmp( argv[i], "-dumppropmaps")) + { + g_bDumpPropLightmaps = true; + } else if (!Q_stricmp(argv[i],"-bounce")) { if ( ++i < argc ) { - numbounce = atoi (argv[i]); - if ( numbounce < 0 ) + int bounceParam = atoi (argv[i]); + if ( bounceParam < 0 ) { Warning("Error: expected non-negative value after '-bounce'\n" ); return 1; } + numbounce = (unsigned)bounceParam; } else { diff --git a/utils/vrad/vrad.h b/utils/vrad/vrad.h index 4a37f179..ba7ea2e0 100644 --- a/utils/vrad/vrad.h +++ b/utils/vrad/vrad.h @@ -285,6 +285,7 @@ extern qboolean g_bLowPriority; extern qboolean do_fast; extern bool g_bInterrupt; // Was used with background lighting in WC. Tells VRAD to stop lighting. extern IIncremental *g_pIncremental; // null if not doing incremental lighting +extern bool g_bDumpPropLightmaps; extern float g_flSkySampleScale; // extra sampling factor for indirect light @@ -367,7 +368,10 @@ void BuildFacelights (int facenum, int threadnum); void PrecompLightmapOffsets(); void FinalLightFace (int threadnum, int facenum); void PvsForOrigin (Vector& org, byte *pvs); -void ConvertRGBExp32ToRGBA8888( const ColorRGBExp32 *pSrc, unsigned char *pDst ); +void ConvertRGBExp32ToRGBA8888( const ColorRGBExp32 *pSrc, unsigned char *pDst, Vector* _optOutLinear = NULL ); +void ConvertRGBExp32ToLinear(const ColorRGBExp32 *pSrc, Vector* pDst); +void ConvertLinearToRGBA8888( const Vector *pSrc, unsigned char *pDst ); + inline byte PVSCheck( const byte *pvs, int iCluster ) { diff --git a/utils/vrad/vraddetailprops.cpp b/utils/vrad/vraddetailprops.cpp index 822bc78c..8cd3dc8b 100644 --- a/utils/vrad/vraddetailprops.cpp +++ b/utils/vrad/vraddetailprops.cpp @@ -738,7 +738,9 @@ void ComputeIndirectLightingAtPoint( Vector &position, Vector &normal, Vector &o ColorRGBExp32ToVector( *pLightmap, lightmapColor ); } - VectorMultiply( lightmapColor, dtexdata[pTex->texdata].reflectivity, lightmapColor ); + float invLengthSqr = 1.0f / (1.0f + ((vEnd - position) * surfEnum.m_HitFrac / 128.0).LengthSqr()); + // Include falloff using invsqrlaw. + VectorMultiply( lightmapColor, invLengthSqr * dtexdata[pTex->texdata].reflectivity, lightmapColor ); VectorAdd( outColor, lightmapColor, outColor ); } diff --git a/utils/vrad/vradstaticprops.cpp b/utils/vrad/vradstaticprops.cpp index f240d94f..fcfe9178 100644 --- a/utils/vrad/vradstaticprops.cpp +++ b/utils/vrad/vradstaticprops.cpp @@ -27,11 +27,13 @@ #include "pacifier.h" #include "materialsystem/imaterial.h" #include "materialsystem/hardwareverts.h" +#include "materialsystem/hardwaretexels.h" #include "byteswap.h" #include "mpivrad.h" #include "vtf/vtf.h" #include "tier1/utldict.h" #include "tier1/utlsymbol.h" +#include "bitmap/tgawriter.h" #include "messbuf.h" #include "vmpi.h" @@ -57,17 +59,166 @@ struct colorVertex_t bool m_bValid; }; +// a texel suitable for a model +struct colorTexel_t +{ + Vector m_Color; + Vector m_WorldPosition; + Vector m_WorldNormal; + float m_fDistanceToTri; // If we are outside of the triangle, how far away is it? + bool m_bValid; + bool m_bPossiblyInteresting; + +}; + class CComputeStaticPropLightingResults { public: ~CComputeStaticPropLightingResults() { m_ColorVertsArrays.PurgeAndDeleteElements(); + m_ColorTexelsArrays.PurgeAndDeleteElements(); } CUtlVector< CUtlVector* > m_ColorVertsArrays; + CUtlVector< CUtlVector* > m_ColorTexelsArrays; }; +//----------------------------------------------------------------------------- +struct Rasterizer +{ + struct Location + { + Vector barycentric; + Vector2D uv; + bool insideTriangle; + }; + + Rasterizer(Vector2D t0, Vector2D t1, Vector2D t2, size_t resX, size_t resY) + : mT0(t0) + , mT1(t1) + , mT2(t2) + , mResX(resX) + , mResY(resY) + , mUvStepX(1.0f / resX) + , mUvStepY(1.0f / resY) + { + Build(); + } + + CUtlVector< Location >::iterator begin() { return mRasterizedLocations.begin(); } + CUtlVector< Location >::iterator end() { return mRasterizedLocations.end(); } + + void Build(); + + inline size_t GetRow(float y) const { return size_t(y * mResY); } + inline size_t GetCol(float x) const { return size_t(x * mResX); } + + inline size_t GetLinearPos( const CUtlVector< Location >::iterator& it ) const + { + // Given an iterator, return what the linear position in the buffer would be for the data. + return (size_t)(GetRow(it->uv.y) * mResX) + + (size_t)(GetCol(it->uv.x)); + } + +private: + const Vector2D mT0, mT1, mT2; + const size_t mResX, mResY; + const float mUvStepX, mUvStepY; + + // Right now, we just fill this out and directly iterate over it. + // It could be large. This is a memory/speed tradeoff. We could instead generate them + // on demand. + CUtlVector< Location > mRasterizedLocations; +}; + +//----------------------------------------------------------------------------- +inline Vector ComputeBarycentric( Vector2D _edgeC, Vector2D _edgeA, Vector2D _edgeB, float _dAA, float _dAB, float _dBB, float _invDenom ) +{ + float dCA = _edgeC.Dot(_edgeA); + float dCB = _edgeC.Dot(_edgeB); + + Vector retVal; + retVal.y = (_dBB * dCA - _dAB * dCB) * _invDenom; + retVal.z = (_dAA * dCB - _dAB * dCA) * _invDenom; + retVal.x = 1.0f - retVal.y - retVal.z; + + return retVal; +} + +//----------------------------------------------------------------------------- +void Rasterizer::Build() +{ + // For now, use the barycentric method. It's easy, I'm lazy. + // We can optimize later if it's a performance issue. + const float baseX = mUvStepX / 2.0f; + const float baseY = mUvStepY / 2.0f; + + + float fMinX = min(min(mT0.x, mT1.x), mT2.x); + float fMinY = min(min(mT0.y, mT1.y), mT2.y); + float fMaxX = max(max(mT0.x, mT1.x), mT2.x); + float fMaxY = max(max(mT0.y, mT1.y), mT2.y); + + // Degenerate. Consider warning about these, but otherwise no problem. + if (fMinX == fMaxX || fMinY == fMaxY) + return; + + // Clamp to 0..1 + fMinX = max(0, fMinX); + fMinY = max(0, fMinY); + fMaxX = min(1.0f, fMaxX); + fMaxY = min(1.0f, fMaxY); + + // We puff the interesting area up by 1 so we can hit an inflated region for the necessary bilerp data. + // If we wanted to support better texturing (almost definitely unnecessary), we'd change this to a larger size. + const int kFilterSampleRadius = 1; + + int iMinX = GetCol(fMinX) - kFilterSampleRadius; + int iMinY = GetRow(fMinY) - kFilterSampleRadius; + int iMaxX = GetCol(fMaxX) + 1 + kFilterSampleRadius; + int iMaxY = GetRow(fMaxY) + 1 + kFilterSampleRadius; + + // Clamp to valid texture (integer) locations + iMinX = max(0, iMinX); + iMinY = max(0, iMinY); + iMaxX = min(iMaxX, mResX - 1); + iMaxY = min(iMaxY, mResY - 1); + + // Set the size to be as expected. + // TODO: Pass this in from outside to minimize allocations + int count = (iMaxY - iMinY + 1) + * (iMaxX - iMinX + 1); + mRasterizedLocations.EnsureCount(count); + memset( mRasterizedLocations.Base(), 0, mRasterizedLocations.Count() * sizeof( Location ) ); + + // Computing Barycentrics adapted from here http://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates + Vector2D edgeA = mT1 - mT0; + Vector2D edgeB = mT2 - mT0; + + float dAA = edgeA.Dot(edgeA); + float dAB = edgeA.Dot(edgeB); + float dBB = edgeB.Dot(edgeB); + float invDenom = 1.0f / (dAA * dBB - dAB * dAB); + + int linearPos = 0; + for (int j = iMinY; j <= iMaxY; ++j) { + for (int i = iMinX; i <= iMaxX; ++i) { + Vector2D testPt( i * mUvStepX + baseX, j * mUvStepY + baseY ); + Vector barycentric = ComputeBarycentric( testPt - mT0, edgeA, edgeB, dAA, dAB, dBB, invDenom ); + + // Test whether the point is inside the triangle. + // MCJOHNTODO: Edge rules and whatnot--right now we re-rasterize points on the edge. + Location& newLoc = mRasterizedLocations[linearPos++]; + newLoc.barycentric = barycentric; + newLoc.uv = testPt; + + newLoc.insideTriangle = (barycentric.x >= 0.0f && barycentric.x <= 1.0f && barycentric.y >= 0.0f && barycentric.y <= 1.0f && barycentric.z >= 0.0f && barycentric.z <= 1.0f); + } + } +} + + //----------------------------------------------------------------------------- // Globals //----------------------------------------------------------------------------- @@ -77,6 +228,18 @@ CUtlSymbolTable g_ForcedTextureShadowsModels; // INSIDE PropTested_t. USE THAT INSTEAD. IPhysicsCollision *s_pPhysCollision = NULL; +static void ConvertTexelDataToTexture(unsigned int _resX, unsigned int _resY, ImageFormat _destFmt, const CUtlVector& _srcTexels, CUtlMemory* _outTexture); + +// Such a monstrosity. :( +static void GenerateLightmapSamplesForMesh( const matrix3x4_t& _matPos, const matrix3x4_t& _matNormal, int _iThread, int _skipProp, int _nFlags, int _lightmapResX, int _lightmapResY, + studiohdr_t* _pStudioHdr, mstudiomodel_t* _pStudioModel, OptimizedModel::ModelHeader_t* _pVtxModel, int _meshID, + CComputeStaticPropLightingResults *_pResults ); + +// Debug function, converts lightmaps to linear space then dumps them out. +// TODO: Write out the file in a .dds instead of a .tga, in whatever format we're supposed to use. +static void DumpLightmapLinear( const char* _dstFilename, const CUtlVector& _srcTexels, int _width, int _height ); + + //----------------------------------------------------------------------------- // Vrad's static prop manager //----------------------------------------------------------------------------- @@ -130,7 +293,8 @@ private: struct MeshData_t { - CUtlVector m_Verts; + CUtlVector m_VertexColors; + CUtlMemory m_TexelsEncoded; int m_nLod; }; @@ -147,6 +311,15 @@ private: CUtlVector m_MeshData; int m_Flags; bool m_bLightingOriginValid; + + // Note that all lightmaps for a given prop share the same resolution (and format)--and there can be multiple lightmaps + // per prop (if there are multiple pieces--the watercooler is an example). + // This is effectively because there's not a good way in hammer for a prop to say "this should be the resolution + // of each of my sub-pieces." + ImageFormat m_LightmapImageFormat; + unsigned int m_LightmapImageWidth; + unsigned int m_LightmapImageHeight; + }; // Enumeration context @@ -163,7 +336,7 @@ private: bool m_bIgnoreStaticPropTrace; void ComputeLighting( CStaticProp &prop, int iThread, int prop_index, CComputeStaticPropLightingResults *pResults ); - void ApplyLightingToStaticProp( CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ); + void ApplyLightingToStaticProp( int iStaticProp, CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ); void SerializeLighting(); void AddPolysForRayTrace(); @@ -854,6 +1027,7 @@ void CVradStaticPropMgr::UnserializeModels( CUtlBuffer& buf ) { int count = buf.GetInt(); + m_StaticProps.AddMultipleToTail(count); for ( int i = 0; i < count; ++i ) { @@ -867,6 +1041,12 @@ void CVradStaticPropMgr::UnserializeModels( CUtlBuffer& buf ) m_StaticProps[i].m_ModelIdx = lump.m_PropType; m_StaticProps[i].m_Handle = TREEDATA_INVALID_HANDLE; m_StaticProps[i].m_Flags = lump.m_Flags; + + // Changed this from using DXT1 to RGB888 because the compression artifacts were pretty nasty. + // TODO: Consider changing back or basing this on user selection in hammer. + m_StaticProps[i].m_LightmapImageFormat = IMAGE_FORMAT_RGB888; + m_StaticProps[i].m_LightmapImageWidth = lump.m_nLightmapResolutionX; + m_StaticProps[i].m_LightmapImageHeight = lump.m_nLightmapResolutionY; } } @@ -1028,9 +1208,9 @@ void ComputeDirectLightingAtPoint( Vector &position, Vector &normal, Vector &out //----------------------------------------------------------------------------- // Takes the results from a ComputeLighting call and applies it to the static prop in question. //----------------------------------------------------------------------------- -void CVradStaticPropMgr::ApplyLightingToStaticProp( CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ) +void CVradStaticPropMgr::ApplyLightingToStaticProp( int iStaticProp, CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ) { - if ( pResults->m_ColorVertsArrays.Count() == 0 ) + if ( pResults->m_ColorVertsArrays.Count() == 0 && pResults->m_ColorTexelsArrays.Count() == 0 ) return; StaticPropDict_t &dict = m_StaticPropDict[prop.m_ModelIdx]; @@ -1039,6 +1219,8 @@ void CVradStaticPropMgr::ApplyLightingToStaticProp( CStaticProp &prop, const CCo Assert( pStudioHdr && pVtxHdr ); int iCurColorVertsArray = 0; + int iCurColorTexelsArray = 0; + for ( int bodyID = 0; bodyID < pStudioHdr->numbodyparts; ++bodyID ) { OptimizedModel::BodyPartHeader_t* pVtxBodyPart = pVtxHdr->pBodyPart( bodyID ); @@ -1048,8 +1230,9 @@ void CVradStaticPropMgr::ApplyLightingToStaticProp( CStaticProp &prop, const CCo { OptimizedModel::ModelHeader_t* pVtxModel = pVtxBodyPart->pModel( modelID ); mstudiomodel_t *pStudioModel = pBodyPart->pModel( modelID ); - - const CUtlVector &colorVerts = *pResults->m_ColorVertsArrays[iCurColorVertsArray++]; + + const CUtlVector *colorVerts = pResults->m_ColorVertsArrays.Count() ? pResults->m_ColorVertsArrays[iCurColorVertsArray++] : nullptr; + const CUtlVector *colorTexels = pResults->m_ColorTexelsArrays.Count() ? pResults->m_ColorTexelsArrays[iCurColorTexelsArray++] : nullptr; for ( int nLod = 0; nLod < pVtxHdr->numLODs; nLod++ ) { @@ -1064,15 +1247,52 @@ void CVradStaticPropMgr::ApplyLightingToStaticProp( CStaticProp &prop, const CCo { OptimizedModel::StripGroupHeader_t* pStripGroup = pVtxMesh->pStripGroup( nGroup ); int nMeshIdx = prop.m_MeshData.AddToTail(); - prop.m_MeshData[nMeshIdx].m_Verts.AddMultipleToTail( pStripGroup->numVerts ); - prop.m_MeshData[nMeshIdx].m_nLod = nLod; - for ( int nVertex = 0; nVertex < pStripGroup->numVerts; ++nVertex ) + if (colorVerts) { - int nIndex = pMesh->vertexoffset + pStripGroup->pVertex( nVertex )->origMeshVertID; + prop.m_MeshData[nMeshIdx].m_VertexColors.AddMultipleToTail( pStripGroup->numVerts ); + prop.m_MeshData[nMeshIdx].m_nLod = nLod; - Assert( nIndex < pStudioModel->numvertices ); - prop.m_MeshData[nMeshIdx].m_Verts[nVertex] = colorVerts[nIndex].m_Color; + for ( int nVertex = 0; nVertex < pStripGroup->numVerts; ++nVertex ) + { + int nIndex = pMesh->vertexoffset + pStripGroup->pVertex( nVertex )->origMeshVertID; + + Assert( nIndex < pStudioModel->numvertices ); + prop.m_MeshData[nMeshIdx].m_VertexColors[nVertex] = (*colorVerts)[nIndex].m_Color; + } + } + + if (colorTexels) + { + // TODO: Consider doing this work in the worker threads, because then we distribute it. + ConvertTexelDataToTexture(prop.m_LightmapImageWidth, prop.m_LightmapImageHeight, prop.m_LightmapImageFormat, (*colorTexels), &prop.m_MeshData[nMeshIdx].m_TexelsEncoded); + + if (g_bDumpPropLightmaps) + { + char buffer[_MAX_PATH]; + V_snprintf( + buffer, + _MAX_PATH - 1, + "staticprop_lightmap_%d_%.0f_%.0f_%.0f_%s_%d_%d_%d_%d_%d.tga", + iStaticProp, + prop.m_Origin.x, + prop.m_Origin.y, + prop.m_Origin.z, + dict.m_pStudioHdr->pszName(), + bodyID, + modelID, + nLod, + nMesh, + nGroup + ); + + for ( int i = 0; buffer[i]; ++i ) + { + if (buffer[i] == '/' || buffer[i] == '\\') + buffer[i] = '-'; + } + DumpLightmapLinear( buffer, (*colorTexels), prop.m_LightmapImageWidth, prop.m_LightmapImageHeight ); + } } } } @@ -1100,23 +1320,41 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr return; } - if (prop.m_Flags & STATIC_PROP_NO_PER_VERTEX_LIGHTING ) + const bool withVertexLighting = (prop.m_Flags & STATIC_PROP_NO_PER_VERTEX_LIGHTING) == 0; + const bool withTexelLighting = (prop.m_Flags & STATIC_PROP_NO_PER_TEXEL_LIGHTING) == 0; + + if (!withVertexLighting && !withTexelLighting) return; + const int skip_prop = (g_bDisablePropSelfShadowing || (prop.m_Flags & STATIC_PROP_NO_SELF_SHADOWING)) ? prop_index : -1; + const int nFlags = ( prop.m_Flags & STATIC_PROP_IGNORE_NORMALS ) ? GATHERLFLAGS_IGNORE_NORMALS : 0; + VMPI_SetCurrentStage( "ComputeLighting" ); + + matrix3x4_t matPos, matNormal; + AngleMatrix(prop.m_Angles, prop.m_Origin, matPos); + AngleMatrix(prop.m_Angles, matNormal); for ( int bodyID = 0; bodyID < pStudioHdr->numbodyparts; ++bodyID ) { + OptimizedModel::BodyPartHeader_t* pVtxBodyPart = pVtxHdr->pBodyPart( bodyID ); mstudiobodyparts_t *pBodyPart = pStudioHdr->pBodypart( bodyID ); for ( int modelID = 0; modelID < pBodyPart->nummodels; ++modelID ) { + OptimizedModel::ModelHeader_t* pVtxModel = pVtxBodyPart->pModel(modelID); mstudiomodel_t *pStudioModel = pBodyPart->pModel( modelID ); + if (withTexelLighting) + { + CUtlVector *pColorTexelArray = new CUtlVector; + pResults->m_ColorTexelsArrays.AddToTail(pColorTexelArray); + } + // light all unique vertexes CUtlVector *pColorVertsArray = new CUtlVector; pResults->m_ColorVertsArrays.AddToTail( pColorVertsArray ); - + CUtlVector &colorVerts = *pColorVertsArray; colorVerts.EnsureCount( pStudioModel->numvertices ); memset( colorVerts.Base(), 0, colorVerts.Count() * sizeof(colorVertex_t) ); @@ -1126,17 +1364,23 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr { mstudiomesh_t *pStudioMesh = pStudioModel->pMesh( meshID ); const mstudio_meshvertexdata_t *vertData = pStudioMesh->GetVertexData((void *)pStudioHdr); - Assert( vertData ); // This can only return NULL on X360 for now + + Assert(vertData); // This can only return NULL on X360 for now + + // TODO: Move this into its own function. In fact, refactor this whole function. + if (withTexelLighting) + { + GenerateLightmapSamplesForMesh( matPos, matNormal, iThread, skip_prop, nFlags, prop.m_LightmapImageWidth, prop.m_LightmapImageHeight, pStudioHdr, pStudioModel, pVtxModel, meshID, pResults ); + } + + // If we do lightmapping, we also do vertex lighting as a potential fallback. This may change. for ( int vertexID = 0; vertexID < pStudioMesh->numvertices; ++vertexID ) { Vector sampleNormal; Vector samplePosition; // transform position and normal into world coordinate system - matrix3x4_t matrix; - AngleMatrix( prop.m_Angles, prop.m_Origin, matrix ); - VectorTransform( *vertData->Position( vertexID ), matrix, samplePosition ); - AngleMatrix( prop.m_Angles, matrix ); - VectorTransform( *vertData->Normal( vertexID ), matrix, sampleNormal ); + VectorTransform(*vertData->Position(vertexID), matPos, samplePosition); + VectorTransform(*vertData->Normal(vertexID), matNormal, sampleNormal); if ( PositionInSolid( samplePosition ) ) { @@ -1150,18 +1394,13 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr else { Vector direct_pos=samplePosition; - int skip_prop = -1; - if ( g_bDisablePropSelfShadowing || ( prop.m_Flags & STATIC_PROP_NO_SELF_SHADOWING ) ) - { - skip_prop = prop_index; - } - int nFlags = ( prop.m_Flags & STATIC_PROP_IGNORE_NORMALS ) ? GATHERLFLAGS_IGNORE_NORMALS : 0; + Vector directColor(0,0,0); ComputeDirectLightingAtPoint( direct_pos, - sampleNormal, directColor, iThread, - skip_prop, nFlags ); + sampleNormal, directColor, iThread, + skip_prop, nFlags ); Vector indirectColor(0,0,0); if (g_bShowStaticPropNormals) @@ -1300,7 +1539,7 @@ void CVradStaticPropMgr::SerializeLighting() int totalVertexes = 0; for ( int j=0; jpMesh( n ); pMesh->m_nLod = m_StaticProps[i].m_MeshData[n].m_nLod; - pMesh->m_nVertexes = m_StaticProps[i].m_MeshData[n].m_Verts.Count(); + pMesh->m_nVertexes = m_StaticProps[i].m_MeshData[n].m_VertexColors.Count(); pMesh->m_nOffset = (unsigned int)pVertexData - (unsigned int)pVhvHdr; // construct vertexes for (int k=0; km_nVertexes; k++) { - Vector &vector = m_StaticProps[i].m_MeshData[n].m_Verts[k]; + Vector &vertexColor = m_StaticProps[i].m_MeshData[n].m_VertexColors[k]; ColorRGBExp32 rgbColor; - VectorToColorRGBExp32( vector, rgbColor ); + VectorToColorRGBExp32( vertexColor, rgbColor ); unsigned char dstColor[4]; ConvertRGBExp32ToRGBA8888( &rgbColor, dstColor ); @@ -1357,6 +1596,63 @@ void CVradStaticPropMgr::SerializeLighting() AddBufferToPak( GetPakFile(), filename, (void*)pVhvHdr, pVertexData - (unsigned char*)pVhvHdr, false ); } + + for (int i = 0; i < count; ++i) + { + const int kAlignment = 512; + // no need to write this file if we didn't compute the data + // props marked this way will not load the info anyway + if (m_StaticProps[i].m_Flags & STATIC_PROP_NO_PER_TEXEL_LIGHTING) + continue; + + sprintf(filename, "texelslighting_%d.ppl", i); + + ImageFormat fmt = m_StaticProps[i].m_LightmapImageFormat; + + unsigned int totalTexelSizeBytes = 0; + for (int j = 0; j < m_StaticProps[i].m_MeshData.Count(); j++) + { + totalTexelSizeBytes += m_StaticProps[i].m_MeshData[j].m_TexelsEncoded.Count(); + } + + // allocate a buffer with enough padding for alignment + size = sizeof(HardwareTexels::FileHeader_t) + + m_StaticProps[i].m_MeshData.Count() * sizeof(HardwareTexels::MeshHeader_t) + + totalTexelSizeBytes + + 2 * kAlignment; + + utlBuf.EnsureCapacity(size); + Q_memset(utlBuf.Base(), 0, size); + + HardwareTexels::FileHeader_t *pVhtHdr = (HardwareTexels::FileHeader_t *)utlBuf.Base(); + + // align start of texel data + unsigned char *pTexelData = (unsigned char *)(sizeof(HardwareTexels::FileHeader_t) + m_StaticProps[i].m_MeshData.Count() * sizeof(HardwareTexels::MeshHeader_t)); + pTexelData = (unsigned char*)pVhtHdr + ALIGN_TO_POW2((unsigned int)pTexelData, kAlignment); + + pVhtHdr->m_nVersion = VHT_VERSION; + pVhtHdr->m_nChecksum = m_StaticPropDict[m_StaticProps[i].m_ModelIdx].m_pStudioHdr->checksum; + pVhtHdr->m_nTexelFormat = fmt; + pVhtHdr->m_nMeshes = m_StaticProps[i].m_MeshData.Count(); + + for (int n = 0; n < pVhtHdr->m_nMeshes; n++) + { + HardwareTexels::MeshHeader_t *pMesh = pVhtHdr->pMesh(n); + pMesh->m_nLod = m_StaticProps[i].m_MeshData[n].m_nLod; + pMesh->m_nOffset = (unsigned int)pTexelData - (unsigned int)pVhtHdr; + pMesh->m_nBytes = m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Count(); + pMesh->m_nWidth = m_StaticProps[i].m_LightmapImageWidth; + pMesh->m_nHeight = m_StaticProps[i].m_LightmapImageHeight; + + Q_memcpy(pTexelData, m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Base(), m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Count()); + pTexelData += m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Count(); + } + + pTexelData = (unsigned char *)((unsigned int)pTexelData - (unsigned int)pVhtHdr); + pTexelData = (unsigned char*)pVhtHdr + ALIGN_TO_POW2((unsigned int)pTexelData, kAlignment); + + AddBufferToPak(GetPakFile(), filename, (void*)pVhtHdr, pTexelData - (unsigned char*)pVhtHdr, false); + } } void CVradStaticPropMgr::VMPI_ProcessStaticProp_Static( int iThread, uint64 iStaticProp, MessageBuffer *pBuf ) @@ -1392,6 +1688,17 @@ void CVradStaticPropMgr::VMPI_ProcessStaticProp( int iThread, int iStaticProp, M pBuf->write( &count, sizeof( count ) ); pBuf->write( curList.Base(), curList.Count() * sizeof( colorVertex_t ) ); } + + nLists = results.m_ColorTexelsArrays.Count(); + pBuf->write(&nLists, sizeof(nLists)); + + for (int i = 0; i < nLists; i++) + { + CUtlVector &curList = *results.m_ColorTexelsArrays[i]; + int count = curList.Count(); + pBuf->write(&count, sizeof(count)); + pBuf->write(curList.Base(), curList.Count() * sizeof(colorTexel_t)); + } } //----------------------------------------------------------------------------- @@ -1415,9 +1722,22 @@ void CVradStaticPropMgr::VMPI_ReceiveStaticPropResults( int iStaticProp, Message pList->SetSize( count ); pBuf->read( pList->Base(), count * sizeof( colorVertex_t ) ); } + + pBuf->read(&nLists, sizeof(nLists)); + + for (int i = 0; i < nLists; i++) + { + CUtlVector *pList = new CUtlVector; + results.m_ColorTexelsArrays.AddToTail(pList); + + int count; + pBuf->read(&count, sizeof(count)); + pList->SetSize(count); + pBuf->read(pList->Base(), count * sizeof(colorTexel_t)); + } // Apply the results. - ApplyLightingToStaticProp( m_StaticProps[iStaticProp], &results ); + ApplyLightingToStaticProp( iStaticProp, m_StaticProps[iStaticProp], &results ); } @@ -1426,7 +1746,7 @@ void CVradStaticPropMgr::ComputeLightingForProp( int iThread, int iStaticProp ) // Compute the lighting. CComputeStaticPropLightingResults results; ComputeLighting( m_StaticProps[iStaticProp], iThread, iStaticProp, &results ); - ApplyLightingToStaticProp( m_StaticProps[iStaticProp], &results ); + ApplyLightingToStaticProp( iStaticProp, m_StaticProps[iStaticProp], &results ); } void CVradStaticPropMgr::ThreadComputeStaticPropLighting( int iThread, void *pUserData ) @@ -1913,3 +2233,462 @@ const vertexFileHeader_t * mstudiomodel_t::CacheVertexData( void *pModelData ) pActiveStudioHdr->pVertexBase = (void*)pVvdHdr; return pVvdHdr; } + +// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ +struct ColorTexelValue +{ + Vector mLinearColor; // Linear color value for this texel + bool mValidData; // Whether there is valid data in this texel. + size_t mTriangleIndex; // Which triangle we used to generate the texel. +}; + +// ------------------------------------------------------------------------------------------------ +inline int ComputeLinearPos( int _x, int _y, int _resX, int _resY ) +{ + return Min( Max( 0, _y ), _resY - 1 ) * _resX + + Min( Max( 0, _x ), _resX - 1 ); +} + +// ------------------------------------------------------------------------------------------------ +inline float ComputeBarycentricDistanceToTri( Vector _barycentricCoord, Vector2D _v[3] ) +{ + Vector2D realPos = _barycentricCoord.x * _v[0] + + _barycentricCoord.y * _v[1] + + _barycentricCoord.z * _v[2]; + + int minIndex = 0; + float minVal = _barycentricCoord[0]; + for (int i = 1; i < 3; ++i) { + if (_barycentricCoord[i] < minVal) { + minVal = _barycentricCoord[i]; + minIndex = i; + } + } + + Vector2D& first = _v[ (minIndex + 1) % 3]; + Vector2D& second = _v[ (minIndex + 2) % 3]; + + return CalcDistanceToLineSegment2D( realPos, first, second ); +} + +// ------------------------------------------------------------------------------------------------ +static void GenerateLightmapSamplesForMesh( const matrix3x4_t& _matPos, const matrix3x4_t& _matNormal, int _iThread, int _skipProp, int _flags, int _lightmapResX, int _lightmapResY, studiohdr_t* _pStudioHdr, mstudiomodel_t* _pStudioModel, OptimizedModel::ModelHeader_t* _pVtxModel, int _meshID, CComputeStaticPropLightingResults *_outResults ) +{ + // Could iterate and gen this if needed. + int nLod = 0; + + OptimizedModel::ModelLODHeader_t *pVtxLOD = _pVtxModel->pLOD(nLod); + + CUtlVector &colorTexels = (*_outResults->m_ColorTexelsArrays.Tail()); + const int cTotalPixelCount = _lightmapResX * _lightmapResY; + colorTexels.EnsureCount(cTotalPixelCount); + memset(colorTexels.Base(), 0, colorTexels.Count() * sizeof(colorTexel_t)); + + for (int i = 0; i < colorTexels.Count(); ++i) { + colorTexels[i].m_fDistanceToTri = FLT_MAX; + } + + mstudiomesh_t* pMesh = _pStudioModel->pMesh(_meshID); + OptimizedModel::MeshHeader_t* pVtxMesh = pVtxLOD->pMesh(_meshID); + const mstudio_meshvertexdata_t *vertData = pMesh->GetVertexData((void *)_pStudioHdr); + Assert(vertData); // This can only return NULL on X360 for now + + for (int nGroup = 0; nGroup < pVtxMesh->numStripGroups; ++nGroup) + { + OptimizedModel::StripGroupHeader_t* pStripGroup = pVtxMesh->pStripGroup(nGroup); + + int nStrip; + for (nStrip = 0; nStrip < pStripGroup->numStrips; nStrip++) + { + OptimizedModel::StripHeader_t *pStrip = pStripGroup->pStrip(nStrip); + + // If this hits, re-factor the code to iterate over triangles, and build the triangles + // from the underlying structures. + Assert((pStrip->flags & OptimizedModel::STRIP_IS_TRISTRIP) == 0); + + if (pStrip->flags & OptimizedModel::STRIP_IS_TRILIST) + { + for (int i = 0; i < pStrip->numIndices; i += 3) + { + int idx = pStrip->indexOffset + i; + + unsigned short i1 = *pStripGroup->pIndex(idx); + unsigned short i2 = *pStripGroup->pIndex(idx + 1); + unsigned short i3 = *pStripGroup->pIndex(idx + 2); + + int vertex1 = pStripGroup->pVertex(i1)->origMeshVertID; + int vertex2 = pStripGroup->pVertex(i2)->origMeshVertID; + int vertex3 = pStripGroup->pVertex(i3)->origMeshVertID; + + Vector modelPos[3] = { + *vertData->Position(vertex1), + *vertData->Position(vertex2), + *vertData->Position(vertex3) + }; + + Vector modelNormal[3] = { + *vertData->Normal(vertex1), + *vertData->Normal(vertex2), + *vertData->Normal(vertex3) + }; + + Vector worldPos[3]; + Vector worldNormal[3]; + + VectorTransform(modelPos[0], _matPos, worldPos[0]); + VectorTransform(modelPos[1], _matPos, worldPos[1]); + VectorTransform(modelPos[2], _matPos, worldPos[2]); + + VectorTransform(modelNormal[0], _matNormal, worldNormal[0]); + VectorTransform(modelNormal[1], _matNormal, worldNormal[1]); + VectorTransform(modelNormal[2], _matNormal, worldNormal[2]); + + Vector2D texcoord[3] = { + *vertData->Texcoord(vertex1), + *vertData->Texcoord(vertex2), + *vertData->Texcoord(vertex3) + }; + + Rasterizer rasterizer(texcoord[0], texcoord[1], texcoord[2], + _lightmapResX, _lightmapResY); + + for (auto it = rasterizer.begin(); it != rasterizer.end(); ++it) + { + size_t linearPos = rasterizer.GetLinearPos(it); + Assert(linearPos < cTotalPixelCount); + + if ( colorTexels[linearPos].m_bValid ) + { + continue; + } + + float ourDistancetoTri = ComputeBarycentricDistanceToTri( it->barycentric, texcoord ); + + bool doWrite = it->insideTriangle + || !colorTexels[linearPos].m_bPossiblyInteresting + || colorTexels[linearPos].m_fDistanceToTri > ourDistancetoTri; + + if (doWrite) + { + Vector itWorldPos = worldPos[0] * it->barycentric.x + + worldPos[1] * it->barycentric.y + + worldPos[2] * it->barycentric.z; + + Vector itWorldNormal = worldNormal[0] * it->barycentric.x + + worldNormal[1] * it->barycentric.y + + worldNormal[2] * it->barycentric.z; + itWorldNormal.NormalizeInPlace(); + + colorTexels[linearPos].m_WorldPosition = itWorldPos; + colorTexels[linearPos].m_WorldNormal = itWorldNormal; + colorTexels[linearPos].m_bValid = it->insideTriangle; + colorTexels[linearPos].m_bPossiblyInteresting = true; + colorTexels[linearPos].m_fDistanceToTri = ourDistancetoTri; + } + } + } + } + } + } + + // Process neighbors to the valid region. Walk through the existing array, look for samples that + // are not valid but are adjacent to valid samples. Works if we are only bilinearly sampling + // on the other side. + // First attempt: Just pretend the triangle was larger and cast a ray from this new world pos + // as above. + int linearPos = 0; + for ( int j = 0; j < _lightmapResY; ++j ) + { + for (int i = 0; i < _lightmapResX; ++i ) + { + bool shouldProcess = colorTexels[linearPos].m_bValid; + // Are any of the eight neighbors valid?? + if ( colorTexels[linearPos].m_bPossiblyInteresting ) + { + // Look at our neighborhood (3x3 centerd on us). + shouldProcess = shouldProcess + || colorTexels[ComputeLinearPos( i - 1, j - 1, _lightmapResX, _lightmapResY )].m_bValid // TL + || colorTexels[ComputeLinearPos( i , j - 1, _lightmapResX, _lightmapResY )].m_bValid // T + || colorTexels[ComputeLinearPos( i + 1, j - 1, _lightmapResX, _lightmapResY )].m_bValid // TR + + || colorTexels[ComputeLinearPos( i - 1, j , _lightmapResX, _lightmapResY )].m_bValid // L + || colorTexels[ComputeLinearPos( i + 1, j , _lightmapResX, _lightmapResY )].m_bValid // R + + || colorTexels[ComputeLinearPos( i - 1, j + 1, _lightmapResX, _lightmapResY )].m_bValid // BL + || colorTexels[ComputeLinearPos( i , j + 1, _lightmapResX, _lightmapResY )].m_bValid // B + || colorTexels[ComputeLinearPos( i + 1, j + 1, _lightmapResX, _lightmapResY )].m_bValid; // BR + } + + if (shouldProcess) + { + Vector directColor(0, 0, 0), + indirectColor(0, 0, 0); + + + ComputeDirectLightingAtPoint( colorTexels[linearPos].m_WorldPosition, colorTexels[linearPos].m_WorldNormal, directColor, _iThread, _skipProp, _flags); + + if (numbounce >= 1) { + ComputeIndirectLightingAtPoint( colorTexels[linearPos].m_WorldPosition, colorTexels[linearPos].m_WorldNormal, indirectColor, _iThread, true, (_flags & GATHERLFLAGS_IGNORE_NORMALS) != 0 ); + } + + VectorAdd(directColor, indirectColor, colorTexels[linearPos].m_Color); + } + + ++linearPos; + } + } +} + +// ------------------------------------------------------------------------------------------------ +static int GetTexelCount(unsigned int _resX, unsigned int _resY, bool _mipmaps) +{ + // Because they are unsigned, this is a != check--but if we were to change to ints, this would be + // the right assert (and it's no worse than != now). + Assert(_resX > 0 && _resY > 0); + + if (_mipmaps == false) + return _resX * _resY; + + int retVal = 0; + while (_resX > 1 || _resY > 1) + { + retVal += _resX * _resY; + _resX = max(1, _resX >> 1); + _resY = max(1, _resY >> 1); + } + + // Add in the 1x1 mipmap level, which wasn't hit above. This could be done in the initializer of + // retVal, but it's more obvious here. + retVal += 1; + + return retVal; +} + +// ------------------------------------------------------------------------------------------------ +static void FilterFineMipmap(unsigned int _resX, unsigned int _resY, const CUtlVector& _srcTexels, CUtlVector* _outLinear) +{ + Assert(_outLinear); + // We can't filter in place, so go ahead and create a linear buffer here. + CUtlVector filterSrc; + filterSrc.EnsureCount(_srcTexels.Count()); + + for (int i = 0; i < _srcTexels.Count(); ++i) + { + ColorRGBExp32 rgbColor; + VectorToColorRGBExp32(_srcTexels[i].m_Color, rgbColor); + ConvertRGBExp32ToLinear( &rgbColor, &(filterSrc[i]) ); + } + + const int cRadius = 1; + const float cOneOverDiameter = 1.0f / pow(2.0f * cRadius + 1.0f, 2.0f) ; + // Filter here. + for (int j = 0; j < _resY; ++j) + { + for (int i = 0; i < _resX; ++i) + { + Vector value(0, 0, 0); + int thisIndex = ComputeLinearPos(i, j, _resX, _resY); + + if (!_srcTexels[thisIndex].m_bValid) + { + (*_outLinear)[thisIndex] = filterSrc[thisIndex]; + continue; + } + + // TODO: Check ASM for this, unroll by hand if needed. + for ( int offsetJ = -cRadius; offsetJ <= cRadius; ++offsetJ ) + { + for ( int offsetI = -cRadius; offsetI <= cRadius; ++offsetI ) + { + int finalIndex = ComputeLinearPos( i + offsetI, j + offsetJ, _resX, _resY ); + if ( !_srcTexels[finalIndex].m_bValid ) + { + finalIndex = thisIndex; + } + + value += filterSrc[finalIndex]; + } + } + + (*_outLinear)[thisIndex] = value * cOneOverDiameter; + } + } +} + +// ------------------------------------------------------------------------------------------------ +static void BuildFineMipmap(unsigned int _resX, unsigned int _resY, bool _applyFilter, const CUtlVector& _srcTexels, CUtlVector* _outTexelsRGB888, CUtlVector* _outLinear) +{ + // At least one of these needs to be non-null, otherwise what are we doing here? + Assert(_outTexelsRGB888 || _outLinear); + Assert(!_applyFilter || _outLinear); + Assert(_srcTexels.Count() == GetTexelCount(_resX, _resY, false)); + + int texelCount = GetTexelCount(_resX, _resY, true); + + if (_outTexelsRGB888) + (*_outTexelsRGB888).EnsureCount(texelCount); + + if (_outLinear) + (*_outLinear).EnsureCount(GetTexelCount(_resX, _resY, false)); + + // This code can take awhile, so minimize the branchiness of the inner-loop. + if (_applyFilter) + { + + FilterFineMipmap(_resX, _resY, _srcTexels, _outLinear); + + if ( _outTexelsRGB888 ) + { + for (int i = 0; i < _srcTexels.Count(); ++i) + { + RGBA8888_t encodedColor; + + Vector linearColor = (*_outLinear)[i]; + + ConvertLinearToRGBA8888( &linearColor, (unsigned char*)&encodedColor ); + (*_outTexelsRGB888)[i].r = encodedColor.r; + (*_outTexelsRGB888)[i].g = encodedColor.g; + (*_outTexelsRGB888)[i].b = encodedColor.b; + } + } + } + else + { + for (int i = 0; i < _srcTexels.Count(); ++i) + { + ColorRGBExp32 rgbColor; + RGBA8888_t encodedColor; + VectorToColorRGBExp32(_srcTexels[i].m_Color, rgbColor); + ConvertRGBExp32ToRGBA8888(&rgbColor, (unsigned char*)&encodedColor, (_outLinear ? (&(*_outLinear)[i]) : NULL) ); + // We drop alpha on the floor here, if this were to fire we'd need to consider using a different compressed format. + Assert(encodedColor.a == 0xFF); + + if (_outTexelsRGB888) + { + (*_outTexelsRGB888)[i].r = encodedColor.r; + (*_outTexelsRGB888)[i].g = encodedColor.g; + (*_outTexelsRGB888)[i].b = encodedColor.b; + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +static void FilterCoarserMipmaps(unsigned int _resX, unsigned int _resY, CUtlVector* _scratchLinear, CUtlVector *_outTexelsRGB888) +{ + Assert(_outTexelsRGB888); + + int srcResX = _resX; + int srcResY = _resY; + int dstResX = max(1, (srcResX >> 1)); + int dstResY = max(1, (srcResY >> 1)); + int dstOffset = GetTexelCount(srcResX, srcResY, false); + + // Build mipmaps here, after being converted to linear space. + // TODO: Should do better filtering for downsampling. But this will work for now. + while (srcResX > 1 || srcResY > 1) + { + for (int j = 0; j < srcResY; j += 2) { + for (int i = 0; i < srcResX; i += 2) { + int srcCol0 = i; + int srcCol1 = i + 1 > srcResX - 1 ? srcResX - 1 : i + 1; + int srcRow0 = j; + int srcRow1 = j + 1 > srcResY - 1 ? srcResY - 1 : j + 1;; + + int dstCol = i >> 1; + int dstRow = j >> 1; + + + const Vector& tl = (*_scratchLinear)[srcCol0 + (srcRow0 * srcResX)]; + const Vector& tr = (*_scratchLinear)[srcCol1 + (srcRow0 * srcResX)]; + const Vector& bl = (*_scratchLinear)[srcCol0 + (srcRow1 * srcResX)]; + const Vector& br = (*_scratchLinear)[srcCol1 + (srcRow1 * srcResX)]; + + Vector sample = (tl + tr + bl + br) / 4.0f; + + ConvertLinearToRGBA8888(&sample, (unsigned char*)&(*_outTexelsRGB888)[dstOffset + dstCol + dstRow * dstResX]); + + // Also overwrite the srcBuffer to filter the next loop. This is safe because we won't be reading this source value + // again during this mipmap level. + (*_scratchLinear)[dstCol + dstRow * dstResX] = sample; + } + } + + srcResX = dstResX; + srcResY = dstResY; + dstResX = max(1, (srcResX >> 1)); + dstResY = max(1, (srcResY >> 1)); + dstOffset += GetTexelCount(srcResX, srcResY, false); + } +} + +// ------------------------------------------------------------------------------------------------ +static void ConvertToDestinationFormat(unsigned int _resX, unsigned int _resY, ImageFormat _destFmt, const CUtlVector& _scratchRBG888, CUtlMemory* _outTexture) +{ + const ImageFormat cSrcImageFormat = IMAGE_FORMAT_RGB888; + + // Converts from the scratch RGB888 buffer, which should be fully filled out to the output texture. + int destMemoryUsage = ImageLoader::GetMemRequired(_resX, _resY, 1, _destFmt, true); + (*_outTexture).EnsureCapacity(destMemoryUsage); + + int srcResX = _resX; + int srcResY = _resY; + int srcOffset = 0; + int dstOffset = 0; + + // The usual case--that they'll be different. + if (cSrcImageFormat != _destFmt) + { + while (srcResX > 1 || srcResY > 1) + { + // Convert this mipmap level. + ImageLoader::ConvertImageFormat((unsigned char*)(&_scratchRBG888[srcOffset]), cSrcImageFormat, (*_outTexture).Base() + dstOffset, _destFmt, srcResX, srcResY); + + // Then update offsets for the next mipmap level. + srcOffset += GetTexelCount(srcResX, srcResY, false); + dstOffset += ImageLoader::GetMemRequired(srcResX, srcResY, 1, _destFmt, false); + + srcResX = max(1, (srcResX >> 1)); + srcResY = max(1, (srcResY >> 1)); + } + + // Do the 1x1 level also. + ImageLoader::ConvertImageFormat((unsigned char*)_scratchRBG888.Base() + srcOffset, cSrcImageFormat, (*_outTexture).Base() + dstOffset, _destFmt, srcResX, srcResY); + } else { + // But sometimes (particularly for debugging) they will be the same. + Q_memcpy( (*_outTexture).Base(), _scratchRBG888.Base(), destMemoryUsage ); + } +} + +// ------------------------------------------------------------------------------------------------ +static void ConvertTexelDataToTexture(unsigned int _resX, unsigned int _resY, ImageFormat _destFmt, const CUtlVector& _srcTexels, CUtlMemory* _outTexture) +{ + Assert(_outTexture); + Assert(_srcTexels.Count() == _resX * _resY); + + CUtlVector scratchRGB888; + CUtlVector scratchLinear; + + BuildFineMipmap(_resX, _resY, true, _srcTexels, &scratchRGB888, &scratchLinear); + FilterCoarserMipmaps(_resX, _resY, &scratchLinear, &scratchRGB888 ); + ConvertToDestinationFormat(_resX, _resY, _destFmt, scratchRGB888, _outTexture); +} + +// ------------------------------------------------------------------------------------------------ +static void DumpLightmapLinear( const char* _dstFilename, const CUtlVector& _srcTexels, int _width, int _height ) +{ + CUtlVector< Vector > linearFloats; + CUtlVector< BGR888_t > linearBuffer; + BuildFineMipmap( _width, _height, true, _srcTexels, NULL, &linearFloats ); + linearBuffer.SetCount( linearFloats.Count() ); + + for ( int i = 0; i < linearFloats.Count(); ++i ) { + linearBuffer[i].b = RoundFloatToByte(linearFloats[i].z * 255.0f); + linearBuffer[i].g = RoundFloatToByte(linearFloats[i].y * 255.0f); + linearBuffer[i].r = RoundFloatToByte(linearFloats[i].x * 255.0f); + } + + TGAWriter::WriteTGAFile( _dstFilename, _width, _height, IMAGE_FORMAT_BGR888, (uint8*)(linearBuffer.Base()), _width * ImageLoader::SizeInBytes(IMAGE_FORMAT_BGR888) ); +} diff --git a/utils/vrad_launcher/vrad_launcher.vpc b/utils/vrad_launcher/vrad_launcher.vpc index c9868357..393bcc17 100644 --- a/utils/vrad_launcher/vrad_launcher.vpc +++ b/utils/vrad_launcher/vrad_launcher.vpc @@ -15,7 +15,7 @@ $Configuration $Compiler { $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)" - $PrecompiledHeaderFile "Debug/vrad_launcher.pch" + $PrecompiledHeaderFile "$(IntDir)/vrad_launcher.pch" } } diff --git a/utils/vtf2tga/vtf2tga.cpp b/utils/vtf2tga/vtf2tga.cpp index 08c73340..dea83915 100644 --- a/utils/vtf2tga/vtf2tga.cpp +++ b/utils/vtf2tga/vtf2tga.cpp @@ -37,7 +37,7 @@ static void PFMWrite( float *pFloatImage, const char *pFilename, int width, int SpewRetval_t VTF2TGAOutputFunc( SpewType_t spewType, char const *pMsg ) { - printf( pMsg ); + printf( "%s", pMsg ); fflush( stdout ); if (spewType == SPEW_ERROR) diff --git a/vgui2/chromehtml/chromewrapper.cpp b/vgui2/chromehtml/chromewrapper.cpp deleted file mode 100644 index 179974f0..00000000 --- a/vgui2/chromehtml/chromewrapper.cpp +++ /dev/null @@ -1,441 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Creates a HTML control -// -// $NoKeywords: $ -//=============================================================================// -#include "winlite.h" -#include "html_chrome.h" -#include "tier1/interface.h" -#include "reliabletimer.h" -#include "htmlmanager.h" - -#include "html/htmlprotobuf.h" -#include - -//----------------------------------------------------------------------------- -// Purpose: owner object that gets responses from the CEF thread and dispatches them -//----------------------------------------------------------------------------- -class CHTMLController : public IHTMLChromeController -{ -public: - CHTMLController() { m_BrowserSerial = 0; m_nCefTargetFrameRate = 0; SetDefLessFunc( m_mapBrowserRequests ); SetDefLessFunc( m_mapBrowsers ); } - ~CHTMLController() {} - - bool Init( const char *pchHTMLCacheDir, const char *pchCookiePath ); - void Shutdown(); - - void SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires ); - void GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ); - void SetClientBuildID( uint64 ulBuildID ); - - bool BHasPendingMessages(); - - void CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ); - void RemoveBrowser( IHTMLResponses *pBrowser ); - bool RunFrame(); - - void WakeThread() { AccessHTMLWrapper().WakeThread(); } - HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) { return AccessHTMLWrapper().GetFreeCommandBuffer( eCmd, iBrowser ); } - void PushCommand( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().PushCommand( pCmd ); } - - - bool GetMainThreadCommand( HTMLCommandBuffer_t **pCmd ) { return AccessHTMLWrapper().GetMainThreadCommand( pCmd ); } - void ReleaseCommandBuffer( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().ReleaseCommandBuffer( pCmd ); } - -#ifdef DBGFLAG_VALIDATE - void Validate( CValidator &validator, const char *pchName ); - bool ChromePrepareForValidate(); - bool ChromeResumeFromValidate(); -#endif - - void SetCefThreadTargetFrameRate( uint32 nFPS ); - -private: - // keeps track of outstanding browser create requests - CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowserRequests; - // the next unique identifier to use when doing a browser create - uint32 m_BrowserSerial; - // the map of browser handles to our html panel objects, used for cef thread command dispatching - CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowsers; - - int m_nCefTargetFrameRate; -}; - - -static CHTMLController s_HTMLController; -EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CHTMLController, IHTMLChromeController, CHROMEHTML_CONTROLLER_INTERFACE_VERSION, s_HTMLController ); - - -//----------------------------------------------------------------------------- -// Purpose: request the cef thread to make a new browser -//----------------------------------------------------------------------------- -void CHTMLController::CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) -{ - m_BrowserSerial++; - m_mapBrowserRequests.Insert( m_BrowserSerial, pBrowser ); - - CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserCreate ); - cmd.Body().set_request_id( m_BrowserSerial ); - cmd.Body().set_popup( bPopupWindow ); - cmd.Body().set_useragent( pchUserAgentIdentifier ); - HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserCreate, -1 ); - cmd.SerializeCrossProc( &pBuf->m_Buffer ); - AccessHTMLWrapper().PushCommand( pBuf ); -} - - -//----------------------------------------------------------------------------- -// Purpose: delete a browser we have -//----------------------------------------------------------------------------- -void CHTMLController::RemoveBrowser( IHTMLResponses *pBrowser ) -{ - - // pull ourselves from the browser handle list as we are doing away - FOR_EACH_MAP_FAST( m_mapBrowsers, i) - { - if ( m_mapBrowsers[i] == pBrowser ) - { - // tell the cef thread this browser is going away - CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserRemove ); - cmd.Body().set_browser_handle( pBrowser->BrowserGetIndex() ); - HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserRemove, pBrowser->BrowserGetIndex() ); - cmd.SerializeCrossProc( &pBuf->m_Buffer ); - AccessHTMLWrapper().PushCommand( pBuf ); - - // now kill it - m_mapBrowsers.RemoveAt( i ); - } - } - - // also remove us from pending list if in it - FOR_EACH_MAP_FAST( m_mapBrowserRequests, i) - { - if ( m_mapBrowserRequests[i] == pBrowser ) - m_mapBrowserRequests.RemoveAt( i ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: turn on the cef engine -//----------------------------------------------------------------------------- -bool CHTMLController::Init( const char *pchHTMLCacheDir, const char *pchCookiePath ) -{ -#if !defined(WIN64) && !defined(STATIC_TIER0) - ChromeInit( pchHTMLCacheDir, pchCookiePath ); -#endif - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: shutdown chrome -//----------------------------------------------------------------------------- -void CHTMLController::Shutdown() -{ -#if !defined(WIN64) && !defined(STATIC_TIER0) - ChromeShutdown(); -#endif -} - - - -// helper macro to dispatch messages from the cef thread -#define HTML_MSG_FUNC( eHTMLCommand, bodyType, commandFunc ) \ - case eHTMLCommand: \ -{ \ - CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ - if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ -{ \ - bError = true; \ -} \ - else \ -{ \ - int idx = m_mapBrowsers.Find( cmd.BodyConst().browser_handle() ); \ - if ( idx != m_mapBrowsers.InvalidIndex() ) \ -{ \ - if ( m_mapBrowsers[idx] ) \ - m_mapBrowsers[idx]->commandFunc( &cmd.BodyConst() ); \ -} \ -} \ -} \ - break; \ - - -//----------------------------------------------------------------------------- -// Purpose: process any ipc responses we have pending -//----------------------------------------------------------------------------- -bool CHTMLController::RunFrame() -{ - VPROF_BUDGET( "CHTMLController::RunFrame", VPROF_BUDGETGROUP_TENFOOT ); - HTMLCommandBuffer_t *pCmd; - bool bError = false; - bool bDidwork = false; - - // Paint messages are dispatched last to avoid doing excessive work on - // the main thread when two paint messages have stacked up in the queue. - // This could be greatly optimized by doing atomic buffer swaps instead - // of pushing the paint updates through a queue, but this helps for now. - // -henryg - CUtlVector< HTMLCommandBuffer_t * > vecDeferredPaint; - - while( GetMainThreadCommand( &pCmd ) ) - { - bool bRelease = true; - bDidwork = true; - //Msg( "Got response %d\n", pCmd->m_eCmd ); - switch( pCmd->m_eCmd ) - { - default: - break; - case eHTMLCommands_BrowserCreateResponse: - { - CHTMLProtoBufMsg< CMsgBrowserCreateResponse > cmd( pCmd->m_eCmd ); - if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) - { - bError = true; - } - else - { - int idx = m_mapBrowserRequests.Find( cmd.BodyConst().request_id() ); - if ( idx != m_mapBrowserRequests.InvalidIndex() ) - { - m_mapBrowsers.Insert( cmd.BodyConst().browser_handle(), m_mapBrowserRequests[idx] ); - m_mapBrowserRequests[idx]->BrowserSetIndex( cmd.BodyConst().browser_handle() ); - m_mapBrowserRequests.RemoveAt( idx ); - } - } - } - break; - case eHTMLCommands_NeedsPaint: - { - bRelease = false; - vecDeferredPaint.AddToTail( pCmd ); - } - break; - - HTML_MSG_FUNC( eHTMLCommands_BrowserReady, CMsgBrowserReady, BrowserReady ); - HTML_MSG_FUNC( eHTMLCommands_StartRequest, CMsgStartRequest, BrowserStartRequest ); - HTML_MSG_FUNC( eHTMLCommands_URLChanged, CMsgURLChanged, BrowserURLChanged ); - HTML_MSG_FUNC( eHTMLCommands_FinishedRequest, CMsgFinishedRequest, BrowserFinishedRequest ); - HTML_MSG_FUNC( eHTMLCommands_ShowPopup, CMsgShowPopup, BrowserShowPopup ); - HTML_MSG_FUNC( eHTMLCommands_HidePopup, CMsgHidePopup, BrowserHidePopup ); - HTML_MSG_FUNC( eHTMLCommands_OpenNewTab, CMsgOpenNewTab, BrowserOpenNewTab ); - HTML_MSG_FUNC( eHTMLCommands_PopupHTMLWindow, CMsgPopupHTMLWindow, BrowserPopupHTMLWindow ); - HTML_MSG_FUNC( eHTMLCommands_SetHTMLTitle, CMsgSetHTMLTitle, BrowserSetHTMLTitle ); - HTML_MSG_FUNC( eHTMLCommands_LoadingResource, CMsgLoadingResource, BrowserLoadingResource ); - HTML_MSG_FUNC( eHTMLCommands_StatusText, CMsgStatusText, BrowserStatusText ); - HTML_MSG_FUNC( eHTMLCommands_SetCursor, CMsgSetCursor, BrowserSetCursor ); - HTML_MSG_FUNC( eHTMLCommands_FileLoadDialog, CMsgFileLoadDialog, BrowserFileLoadDialog ); - HTML_MSG_FUNC( eHTMLCommands_ShowToolTip, CMsgShowToolTip, BrowserShowToolTip ); - HTML_MSG_FUNC( eHTMLCommands_UpdateToolTip, CMsgUpdateToolTip, BrowserUpdateToolTip ); - HTML_MSG_FUNC( eHTMLCommands_HideToolTip, CMsgHideToolTip, BrowserHideToolTip ); - HTML_MSG_FUNC( eHTMLCommands_SearchResults, CMsgSearchResults, BrowserSearchResults ); - HTML_MSG_FUNC( eHTMLCommands_Close, CMsgClose, BrowserClose ); - HTML_MSG_FUNC( eHTMLCommands_GetZoomResponse, CMsgGetZoomResponse, BrowserGetZoomResponse ); - HTML_MSG_FUNC( eHTMLCommands_HorizontalScrollBarSizeResponse, CMsgHorizontalScrollBarSizeResponse, BrowserHorizontalScrollBarSizeResponse ); - HTML_MSG_FUNC( eHTMLCommands_VerticalScrollBarSizeResponse, CMsgVerticalScrollBarSizeResponse, BrowserVerticalScrollBarSizeResponse ); - HTML_MSG_FUNC( eHTMLCommands_LinkAtPositionResponse, CMsgLinkAtPositionResponse, BrowserLinkAtPositionResponse ); - HTML_MSG_FUNC( eHTMLCommands_ZoomToElementAtPositionResponse, CMsgZoomToElementAtPositionResponse, BrowserZoomToElementAtPositionResponse ); - HTML_MSG_FUNC( eHTMLCommands_JSAlert, CMsgJSAlert, BrowserJSAlert ); - HTML_MSG_FUNC( eHTMLCommands_JSConfirm, CMsgJSConfirm, BrowserJSConfirm ); - HTML_MSG_FUNC( eHTMLCommands_OpenSteamURL, CMsgOpenSteamURL, BrowserOpenSteamURL ); - HTML_MSG_FUNC( eHTMLCommands_CanGoBackandForward, CMsgCanGoBackAndForward, BrowserCanGoBackandForward ); - HTML_MSG_FUNC( eHTMLCommands_SizePopup, CMsgSizePopup, BrowserSizePopup ); - HTML_MSG_FUNC( eHTMLCommands_ScaleToValueResponse, CMsgScalePageToValueResponse, BrowserScalePageToValueResponse ); - HTML_MSG_FUNC( eHTMLCommands_RequestFullScreen, CMsgRequestFullScreen, BrowserRequestFullScreen ); - HTML_MSG_FUNC( eHTMLCommands_ExitFullScreen, CMsgExitFullScreen, BrowserExitFullScreen ); - HTML_MSG_FUNC( eHTMLCommands_GetCookiesForURLResponse, CMsgGetCookiesForURLResponse, BrowserGetCookiesForURLResponse ); - HTML_MSG_FUNC( eHTMLCommands_NodeGotFocus, CMsgNodeHasFocus, BrowserNodeGotFocus ); - HTML_MSG_FUNC( eHTMLCommands_SavePageToJPEGResponse, CMsgSavePageToJPEGResponse, BrowserSavePageToJPEGResponse ); - HTML_MSG_FUNC( eHTMLCommands_GetFocusedNodeValueResponse, CMsgFocusedNodeTextResponse, BrowserFocusedNodeValueResponse ); - } - if ( bError ) - { - Warning( "Failed to parse command %d", pCmd->m_eCmd ); - Assert( !"Bad Command" ); - } - if ( bRelease ) - { - ReleaseCommandBuffer( pCmd ); - } - } - - // Collapse deferred paints by browser ID and process them; the latest texture always - // has fully updated bits, we simply union its dirty rect with the skipped updates. - // Note: browser resizes always include a full dirty rect, we don't have to check here. - while ( vecDeferredPaint.Count() ) - { - // Pull the last paint off the queue - pCmd = vecDeferredPaint[ vecDeferredPaint.Count() - 1 ]; - int iBrowser = pCmd->m_iBrowser; - CHTMLProtoBufMsg cmd( eHTMLCommands_NeedsPaint ); - DbgVerify( cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ); - ReleaseCommandBuffer( pCmd ); - vecDeferredPaint.Remove( vecDeferredPaint.Count() - 1 ); - - - CMsgNeedsPaint &body = cmd.Body(); - CChromeUpdateRegion region; - if ( body.updatewide() && body.updatetall() ) - { - region.MarkDirtyRect( body.updatex(), body.updatey(), body.updatex() + body.updatewide(), body.updatey() + body.updatetall() ); - } - else - { - region.MarkAllDirty(); - } - - // Remove earlier paints for the same browser from the queue - for ( int i = vecDeferredPaint.Count() - 1; i >= 0; --i ) - { - if ( vecDeferredPaint[i]->m_iBrowser == iBrowser ) - { - // Decode - CHTMLProtoBufMsg cmdMerge( eHTMLCommands_NeedsPaint ); - DbgVerify( cmdMerge.BDeserializeCrossProc( &vecDeferredPaint[i]->m_Buffer ) ); - CMsgNeedsPaint &bodyMerge = cmdMerge.Body(); - - if ( body.browser_handle() == bodyMerge.browser_handle() ) - { - ReleaseCommandBuffer( vecDeferredPaint[i] ); - vecDeferredPaint.Remove( i ); - - // Merge update region - if ( bodyMerge.updatewide() && bodyMerge.updatetall() ) - { - region.MarkDirtyRect( bodyMerge.updatex(), bodyMerge.updatey(), bodyMerge.updatex() + bodyMerge.updatewide(), bodyMerge.updatey() + bodyMerge.updatetall() ); - } - else - { - region.MarkAllDirty(); - } - - // Send response to the skipped paint update to free up the texture slot - pCmd = GetFreeCommandBuffer( eHTMLCommands_NeedsPaintResponse, bodyMerge.browser_handle() ); - CHTMLProtoBufMsg cmdResponse( eHTMLCommands_NeedsPaintResponse ); - cmdResponse.Body().set_browser_handle( bodyMerge.browser_handle() ); - cmdResponse.Body().set_textureid( bodyMerge.textureid() ); - cmdResponse.SerializeCrossProc( &pCmd->m_Buffer ); - PushCommand( pCmd ); - } - } - } - - // Dispatch the merged update - int idxBrowser = m_mapBrowsers.Find( body.browser_handle() ); - if ( idxBrowser != m_mapBrowsers.InvalidIndex() ) - { - if ( m_mapBrowsers[idxBrowser] ) - { - int updateWide = region.GetUpdateWide( body.wide() ); - int updateTall = region.GetUpdateTall( body.tall() ); - if ( updateWide != body.wide() || updateTall != body.tall() ) - { - body.set_updatex( region.GetUpdateX( body.wide() ) ); - body.set_updatey( region.GetUpdateY( body.tall() ) ); - body.set_updatewide( updateWide ); - body.set_updatetall( updateTall ); - } - else - { - body.clear_updatex(); - body.clear_updatey(); - body.clear_updatewide(); - body.clear_updatetall(); - } - m_mapBrowsers[idxBrowser]->BrowserNeedsPaint( &body ); - } - } - } - - return bDidwork; -} - -//----------------------------------------------------------------------------- -// Purpose: set a cef cookie -//----------------------------------------------------------------------------- -void CHTMLController::SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires ) -{ -#if !defined(WIN64) && !defined(STATIC_TIER0) - ChromeSetWebCookie( pchHostname, pchKey, pchValue, pchPath, nExpires ); -#endif -} - - -//----------------------------------------------------------------------------- -// Purpose: set the buildid to report -//----------------------------------------------------------------------------- -void CHTMLController::SetClientBuildID( uint64 ulBuildID ) -{ -#if !defined(WIN64) && !defined(STATIC_TIER0) - ChromeSetClientBuildID( ulBuildID ); -#endif -} - - -//----------------------------------------------------------------------------- -// Purpose: get the cef cookies for a url -//----------------------------------------------------------------------------- -void CHTMLController::GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) -{ -#if !defined(WIN64) && !defined(STATIC_TIER0) - ChromeGetWebCookiesForURL( pstrValue, pchURL, pchName ); -#endif -} - - -//----------------------------------------------------------------------------- -// Purpose: true if any pending html message in the queue -//----------------------------------------------------------------------------- -bool CHTMLController::BHasPendingMessages() -{ - return AccessHTMLWrapper().BHasPendingMessages(); -} - - -//----------------------------------------------------------------------------- -// Purpose: tell the cef thread the frame rate to use if it changes -//----------------------------------------------------------------------------- -void CHTMLController::SetCefThreadTargetFrameRate( uint32 nFPS ) -{ - if ( nFPS != m_nCefTargetFrameRate ) - { - m_nCefTargetFrameRate = nFPS; - CHTMLProtoBufMsg cmd( eHTMLCommands_SetTargetFrameRate ); - cmd.Body().set_ntargetframerate( nFPS ); - HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_SetTargetFrameRate, -1 ); - cmd.SerializeCrossProc( &pBuf->m_Buffer ); - AccessHTMLWrapper().PushCommand( pBuf ); - } -} - -#ifdef DBGFLAG_VALIDATE -//----------------------------------------------------------------------------- -// Purpose: validate mem -//----------------------------------------------------------------------------- -void CHTMLController::Validate( CValidator &validator, const char *pchName ) -{ - ChromeValidate( validator, "ChromeValidate" ); - - validator.Push( "CHTMLController::ValidateStatics", NULL, pchName ); - ValidateObj( m_mapBrowserRequests ); - ValidateObj( m_mapBrowsers ); - validator.Pop(); -} - -bool CHTMLController::ChromeResumeFromValidate() -{ - return ::ChromeResumeFromValidate(); -} - -bool CHTMLController::ChromePrepareForValidate() -{ - return ::ChromePrepareForValidate(); -} -#endif // DBGFLAG_VALIDATE - - - diff --git a/vgui2/chromehtml/html_chrome.cpp b/vgui2/chromehtml/html_chrome.cpp deleted file mode 100644 index 2bf1b3f6..00000000 --- a/vgui2/chromehtml/html_chrome.cpp +++ /dev/null @@ -1,3552 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -//=============================================================================// - -#include "winlite.h" -#include "html_chrome.h" -#include "cef/include/cef_cookie.h" -#include "imageloadwrapper.h" -#include "html/ichromehtmlwrapper.h" -#include "input/mousecursors.h" -//#include "rtime.h" -#ifdef OSX -extern "C" void *CreateAutoReleasePool(); -extern "C" void ReleaseAutoReleasePool( void *pool ); -#endif -#ifdef WIN32 -#include -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include - -static uint64 sm_ulBuildID = 0; // will be appended to the user agent -static CCEFThread g_CEFThread; // main thread for CEF to do its thinking - -// access for main thread to get to the html object -CCEFThread &AccessHTMLWrapper() -{ - return g_CEFThread; -} - -// helper macro to send a command to the CEF thread -#define DISPATCH_MESSAGE( eCmd ) \ - cmd.Body().set_browser_handle( m_iBrowser ); \ - HTMLCommandBuffer_t *pBuf = g_CEFThread.GetFreeCommandBuffer( eCmd, m_iBrowser ); \ - cmd.SerializeCrossProc( &pBuf->m_Buffer ); \ - g_CEFThread.PushResponse( pBuf ); \ - -// wrappers for our handle to list index/serial, lower 16 bits are list index, top 16 bits are the serial number -#define BROWSER_HANDLE_FROM_INDEX_SERIAL( iList, nSerial ) iList + ((int)nSerial<<16) -#define BROWSER_SERIAL_FROM_HANDLE( nHandle ) (uint32)nHandle>>16 - -const int k_ScreenshotQuality = 95; // quality value used when making a jpeg image of a web page -const float k_flMaxScreenshotWaitTime = 5.0; // wait up to 5 sec before taking a screenshot - -//----------------------------------------------------------------------------- -// Purpose: thread to manage pumping the CEF message loop -//----------------------------------------------------------------------------- -CCEFThread::CCEFThread() -{ - m_bExit = false; - m_nTargetFrameRate = 60; // 60 Hz by default - m_nBrowserSerial = 0; - m_bFullScreenFlashVisible = false; - m_bSawUserInputThisFrame = false; -} - - -//----------------------------------------------------------------------------- -// Purpose: destructor -//----------------------------------------------------------------------------- -CCEFThread::~CCEFThread() -{ - // This can get called by the main thread before the actual thread exits, - // if there is a forced process exit due to some error. In this case, - // force the thread to exit before destroying the member variables it - // is depending on. - if ( !m_bExit ) - { - TriggerShutdown(); - Join( 20 * k_nThousand ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: tell cef where to place its state dirs -//----------------------------------------------------------------------------- -void CCEFThread::SetCEFPaths( const char *pchHTMLCacheDir, const char *pchCookiePath ) -{ - Assert( !IsAlive() ); - m_sHTMLCacheDir = pchHTMLCacheDir; - m_sCookiePath = pchCookiePath; -} - - -//----------------------------------------------------------------------------- -// Purpose: set the exit event on the cef thread -//----------------------------------------------------------------------------- -void CCEFThread::TriggerShutdown() -{ - m_bExit = true; - m_WakeEvent.Set(); - m_evWaitingForCommand.Set(); - m_eventDidExit.Wait( k_nThousand ); // wait 1 second at most for it to go away -} - - -//----------------------------------------------------------------------------- -// Purpose: tickle the run loop of the thread to run more commands -//----------------------------------------------------------------------------- -void CCEFThread::WakeThread() -{ - m_WakeEvent.Set(); -} - - -//----------------------------------------------------------------------------- -// Purpose: helper macro for message dispatch -//----------------------------------------------------------------------------- -#define HTML_MSG_FUNC( eHTMLCommand, bodyType, commandFunc ) \ - case eHTMLCommand: \ -{ \ - CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ - if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ -{ \ - bError = true; \ -} \ - else \ -{ \ - cmd.Body().set_browser_handle( pCmd->m_iBrowser ); \ - g_CEFThread.commandFunc( cmd ); \ -} \ -} \ - break; - - -#define HTML_MSG_FUNC_NOHANDLE( eHTMLCommand, bodyType, commandFunc ) \ - case eHTMLCommand: \ - { \ - CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ - if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ - { \ - bError = true; \ - } \ - else \ - { \ - g_CEFThread.commandFunc( cmd ); \ - } \ - } \ - break; - - -//----------------------------------------------------------------------------- -// Purpose: clear any pending commands from the main thread -//----------------------------------------------------------------------------- -void CCEFThread::RunCurrentCommands() -{ - bool bError = false; - HTMLCommandBuffer_t *pCmd =NULL; - - while( GetCEFThreadCommand( &pCmd ) ) - { - //Msg( "Got command %d\n", pCmd->m_eCmd ); - switch( pCmd->m_eCmd ) - { - HTML_MSG_FUNC_NOHANDLE( eHTMLCommands_BrowserCreate, CMsgBrowserCreate, ThreadCreateBrowser ); - HTML_MSG_FUNC( eHTMLCommands_BrowserRemove, CMsgBrowserRemove, ThreadRemoveBrowser ); - HTML_MSG_FUNC( eHTMLCommands_BrowserSize, CMsgBrowserSize, ThreadBrowserSize ); - HTML_MSG_FUNC( eHTMLCommands_BrowserPosition, CMsgBrowserPosition, ThreadBrowserPosition ); - HTML_MSG_FUNC( eHTMLCommands_PostURL, CMsgPostURL, ThreadBrowserPostURL ); - HTML_MSG_FUNC( eHTMLCommands_StopLoad, CMsgStopLoad, ThreadBrowserStopLoad ); - HTML_MSG_FUNC( eHTMLCommands_Reload, CMsgReload, ThreadBrowserReload ); - HTML_MSG_FUNC( eHTMLCommands_GoForward, CMsgGoForward, ThreadBrowserGoForward ); - HTML_MSG_FUNC( eHTMLCommands_GoBack, CMsgGoBack, ThreadBrowserGoBack ); - HTML_MSG_FUNC( eHTMLCommands_Copy, CMsgCopy, ThreadBrowserCopy ); - HTML_MSG_FUNC( eHTMLCommands_Paste, CMsgPaste, ThreadBrowserPaste ); - HTML_MSG_FUNC( eHTMLCommands_ExecuteJavaScript, CMsgExecuteJavaScript, ThreadBrowserExecuteJavascript ); - HTML_MSG_FUNC( eHTMLCommands_SetFocus, CMsgSetFocus, ThreadBrowserSetFocus ); - HTML_MSG_FUNC( eHTMLCommands_HorizontalScrollBarSize, CMsgHorizontalScrollBarSize, ThreadBrowserHorizontalScrollBarSize ); - HTML_MSG_FUNC( eHTMLCommands_VerticalScrollBarSize, CMsgVerticalScrollBarSize, ThreadBrowserVerticalScrollBarSize ); - HTML_MSG_FUNC( eHTMLCommands_Find, CMsgFind, ThreadBrowserFind ); - HTML_MSG_FUNC( eHTMLCommands_StopFind, CMsgStopFind, ThreadBrowserStopFind ); - HTML_MSG_FUNC( eHTMLCommands_SetHorizontalScroll, CMsgSetHorizontalScroll, ThreadBrowserSetHorizontalScroll ); - HTML_MSG_FUNC( eHTMLCommands_SetVerticalScroll, CMsgSetVerticalScroll, ThreadBrowserSetVerticalScroll ); - HTML_MSG_FUNC( eHTMLCommands_SetZoomLevel, CMsgSetZoomLevel, ThreadBrowserSetZoomLevel ); - HTML_MSG_FUNC( eHTMLCommands_ViewSource, CMsgViewSource, ThreadBrowserViewSource ); - HTML_MSG_FUNC( eHTMLCommands_NeedsPaintResponse, CMsgNeedsPaintResponse, ThreadNeedsPaintResponse ); - HTML_MSG_FUNC( eHTMLCommands_BrowserErrorStrings, CMsgBrowserErrorStrings, ThreadBrowserErrorStrings ); - HTML_MSG_FUNC( eHTMLCommands_AddHeader, CMsgAddHeader, ThreadAddHeader ); - HTML_MSG_FUNC( eHTMLCommands_GetZoom, CMsgGetZoom, ThreadGetZoom ); - HTML_MSG_FUNC_NOHANDLE( eHTMLCommands_SetCookie, CMsgSetCookie, ThreadSetCookie ); - HTML_MSG_FUNC_NOHANDLE( eHTMLCommands_SetTargetFrameRate, CMsgSetTargetFrameRate, ThreadSetTargetFrameRate ); - HTML_MSG_FUNC( eHTMLCommands_HidePopup, CMsgHidePopup, ThreadHidePopup ); - HTML_MSG_FUNC( eHTMLCommands_FullRepaint, CMsgFullRepaint, ThreadFullRepaint ); - HTML_MSG_FUNC( eHTMLCommands_GetCookiesForURL, CMsgGetCookiesForURL, ThreadGetCookiesForURL ); - HTML_MSG_FUNC( eHTMLCommands_ZoomToCurrentlyFocusedNode, CMsgZoomToFocusedElement, ThreadZoomToFocusedElement ); - HTML_MSG_FUNC( eHTMLCommands_GetFocusedNodeValue, CMsgFocusedNodeText, ThreadGetFocusedNodeText ); - - HTML_MSG_FUNC( eHTMLCommands_MouseDown, CMsgMouseDown, ThreadMouseButtonDown ); - HTML_MSG_FUNC( eHTMLCommands_MouseUp, CMsgMouseUp, ThreadMouseButtonUp ); - HTML_MSG_FUNC( eHTMLCommands_MouseDblClick, CMsgMouseDblClick, ThreadMouseButtonDlbClick ); - HTML_MSG_FUNC( eHTMLCommands_MouseWheel, CMsgMouseWheel, ThreadMouseWheel ); - HTML_MSG_FUNC( eHTMLCommands_KeyDown, CMsgKeyDown, ThreadKeyDown ); - HTML_MSG_FUNC( eHTMLCommands_KeyUp, CMsgKeyUp, ThreadKeyUp ); - HTML_MSG_FUNC( eHTMLCommands_KeyChar, CMsgKeyChar, ThreadKeyTyped ); - HTML_MSG_FUNC( eHTMLCommands_MouseMove, CMsgMouseMove, ThreadMouseMove ); - HTML_MSG_FUNC( eHTMLCommands_MouseLeave, CMsgMouseLeave, ThreadMouseLeave ); - HTML_MSG_FUNC( eHTMLCommands_LinkAtPosition, CMsgLinkAtPosition, ThreadLinkAtPosition ); - HTML_MSG_FUNC( eHTMLCommands_ZoomToElementAtPosition, CMsgZoomToElementAtPosition, ThreadZoomToElementAtPosition ); - HTML_MSG_FUNC( eHTMLCommands_SavePageToJPEG, CMsgSavePageToJPEG, ThreadSavePageToJPEG ); - HTML_MSG_FUNC( eHTMLCommands_SetPageScale, CMsgScalePageToValue, ThreadSetPageScale ); - HTML_MSG_FUNC( eHTMLCommands_ExitFullScreen, CMsgExitFullScreen, ThreadExitFullScreen ); - HTML_MSG_FUNC( eHTMLCommands_CloseFullScreenFlashIfOpen, CMsgCloseFullScreenFlashIfOpen, ThreadCloseFullScreenFlashIfOpen ); - HTML_MSG_FUNC( eHTMLCommands_PauseFullScreenFlashMovieIfOpen, CMsgPauseFullScreenFlashMovieIfOpen, ThreadPauseFullScreenFlashMovieIfOpen ); - - default: - bError = true; - AssertMsg1( false, "Invalid message in browser stream (%d)", pCmd->m_eCmd ); - break; - } - - if ( pCmd->m_eCmd == eHTMLCommands_MouseDown || pCmd->m_eCmd == eHTMLCommands_MouseDblClick || pCmd->m_eCmd == eHTMLCommands_KeyDown ) - m_bSawUserInputThisFrame = true; - - ReleaseCommandBuffer( pCmd ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: done with this buffer, put it in the free queue -//----------------------------------------------------------------------------- -void CCEFThread::ReleaseCommandBuffer( HTMLCommandBuffer_t *pBuf ) -{ - pBuf->m_eCmd = eHTMLCommands_None; - pBuf->m_iBrowser = -1; - pBuf->m_Buffer.Clear(); - m_tslUnsedBuffers.PushItem( pBuf ); -} - - -//----------------------------------------------------------------------------- -// Purpose: get the next free cef thread command buffer to write into -//----------------------------------------------------------------------------- -HTMLCommandBuffer_t *CCEFThread::GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) -{ - HTMLCommandBuffer_t *pBuf; - if ( !m_tslUnsedBuffers.PopItem( &pBuf ) ) // if nothing in the free queue just make a new one - pBuf = new HTMLCommandBuffer_t; - - pBuf->m_eCmd = eCmd; - pBuf->m_iBrowser = iBrowser; - return pBuf; -} - - -//----------------------------------------------------------------------------- -// Purpose: wait for a command of this type on the cef thread -//----------------------------------------------------------------------------- -HTMLCommandBuffer_t *CCEFThread::BWaitForCommand( EHTMLCommands eCmd, int iBrowser ) -{ - while ( !m_bExit ) - { - if ( m_bSleepForValidate ) - { - m_bSleepingForValidate = true; - ThreadSleep( 100 ); - continue; - } - m_bSleepingForValidate = false; - - HTMLCommandBuffer_t *pBuf = NULL; - while ( m_tslCommandBuffers.PopItem( &pBuf ) && pBuf ) - { - if ( pBuf->m_iBrowser == iBrowser ) - { - if ( pBuf->m_eCmd == eCmd ) // it is what we have been waiting for - return pBuf; - if ( pBuf->m_eCmd == eHTMLCommands_BrowserRemove ) // check to see if this is being deleted while its launching - return NULL; - } - - m_vecQueueCommands.AddToTail( pBuf ); - pBuf = NULL; - } - Assert( pBuf == NULL ); - m_evWaitingForCommand.Wait(); - } - return NULL; -} - - -//----------------------------------------------------------------------------- -// Purpose: wait for a command of this type on the cef thread -//----------------------------------------------------------------------------- -HTMLCommandBuffer_t *CCEFThread::BWaitForResponse( EHTMLCommands eCmd, int iBrowser ) -{ - while ( !m_bExit ) - { - if ( m_bSleepForValidate ) - { - m_bSleepingForValidate = true; - ThreadSleep( 100 ); - continue; - } - m_bSleepingForValidate = false; - - HTMLCommandBuffer_t *pBuf = NULL; - while ( m_tslResponseBuffers.PopItem( &pBuf ) && pBuf ) - { - if ( pBuf->m_iBrowser == iBrowser ) - { - if ( pBuf->m_eCmd == eCmd ) // it is what we have been waiting for - return pBuf; - if ( pBuf->m_eCmd == eHTMLCommands_BrowserRemove ) // check to see if this is being deleted while its launching - return NULL; - } - - m_vecQueueResponses.AddToTail( pBuf ); - pBuf = NULL; - } - Assert( pBuf == NULL ); - m_evWaitingForResponse.Wait(); - } - return NULL; -} - - -//----------------------------------------------------------------------------- -// Purpose: add a command for the cef thread -//----------------------------------------------------------------------------- -void CCEFThread::PushCommand( HTMLCommandBuffer_t *pBuf ) -{ - m_tslCommandBuffers.PushItem( pBuf ); - m_evWaitingForCommand.Set(); -} - - -//----------------------------------------------------------------------------- -// Purpose: add a command for the main thread -//----------------------------------------------------------------------------- -void CCEFThread::PushResponse( HTMLCommandBuffer_t *pBuf ) -{ - m_tslResponseBuffers.PushItem( pBuf ); - m_evWaitingForResponse.Set(); -} - - - -//----------------------------------------------------------------------------- -// Purpose: get any cef responses on the main thread, returns false if there are none -//----------------------------------------------------------------------------- -bool CCEFThread::GetMainThreadCommand( HTMLCommandBuffer_t **pBuf ) -{ - if ( m_vecQueueResponses.Count() ) - { - *pBuf = m_vecQueueResponses[0]; - m_vecQueueResponses.Remove(0); - return true; - } - else - return m_tslResponseBuffers.PopItem( pBuf ); -} - - -//----------------------------------------------------------------------------- -// Purpose: get the next cef thread protobuf command to run, return false if there are none -//----------------------------------------------------------------------------- -bool CCEFThread::GetCEFThreadCommand( HTMLCommandBuffer_t **pBuf ) -{ - if ( m_vecQueueCommands.Count() ) - { - *pBuf = m_vecQueueCommands[0]; - m_vecQueueCommands.Remove(0); - return true; - } - else - return m_tslCommandBuffers.PopItem( pBuf ); -} - - -//----------------------------------------------------------------------------- -// Purpose: the user agent to report when using this browser control -//----------------------------------------------------------------------------- -const char *CCEFThread::PchWebkitUserAgent() -{ - return "Mozilla/5.0 (%s; U; %s; en-US; %s/%llu; %s) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19"; -} - - -//----------------------------------------------------------------------------- -// Purpose: make a new browser object -//----------------------------------------------------------------------------- -void CCEFThread::ThreadCreateBrowser( const CHTMLProtoBufMsg &htmlCommand ) -{ - int idx = m_listClientHandlers.AddToTail(); - ++m_nBrowserSerial; - CClientHandler *pBrowser = new CClientHandler( BROWSER_HANDLE_FROM_INDEX_SERIAL( idx, m_nBrowserSerial ), PchWebkitUserAgent(), m_nBrowserSerial ); - pBrowser->SetUserAgentIdentifier( htmlCommand.BodyConst().useragent().c_str() ); - - // send the handle info back to the main thread, needs to be before the CreateBrowser below - // to stop a race condition of the browser being ready before the main thread knows its handle - CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserCreateResponse ); - cmd.Body().set_browser_handle( BROWSER_HANDLE_FROM_INDEX_SERIAL( idx, m_nBrowserSerial ) ); - cmd.Body().set_request_id( htmlCommand.BodyConst().request_id() ); - HTMLCommandBuffer_t *pBuf = GetFreeCommandBuffer( eHTMLCommands_BrowserCreateResponse, idx ); - cmd.SerializeCrossProc( &pBuf->m_Buffer ); - PushResponse( pBuf ); - - m_listClientHandlers[idx] = pBrowser; - pBrowser->AddRef(); - - CefWindowInfo info; - info.SetAsOffScreen( NULL ); - info.m_bPopupWindow = htmlCommand.BodyConst().popup(); - CefBrowserSettings settings; - settings.fullscreen_enabled = true; - settings.threaded_compositing_enabled = true; - settings.java_disabled = true; - //settings.accelerated_compositing_enabled = true; // not supported when going into fullscreen mode - - // Drag and drop is supposed to be disabled automatically for offscreen views, but - // ports for Mac and Linux have bugs where it is not really disabled, causing havoc - settings.drag_drop_disabled = true; - -#ifdef LINUX - // Turn off web features here that don't work on Linux - settings.webgl_disabled = true; -#endif - - // CEF HTML local storage, databases, and offline application cache are all busted; - // they live in a temp dir which gets cleaned up on shutdown. There's no point in - // enabling them just to generate extra files to cleanup on shutdown when there's - // no actual disk persistence. we need to upgrade CEF again before they will work. - settings.local_storage_disabled = true; - settings.databases_disabled = true; - settings.application_cache_disabled = true; - settings.java_disabled = true; - - // We don't provide a UI to connect to the WebKit developer tools API - // so there is no point having it suck up CPU and listening on a port. - settings.developer_tools_disabled = true; - - // Drag and drop is supposed to be disabled automatically for offscreen views, but - // ports for Mac and Linux have bugs where it is not really disabled, causing havoc - settings.drag_drop_disabled = true; - -#ifdef LINUX - // Turn off web features here that don't work on Linux - settings.webgl_disabled = true; -#endif - - CefBrowser::CreateBrowserSync( info, pBrowser, "", settings ); - CefDoMessageLoopWork(); -} - - -//----------------------------------------------------------------------------- -// Purpose: return true if this browser handle resolves into a currently valid browser handler object -//----------------------------------------------------------------------------- -bool CCEFThread::BIsValidBrowserHandle( uint32 nHandle, int &iClient ) -{ - iClient = nHandle & 0xffff; - if ( m_listClientHandlers.IsValidIndex( nHandle & 0xffff ) ) - { - if ( m_listClientHandlers[ iClient ]->NSerial() == BROWSER_SERIAL_FROM_HANDLE( nHandle ) ) - return true; - } - iClient = -1; - return false; -} - - -//----------------------------------------------------------------------------- -// Purpose: delete this browser object, we are done with it -//----------------------------------------------------------------------------- -void CCEFThread::ThreadRemoveBrowser( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - m_listClientHandlers[iClient]->CloseBrowser(); - m_listClientHandlers[iClient]->Release(); - m_listClientHandlers[iClient] = NULL; - m_listClientHandlers.Remove( iClient ); - } -} - - -// helper macro to call browser functions if you have a valid handle -#define GET_BROSWER_FUNC( msg, cmd ) \ - int iClient; \ - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) \ - { \ - if ( m_listClientHandlers[iClient]->GetBrowser() ) \ - m_listClientHandlers[iClient]->GetBrowser()->cmd; \ - } \ - - //else \ - // Assert( false ); - - -//----------------------------------------------------------------------------- -// Purpose: make the web page this many pixels wide&tall -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserSize( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, SetSize( PET_VIEW, htmlCommand.BodyConst().width(), htmlCommand.BodyConst().height() ) ); - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - m_listClientHandlers[iClient]->SetSize( htmlCommand.BodyConst().width(), htmlCommand.BodyConst().height() ); - } - - -//----------------------------------------------------------------------------- -// Purpose: set the global position of the browser to these co-ords, used by some activeX controls -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserPosition( const CHTMLProtoBufMsg &htmlCommand ) -{ - // no longer used - BUGBUG remove me -} - - -//----------------------------------------------------------------------------- -// Purpose: load this url in the browser with optional post data -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserPostURL( const CHTMLProtoBufMsg &htmlCommand ) -{ - if ( htmlCommand.BodyConst().url().empty() ) - return; // they asked us to load nothing, ignore them - - const char *pchPostData = htmlCommand.BodyConst().post().c_str(); - if ( !pchPostData || !pchPostData[0] ) - { - GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->LoadURL( std::wstring( CStrAutoEncode( htmlCommand.BodyConst().url().c_str() ).ToWString() ) ) ); - } - else - { - // Create a new request - CefRefPtr request(CefRequest::CreateRequest()); - - // Set the request URL - request->SetURL( CStrAutoEncode( htmlCommand.BodyConst().url().c_str() ).ToWString() ); - - // Add post data to the request. The correct method and content- - // type headers will be set by CEF. - CefRefPtr postDataElement( CefPostDataElement::CreatePostDataElement() ); - - std::string data = pchPostData; - - postDataElement->SetToBytes(data.length(), data.c_str()); - - CefRefPtr postData(CefPostData::CreatePostData()); - - postData->AddElement(postDataElement); - request->SetPostData(postData); - - GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->LoadRequest( request ) ); - } - - int iClient; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - m_listClientHandlers[iClient]->SetPendingPageSerial( htmlCommand.BodyConst().pageserial() ); - - CefDoMessageLoopWork(); // make sure CEF processes this load before we do anything else (like delete the browser control) -} - - -//----------------------------------------------------------------------------- -// Purpose: stop loading the page we are on -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserStopLoad( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, StopLoad() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: reload the current page -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserReload( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, Reload() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: go forward one page in its history -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserGoForward( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, GoForward() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: go back one page in its history -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserGoBack( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, GoBack() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: copy selected text to the clipboard -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserCopy( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->Copy() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: paste from the clipboard into the web page -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserPaste( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->Paste() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: run this javascript on the current page -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserExecuteJavascript( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->ExecuteJavaScript( - CStrAutoEncode( htmlCommand.BodyConst().script().c_str() ).ToWString(), L"", 0 ) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: tell the browser it has key focus -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserSetFocus( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, SetFocus( htmlCommand.BodyConst().focus() ) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: get the size of the horizontal scroll bar -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserHorizontalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ) -{ - ThreadBrowserHorizontalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); -} - - -//----------------------------------------------------------------------------- -// Purpose: tell the main thread details of the horiztonal scrollbar -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserHorizontalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ) -{ - CClientHandler::CachedScrollBarState_t scroll = { }; - float flZoom = 0.0f; - int iClient = 0; - if ( BIsValidBrowserHandle( iBrowser, iClient ) ) - { - CClientHandler *pHandler = m_listClientHandlers[iClient]; - - if ( pHandler->GetBrowser() ) - { - scroll.m_nMax = pHandler->GetBrowser()->HorizontalScrollMax(); - scroll.m_nScroll = pHandler->GetBrowser()->HorizontalScroll(); - scroll.m_bVisible = pHandler->GetBrowser()->IsHorizontalScrollBarVisible(); - pHandler->GetBrowser()->HorizontalScrollBarSize( scroll.m_nX, scroll.m_nY, scroll.m_nWide, scroll.m_nTall ); - flZoom = pHandler->GetBrowser()->GetZoomLevel(); - if ( scroll.m_nMax < 0 ) - scroll.m_nMax = 0; - if ( flZoom == 0.0f ) - flZoom = 1.0f; - } - - if ( bForceSendUpdate || 0 != memcmp( &pHandler->m_CachedHScroll, &scroll, sizeof( scroll ) ) ) - { - pHandler->m_CachedHScroll = scroll; - - CHTMLProtoBufMsg cmd( eHTMLCommands_HorizontalScrollBarSizeResponse ); - cmd.Body().set_x( scroll.m_nX ); - cmd.Body().set_y( scroll.m_nY ); - cmd.Body().set_wide( scroll.m_nWide ); - cmd.Body().set_tall( scroll.m_nTall ); - cmd.Body().set_scroll_max( scroll.m_nMax ); - cmd.Body().set_scroll( scroll.m_nScroll ); - cmd.Body().set_visible( scroll.m_bVisible != 0 ); - cmd.Body().set_zoom( flZoom ); - int m_iBrowser = iBrowser; - DISPATCH_MESSAGE( eHTMLCommands_HorizontalScrollBarSizeResponse ); -} - } -} - - -//----------------------------------------------------------------------------- -// Purpose: get the size of the verical scrollbar -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserVerticalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ) -{ - ThreadBrowserVerticalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); -} - - -//----------------------------------------------------------------------------- -// Purpose: tell the main thread details of the vertical scrollbar -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserVerticalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ) -{ - CClientHandler::CachedScrollBarState_t scroll = { }; - float flZoom = 0.0f; - int iClient = 0; - if ( BIsValidBrowserHandle( iBrowser, iClient ) ) - { - CClientHandler *pHandler = m_listClientHandlers[iClient]; - - if ( pHandler->GetBrowser() ) - { - scroll.m_nMax = pHandler->GetBrowser()->VerticalScrollMax(); - scroll.m_nScroll = pHandler->GetBrowser()->VerticalScroll(); - scroll.m_bVisible = pHandler->GetBrowser()->IsVeritcalScrollBarVisible(); - pHandler->GetBrowser()->VerticalScrollBarSize( scroll.m_nX, scroll.m_nY, scroll.m_nWide, scroll.m_nTall ); - flZoom = pHandler->GetBrowser()->GetZoomLevel(); - if ( scroll.m_nMax < 0 ) - scroll.m_nMax = 0; - if ( flZoom == 0.0f ) - flZoom = 1.0f; - } - - if ( bForceSendUpdate || 0 != memcmp( &pHandler->m_CachedVScroll, &scroll, sizeof( scroll ) ) ) - { - pHandler->m_CachedVScroll = scroll; - - CHTMLProtoBufMsg cmd( eHTMLCommands_VerticalScrollBarSizeResponse ); - cmd.Body().set_x( scroll.m_nX ); - cmd.Body().set_y( scroll.m_nY ); - cmd.Body().set_wide( scroll.m_nWide ); - cmd.Body().set_tall( scroll.m_nTall ); - cmd.Body().set_scroll_max( scroll.m_nMax ); - cmd.Body().set_scroll( scroll.m_nScroll ); - cmd.Body().set_visible( scroll.m_bVisible != 0 ); - cmd.Body().set_zoom( flZoom ); - int m_iBrowser = iBrowser; - DISPATCH_MESSAGE( eHTMLCommands_VerticalScrollBarSizeResponse ); -} - } -} - - -//----------------------------------------------------------------------------- -// Purpose: start a find in a web page -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserFind( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, Find( 1, htmlCommand.BodyConst().find().c_str(), !htmlCommand.BodyConst().reverse(), false, htmlCommand.BodyConst().infind() ) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: dismiss a current find -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserStopFind( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, StopFinding( 1 ) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: scroll the page horizontally to this pos -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserSetHorizontalScroll( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, SetHorizontalScroll( htmlCommand.BodyConst().scroll() ) ); - - ThreadBrowserHorizontalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); - } - - -//----------------------------------------------------------------------------- -// Purpose: scroll the page vertically to this pos -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserSetVerticalScroll( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, SetVerticalScroll( htmlCommand.BodyConst().scroll() ) ); - - ThreadBrowserVerticalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); -} - - -//----------------------------------------------------------------------------- -// Purpose: set the zoom to this level, 100% means normal size, 200% double size -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserSetZoomLevel( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, SetZoomLevel( htmlCommand.BodyConst().zoom() ) ); - - CefDoMessageLoopWork(); // tell cef to think one frame, Zoom is in a work queue and we want it to apply right away so think now - - // now tell if about the scrollbars we now have - ThreadBrowserHorizontalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); - ThreadBrowserVerticalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); -} - - -//----------------------------------------------------------------------------- -// Purpose: show the page source in notepad -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserViewSource( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->ViewSource() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: add a header to any requests we make -//----------------------------------------------------------------------------- -void CCEFThread::ThreadAddHeader( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - m_listClientHandlers[iClient]->AddHeader( htmlCommand.BodyConst().key().c_str(), htmlCommand.BodyConst().value().c_str() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: main thread is done with a paint buffer, tell our handler -//----------------------------------------------------------------------------- -void CCEFThread::ThreadNeedsPaintResponse( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - m_listClientHandlers[iClient]->SetTextureUploaded( htmlCommand.BodyConst().textureid() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: set the error strings to display on page load -//----------------------------------------------------------------------------- -void CCEFThread::ThreadBrowserErrorStrings( const CHTMLProtoBufMsg &cmd ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( cmd.BodyConst().browser_handle(), iClient ) ) - { - m_listClientHandlers[iClient]->SetErrorStrings( cmd.BodyConst().title().c_str(), cmd.BodyConst().header().c_str(), - cmd.BodyConst().cache_miss().c_str(), cmd.BodyConst().bad_url().c_str(), - cmd.BodyConst().connection_problem().c_str(), - cmd.BodyConst().proxy_problem().c_str(), cmd.BodyConst().unknown().c_str() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: return the zoom level for the current page, 100% means actual size, 200% double size -//----------------------------------------------------------------------------- -void CCEFThread::ThreadGetZoom( const CHTMLProtoBufMsg &htmlCmd ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCmd.BodyConst().browser_handle(), iClient ) ) - { - float flZoom = 0.0f; - if ( m_listClientHandlers[iClient]->GetBrowser() ) - flZoom = m_listClientHandlers[iClient]->GetBrowser()->GetZoomLevel(); - if ( flZoom == 0.0f ) - flZoom = 1.0f; - if ( flZoom > 100.0f ) - flZoom /= 100.0f; - CHTMLProtoBufMsg cmd( eHTMLCommands_GetZoomResponse ); - cmd.Body().set_zoom( flZoom ); - int m_iBrowser = htmlCmd.BodyConst().browser_handle(); - DISPATCH_MESSAGE( eHTMLCommands_GetZoomResponse ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: handler func to throw the cookie call to the cef IO thread -//----------------------------------------------------------------------------- -void IOT_SetCookie(const CefString& url, CefCookie* cookie, CThreadEvent *pEvent ) -{ - CefCookieManager::GetGlobalManager()->SetCookie(url, *cookie); - pEvent->Set(); -} - - -//----------------------------------------------------------------------------- -// Purpose: set this cookie into the cef instance -//----------------------------------------------------------------------------- -void CCEFThread::ThreadSetCookie( const CHTMLProtoBufMsg &htmlCommand ) -{ - CefCookie cookie; - cef_string_utf8_copy( htmlCommand.BodyConst().key().c_str(), htmlCommand.BodyConst().key().size(), &cookie.name ); - cef_string_utf8_copy( htmlCommand.BodyConst().value().c_str(), htmlCommand.BodyConst().value().size(), &cookie.value ); - cef_string_utf8_copy( htmlCommand.BodyConst().path().c_str(), htmlCommand.BodyConst().path().size(), &cookie.path ); - if ( htmlCommand.BodyConst().has_expires() ) - { - AssertMsg( false, "Cookie expiration not implemented -- rtime.cpp needs to be ported." ); - /* - cookie.has_expires = true; - CRTime rtExpire( (RTime32)htmlCommand.BodyConst().expires() ); - cookie.expires.year = rtExpire.GetLocalYear(); - cookie.expires.month = rtExpire.GetLocalMonth(); -#if !defined(OS_MACOSX) - cookie.expires.day_of_week = rtExpire.GetLocalDayOfWeek(); -#endif - cookie.expires.day_of_month = rtExpire.GetLocalMonth(); - cookie.expires.hour = rtExpire.GetLocalHour(); - cookie.expires.minute = rtExpire.GetLocalMinute(); - cookie.expires.second = rtExpire.GetLocalSecond(); - */ - } - - CThreadEvent event; - CefPostTask(TID_IO, NewCefRunnableFunction( IOT_SetCookie, htmlCommand.BodyConst().host().c_str(), &cookie, &event)); - event.Wait(); -} - - -struct CCefCookie -{ - CUtlString sValue; - CUtlString sName; - CUtlString sDomain; - CUtlString sPath; -}; -//----------------------------------------------------------------------------- -// Purpose: helper class to iterator cookies -//----------------------------------------------------------------------------- -class CookieVisitor : public CefCookieVisitor { -public: - CookieVisitor( CUtlVector *pVec, CThreadEvent *pEvent ) - { - m_pVecCookies = pVec; - m_pEvent = pEvent; - } - ~CookieVisitor() - { - m_pEvent->Set(); - } - - virtual bool Visit(const CefCookie& cookie, int count, int total, - bool& deleteCookie) { - - CCefCookie cookieCopy; - cookieCopy.sValue = cookie.value.str; - cookieCopy.sName = cookie.name.str; - cookieCopy.sDomain = cookie.domain.str; - cookieCopy.sPath = cookie.path.str; - m_pVecCookies->AddToTail( cookieCopy ); - return true; - } - -private: - CUtlVector *m_pVecCookies; - CThreadEvent *m_pEvent; - - IMPLEMENT_REFCOUNTING(CookieVisitor); -}; - - -//----------------------------------------------------------------------------- -// Purpose: handler func to throw the cookie call to the cef IO thread -//----------------------------------------------------------------------------- -void IOT_CookiesForURL(const CefString& url, CThreadEvent *pEvent, CUtlVector *pVecCookies ) -{ - CefCookieManager::GetGlobalManager()->VisitUrlCookies( url, false, new CookieVisitor( pVecCookies, pEvent ) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: get all the cookies for this URL -//----------------------------------------------------------------------------- -void CCEFThread::ThreadGetCookiesForURL( const CHTMLProtoBufMsg &htmlCommand ) -{ - CUtlVector vecCookies; - CThreadEvent event; - CefPostTask(TID_IO, NewCefRunnableFunction( IOT_CookiesForURL, htmlCommand.BodyConst().url().c_str(), &event, &vecCookies )); - event.Wait(); - - CHTMLProtoBufMsg cmd( eHTMLCommands_GetCookiesForURLResponse ); - int m_iBrowser = htmlCommand.BodyConst().browser_handle(); - cmd.Body().set_url( htmlCommand.BodyConst().url() ); - - FOR_EACH_VEC( vecCookies, i ) - { - CCookie *pCookie = cmd.Body().add_cookies(); - pCookie->set_name( vecCookies[i].sName ); - pCookie->set_value( vecCookies[i].sValue ); - pCookie->set_domain( vecCookies[i].sDomain ); - pCookie->set_path( vecCookies[i].sPath ); - } - - DISPATCH_MESSAGE( eHTMLCommands_GetCookiesForURLResponse ); -} - - -//----------------------------------------------------------------------------- -// Purpose: set the framerate to run CEF at -//----------------------------------------------------------------------------- -void CCEFThread::ThreadSetTargetFrameRate( const CHTMLProtoBufMsg &htmlCommand ) -{ - m_nTargetFrameRate = htmlCommand.BodyConst().ntargetframerate(); -} - - -//----------------------------------------------------------------------------- -// Purpose: hide any showing popup for this browser -//----------------------------------------------------------------------------- -void CCEFThread::ThreadHidePopup( const CHTMLProtoBufMsg &htmlCommand ) -{ - GET_BROSWER_FUNC( htmlCommand, HidePopup() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: request a full redraw of the client -//----------------------------------------------------------------------------- -void CCEFThread::ThreadFullRepaint( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - if ( m_listClientHandlers[iClient]->GetBrowser()->IsVisuallyNonEmpty() ) - { - int wide, tall; - m_listClientHandlers[iClient]->GetExpectedSize( wide, tall); - CefRect rect; - rect.x = rect.y = 0; - rect.width = wide; - rect.height = tall; - m_listClientHandlers[iClient]->GetBrowser()->Invalidate( rect ); - } - else - m_listClientHandlers[iClient]->GetBrowser()->Reload(); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: configure the options we want for cef -//----------------------------------------------------------------------------- -void CCEFThread::AppGetSettings(CefSettings& settings, CefRefPtr& app) -{ - settings.multi_threaded_message_loop = false; -#if defined(OS_WIN) - settings.auto_detect_proxy_settings_enabled = true; -#endif - - CefString(&settings.cache_path) = m_sHTMLCacheDir; - CefString(&settings.product_version) = "Steam"; -// CefString(&settings.log_file) = -/*#ifdef WIN32 - settings.graphics_implementation = ANGLE_IN_PROCESS_COMMAND_BUFFER; -#else*/ - settings.graphics_implementation = DESKTOP_IN_PROCESS_COMMAND_BUFFER; -//#endif -} - -//----------------------------------------------------------------------------- -// Purpose: clean up the temp folders cef can leave around on crash -//----------------------------------------------------------------------------- -void CCEFThread::CleanupTempFolders() -{ - /* - // Temporarily commented out to avoid bringing in additional code. -#if defined( WIN32 ) - char rgchPath[MAX_PATH]; - if ( GetTempPathA( Q_ARRAYSIZE( rgchPath ), rgchPath ) == 0 ) - return; - - CUtlString strPath = rgchPath; -#elif defined( LINUX ) || defined( OSX ) - // TMPDIR first, T_tmpdir next, /tmp last. - char *pszDir = getenv( "TMPDIR" ); - if ( pszDir == NULL ) - { - pszDir = P_tmpdir; - if ( pszDir == NULL ) - pszDir = "/tmp"; - } - if ( pszDir == NULL ) - return; - - CUtlString strPath = pszDir; -#endif - - if ( strPath[strPath.Length()-1] != CORRECT_PATH_SEPARATOR ) - strPath += CORRECT_PATH_SEPARATOR_S; - - CUtlString strSearch = strPath; - strSearch += "scoped_dir*"; - CDirIterator tempDirIterator( strSearch.String() ); - - while ( tempDirIterator.BNextFile() ) - { - if ( tempDirIterator.BCurrentIsDir() ) - { - CUtlString sStrDir = strPath; - sStrDir += tempDirIterator.CurrentFileName(); - BRemoveDirectoryRecursive( sStrDir ); - } - } - */ -} - - -//----------------------------------------------------------------------------- -// Purpose: main thread for pumping CEF, get commands from the main thread and dispatches responses to it -//----------------------------------------------------------------------------- -int CCEFThread::Run() -{ - { // scope to trigger destructors before setting the we have exited event - CefSettings settings; - CefRefPtr app; - - // blow away any temp folders CEF left lying around if we crashed last - CleanupTempFolders(); - - // Populate the settings based on command line arguments. - AppGetSettings(settings, app); - settings.pack_loading_disabled = true; - - // Initialize CEF. - CefInitialize(settings, app, ""); - - #if defined( VPROF_ENABLED ) -// CVProfile *pProfile = GetVProfProfileForCurrentThread(); - #endif - - CLimitTimer timer; - CLimitTimer timerLastCefThink; // track when we think cef so we can do it at a minimum of 10hz - timerLastCefThink.SetLimit( k_nMillion ); // 1Hz min think time -#ifdef WIN32 - CLimitTimer timerLastFlashFullscreenThink; // track when we think cef so we can do it at a minimum of 10hz - timerLastFlashFullscreenThink.SetLimit( k_nMillion * k_nMillion ); // think again in the distance future - bool bInitialThinkAfterInput = false; -#endif - while( !m_bExit ) - { - #ifdef OSX - void *pool = CreateAutoReleasePool(); - #endif - - if ( m_bSleepForValidate ) - { - m_bSleepingForValidate = true; - ThreadSleep( 100 ); - continue; - } - m_bSleepingForValidate = false; - - m_bSawUserInputThisFrame = false; - - #if defined( VPROF_ENABLED ) -// if ( pProfile ) -// pProfile->MarkFrame( "UI CEF HTML Thread" ); - #endif - // Limit animation frame rate - timer.SetLimit( k_nMillion/m_nTargetFrameRate ); - - // run any pending commands, get ack'd paint buffers - { - VPROF_BUDGET( "CCEFThread - RunCurrentCommands()", VPROF_BUDGETGROUP_VGUI ); - RunCurrentCommands(); - } - - // now let cef think - if ( !m_bExit && ( m_listClientHandlers.Count() || timerLastCefThink.BLimitReached() ) && m_nTargetFrameRate > 0 ) - { - VPROF_BUDGET( "CCEFThread - CefDoMessageLoopWork()", VPROF_BUDGETGROUP_TENFOOT ); - CefDoMessageLoopWork(); - timerLastCefThink.SetLimit( k_nMillion ); // 1Hz min think time - } - #ifdef OSX - ReleaseAutoReleasePool( pool ); - #endif - - // push any changes to scrollbar data and refresh HTML element hover states - { - VPROF_BUDGET( "CCEFThread - Scroll", VPROF_BUDGETGROUP_VGUI ); - FOR_EACH_LL( m_listClientHandlers, i ) - { - int nBrowser = BROWSER_HANDLE_FROM_INDEX_SERIAL( i, m_listClientHandlers[i]->NSerial() ); - ThreadBrowserHorizontalScrollBarSizeHelper( nBrowser, false ); - ThreadBrowserVerticalScrollBarSizeHelper( nBrowser, false ); - - // workaround a CEF issue where mouse hover states don't update after scrolling - m_listClientHandlers[i]->RefreshCEFHoverStatesAfterScroll(); - } - } - - { - VPROF_BUDGET( "CCEFThread - SendSizeChangeEvents", VPROF_BUDGETGROUP_VGUI ); - SendSizeChangeEvents(); - } - - //see if we need a paint - { - VPROF_BUDGET( "CCEFThread - Paint", VPROF_BUDGETGROUP_VGUI ); - FOR_EACH_LL( m_listClientHandlers, i ) - { - if ( !m_listClientHandlers[i]->GetBrowser() ) - continue; - - m_listClientHandlers[i]->Paint(); - if ( m_listClientHandlers[i]->BPaintBufferReady() && m_listClientHandlers[i]->BNeedsPaint() ) - { - uint32 textureID = m_listClientHandlers[i]->FlipTexture(); - const byte *pRGBA = m_listClientHandlers[i]->PComposedTextureData( textureID ); - if ( pRGBA ) - { - CClientHandler *pHandler = m_listClientHandlers[i]; - pHandler->Lock(); - if ( pHandler->BPendingScreenShot() ) - { - pHandler->SavePageToJPEGIfNeeded( pHandler->GetBrowser(), pRGBA, pHandler->GetTextureWide(), pHandler->GetTextureTall() ); - } - CHTMLProtoBufMsg cmd( eHTMLCommands_NeedsPaint ); - cmd.Body().set_browser_handle( BROWSER_HANDLE_FROM_INDEX_SERIAL( i, pHandler->NSerial() ) ); - cmd.Body().set_wide( pHandler->GetTextureWide() ); - cmd.Body().set_tall( pHandler->GetTextureTall() ); - cmd.Body().set_rgba( (uint64)pRGBA ); - cmd.Body().set_pageserial( pHandler->GetPageSerial() ); - cmd.Body().set_textureid( textureID ); - cmd.Body().set_updatex( pHandler->GetUpdateX() ); - cmd.Body().set_updatey( pHandler->GetUpdateY() ); - cmd.Body().set_updatewide( pHandler->GetUpdateWide() ); - cmd.Body().set_updatetall( pHandler->GetUpdateTall() ); - cmd.Body().set_scrollx( pHandler->GetBrowser()->HorizontalScroll() ); - cmd.Body().set_scrolly( pHandler->GetBrowser()->VerticalScroll() ); - - if ( pHandler->BPopupVisibleAndPainted() ) // add in the combo box's texture data if visible - { - int x,y,wide,tall; // popup sizes - pHandler->PopupRect( x, y, wide, tall ); - cmd.Body().set_combobox_rgba( (uint64)pHandler->PPopupTextureDataCached() ); - cmd.Body().set_combobox_wide( wide ); - cmd.Body().set_combobox_tall( tall ); - } - - // Texture update rect has now been pushed to main thread - pHandler->ClearUpdateRect(); - - HTMLCommandBuffer_t *pBuf = g_CEFThread.GetFreeCommandBuffer( eHTMLCommands_NeedsPaint, i ); - cmd.SerializeCrossProc( &pBuf->m_Buffer ); - pHandler->Unlock(); - - g_CEFThread.PushResponse( pBuf ); - } - else - { - m_listClientHandlers[i]->SetTextureUploaded( textureID ); - } - } - } - } - -#ifdef WIN32 - if ( m_bSawUserInputThisFrame ) - { - if ( timerLastFlashFullscreenThink.CMicroSecLeft() > k_nMillion/10 || timerLastFlashFullscreenThink.BLimitReached() ) - { - timerLastFlashFullscreenThink.SetLimit( k_nMillion/10 ); // check in 100msec - } - bInitialThinkAfterInput = true; - } - - if ( m_listClientHandlers.Count() && timerLastFlashFullscreenThink.BLimitReached() ) - { - CheckForFullScreenFlashControl(); - if ( ( !m_bFullScreenFlashVisible && bInitialThinkAfterInput ) || m_bFullScreenFlashVisible ) - { - timerLastFlashFullscreenThink.SetLimit( k_nMillion ); // could be a slow machine, check again in 1 sec - } - else - { - timerLastFlashFullscreenThink.SetLimit( k_nMillion * k_nMillion ); // think again in the distance future - } - - bInitialThinkAfterInput= false; - } -#endif - - { - VPROF_BUDGET( "Sleep - FPS Limiting", VPROF_BUDGETGROUP_TENFOOT ); - if ( timer.BLimitReached() ) - ThreadSleep( 1 ); - else - m_WakeEvent.Wait( timer.CMicroSecLeft() / 1000 ); - } - } - - FOR_EACH_LL( m_listClientHandlers, i ) - { - if ( m_listClientHandlers[i] ) - m_listClientHandlers[i]->CloseBrowser(); - m_listClientHandlers[i] = NULL;; - } - m_listClientHandlers.RemoveAll(); - - CefDoMessageLoopWork(); // pump the message loop to clear the close browser calls from above - - CefShutdown(); - } - m_eventDidExit.Set(); - return 0; -} - - -//----------------------------------------------------------------------------- -// Purpose: special code to sniff for flash doing its usual naughty things -//----------------------------------------------------------------------------- -void CCEFThread::CheckForFullScreenFlashControl() -{ -#ifdef WIN32 - VPROF_BUDGET( "Searching for Flash fullscreen - FindWindowEx", VPROF_BUDGETGROUP_TENFOOT ); - - // see if we need to drag the flash fullscreen window to front - HWND flashfullscreenHWND = ::FindWindowEx( NULL, NULL, "ShockwaveFlashFullScreen", NULL ); - if ( flashfullscreenHWND ) - { - DWORD proccess_id; - GetWindowThreadProcessId( flashfullscreenHWND, &proccess_id); - TCHAR exe_path[MAX_PATH]; - GetModuleFileName( GetModuleHandle(NULL), exe_path, MAX_PATH); - HANDLE hmodule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proccess_id); - MODULEENTRY32 mod = { sizeof(MODULEENTRY32) }; - if ( Module32First( hmodule, &mod) ) - { - if ( Q_stricmp(mod.szExePath, exe_path) == 0 ) - { - if ( !m_bFullScreenFlashVisible ) - { - m_bFullScreenFlashVisible = true; - m_flashfullscreenHWND = flashfullscreenHWND; - - FOR_EACH_LL( m_listClientHandlers, i ) - { - if ( m_listClientHandlers[i] ) - m_listClientHandlers[i]->GetRenderHandler()->OnEnterFullScreen( m_listClientHandlers[i]->GetBrowser() ); - } - - SetForegroundWindow( m_flashfullscreenHWND ); - } - } - else - { - if ( m_bFullScreenFlashVisible ) - { - m_bFullScreenFlashVisible = false; - m_flashfullscreenHWND = NULL; - FOR_EACH_LL( m_listClientHandlers, i ) - { - if ( m_listClientHandlers[i] ) - m_listClientHandlers[i]->GetRenderHandler()->OnExitFullScreen( m_listClientHandlers[i]->GetBrowser() ); - } - } - } - } - CloseHandle( hmodule ); - } - else - { - if ( m_bFullScreenFlashVisible ) - { - m_bFullScreenFlashVisible = false; - m_flashfullscreenHWND = NULL; - FOR_EACH_LL( m_listClientHandlers, i ) - { - if ( m_listClientHandlers[i] ) - m_listClientHandlers[i]->GetRenderHandler()->OnExitFullScreen( m_listClientHandlers[i]->GetBrowser() ); - } - } - } -#else -#warning "Do we need to sniff for fullscreen flash and it breaking us?" -#endif -} - - -#ifdef DBGFLAG_VALIDATE -//----------------------------------------------------------------------------- -// Purpose: validate mem -//----------------------------------------------------------------------------- -void CCEFThread::Validate( CValidator &validator, const tchar *pchName ) -{ - // hacky but reliable way to avoid both vgui and panorama validating all this stuff twice - if ( !validator.IsClaimed( m_sHTMLCacheDir.Access() ) ) - { - VALIDATE_SCOPE(); - ValidateObj( m_sHTMLCacheDir ); - ValidateObj( m_sCookiePath ); - ValidateObj( m_listClientHandlers ); - FOR_EACH_LL( m_listClientHandlers, i ) - { - ValidatePtr( m_listClientHandlers[i] ); - } - ValidateObj( m_vecQueueCommands ); - FOR_EACH_VEC( m_vecQueueCommands, i ) - { - ValidatePtr( m_vecQueueCommands[i] ); - } - ValidateObj( m_vecQueueResponses ); - FOR_EACH_VEC( m_vecQueueResponses, i ) - { - ValidatePtr( m_vecQueueResponses[i] ); - } - - ValidateObj( m_tslUnsedBuffers ); - { - CTSList::Node_t *pNode = m_tslUnsedBuffers.Detach(); - while ( pNode ) - { - CTSList::Node_t *pNext = (CTSList::Node_t *)pNode->Next; - ValidatePtr( pNode->elem ); - m_tslUnsedBuffers.Push( pNode ); - pNode = pNext; - } - } - - ValidateObj( m_tslCommandBuffers ); - ValidateObj( m_tslResponseBuffers ); -} -} -#endif - - -//----------------------------------------------------------------------------- -// Purpose: turn on CEF and its supporting thread -//----------------------------------------------------------------------------- -void ChromeInit( const char *pchHTMLCacheDir, const char *pchCookiePath ) -{ - Assert( !g_CEFThread.IsAlive() ); - g_CEFThread.SetCEFPaths( pchHTMLCacheDir, pchCookiePath ); - g_CEFThread.SetName( "UICEFThread" ); - g_CEFThread.Start(); -} - - -//----------------------------------------------------------------------------- -// Purpose: turn off CEF -//----------------------------------------------------------------------------- -void ChromeShutdown() -{ - g_CEFThread.TriggerShutdown(); - g_CEFThread.Join( 20 *k_nThousand ); -} - - -#ifdef DBGFLAG_VALIDATE -//----------------------------------------------------------------------------- -// Purpose: suspend the cef thread so we can validate mem -//----------------------------------------------------------------------------- -bool ChromePrepareForValidate() -{ - g_CEFThread.SleepForValidate(); - while ( !g_CEFThread.BSleepingForValidate() ) - ThreadSleep( 100 ); - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: wake the cef thread back up -//----------------------------------------------------------------------------- -bool ChromeResumeFromValidate() -{ - g_CEFThread.WakeFromValidate(); - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void ChromeValidate( CValidator &validator, const char *pchName ) -{ - g_CEFThread.Validate( validator, "g_CEFThread" ); -} -#endif - - -//----------------------------------------------------------------------------- -// Purpose: set this cookie to be used by cef -//----------------------------------------------------------------------------- -bool ChromeSetWebCookie( const char *pchHostname, const char *pchName, const char *pchValue, const char *pchPath, RTime32 nExpires ) -{ - CHTMLProtoBufMsg< CMsgSetCookie > cmd( eHTMLCommands_SetCookie ); - cmd.Body().set_value( pchValue ); - cmd.Body().set_key( pchName ); - cmd.Body().set_path( pchPath ); - cmd.Body().set_host( pchHostname ); - if ( nExpires ) - cmd.Body().set_expires( nExpires ); - - HTMLCommandBuffer_t *pBuf = g_CEFThread.GetFreeCommandBuffer( eHTMLCommands_SetCookie, -1 ); - cmd.SerializeCrossProc( &pBuf->m_Buffer ); - g_CEFThread.PushCommand( pBuf ); - g_CEFThread.WakeThread(); - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: set this cookie to be used by cef -//----------------------------------------------------------------------------- -bool ChromeGetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) -{ - pstrValue->Clear(); - - { - CHTMLProtoBufMsg cmd( eHTMLCommands_GetCookiesForURL ); - cmd.Body().set_url( pchURL ); - - HTMLCommandBuffer_t *pCmd = g_CEFThread.GetFreeCommandBuffer( eHTMLCommands_GetCookiesForURL, -1 ); - cmd.SerializeCrossProc( &pCmd->m_Buffer ); - g_CEFThread.PushCommand( pCmd ); - } - - HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForResponse( eHTMLCommands_GetCookiesForURLResponse, -1 ); - if ( pBuf ) - { - CHTMLProtoBufMsg< CMsgGetCookiesForURLResponse > cmdResponse( eHTMLCommands_GetCookiesForURLResponse ); - if ( cmdResponse.BDeserializeCrossProc( &pBuf->m_Buffer ) ) - { - for ( int i = 0; i < cmdResponse.BodyConst().cookies_size(); i++ ) - { - const CCookie &cookie = cmdResponse.BodyConst().cookies(i); - if ( cookie.name() == pchName ) - pstrValue->Set( cookie.value().c_str() ); - } - } - g_CEFThread.ReleaseCommandBuffer( pBuf ); - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: set the build number to report in our user agent -//----------------------------------------------------------------------------- -void ChromeSetClientBuildID( uint64 ulBuildID ) -{ - sm_ulBuildID = ulBuildID; -} - - -//----------------------------------------------------------------------------- -// Purpose: constructor -//----------------------------------------------------------------------------- -CChromePainter::CChromePainter( CClientHandler *pParent ) -{ - m_iNextTexture = 0; - m_iTexturesInFlightBits = 0; - m_pParent = pParent; - m_bUpdated = false; - m_bPopupVisible = false; -} - - -//----------------------------------------------------------------------------- -// Purpose: destructor -//----------------------------------------------------------------------------- -CChromePainter::~CChromePainter() -{ -} - -//----------------------------------------------------------------------------- -// Purpose: cef is calling us back and saying it updated the html texture -//----------------------------------------------------------------------------- -void CChromePainter::OnPaint(CefRefPtr browser, PaintElementType type, const RectList& dirtyRects, const void* buffer) -{ - VPROF_BUDGET( "CChromePainter::DrawSubTextureRGBA", VPROF_BUDGETGROUP_VGUI ); - - int wide, tall; - browser->GetSize( type, wide, tall ); - - if ( wide <= 0 || tall <= 0 ) - return; - - if ( type == PET_POPUP ) - { - m_nPopupWide = wide; - m_nPopupTall = tall; - - m_PopupTexture.EnsureCount( tall*wide*4 ); - Q_memcpy( m_PopupTexture.Base(), buffer, tall*wide*4 ); - - // force a recomposition + display whenever painting a popup - m_bUpdated = true; - } - else - { - // main browser painting - - if ( !m_pParent->IsVisuallyNonEmpty() ) - { - return; - } - - // If there were no dirty regions (unlikely), perhaps due to a bug, be conservative and paint all - if ( dirtyRects.empty() ) - { - m_MainTexture.MarkAllDirty(); - } - else - { - for ( RectList::const_iterator iter = dirtyRects.begin(); iter != dirtyRects.end(); ++iter ) - { - m_MainTexture.MarkDirtyRect( iter->x, iter->y, iter->x + iter->width, iter->y + iter->height ); - } - } - - // Refresh all dirty main texture pixels from the chromium rendering buffer - if ( m_MainTexture.BUpdatePixels( (byte*)buffer, wide, tall ) ) - { - // at least one pixel in the main texture has changed - m_bUpdated = true; - - // Notify the main thread that this newly painted region is dirty - m_UpdateRect.MarkDirtyRect( m_MainTexture ); - - // Merge update region into all buffer textures so that at composition time, - // they know to copy the union of all updates since the last composition - for ( size_t i = 0; i < Q_ARRAYSIZE(m_Texture); ++i ) - { - m_Texture[i].MarkDirtyRect( m_MainTexture ); - } - } - - // The main texture is now a clean copy of chromium's canvas backing - m_MainTexture.MarkAllClean(); - } -} - -//----------------------------------------------------------------------------- -// Purpose: true if we have had a paint call from cef -//----------------------------------------------------------------------------- -bool CChromePainter::BUpdated() -{ - return m_bUpdated; -} - - -//----------------------------------------------------------------------------- -// Purpose: force the updated state -//----------------------------------------------------------------------------- -void CChromePainter::SetUpdated( bool state ) -{ - m_bUpdated = state; -} - - -//----------------------------------------------------------------------------- -// Purpose: move to the next html texture to render into -//----------------------------------------------------------------------------- -uint32 CChromePainter::FlipTexture() -{ - int iTex = m_iNextTexture; - m_iTexturesInFlightBits |= ( 1< 0 && m_MainTexture.GetTall() > 0) && !( m_iTexturesInFlightBits & (1< parentBrowser, - const CefPopupFeatures& popupFeatures, - CefWindowInfo& windowInfo, - const CefString& url, - bool bForeground, - CefRefPtr& client, - CefBrowserSettings& settings ) -{ - CHTMLProtoBufMsg cmd( eHTMLCommands_OpenNewTab ); - cmd.Body().set_url( url.c_str() ); - cmd.Body().set_bforeground( bForeground ); - - DISPATCH_MESSAGE( eHTMLCommands_OpenNewTab ); - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Called before a new popup window is created. The |parentBrowser| parameter -// will point to the parent browser window. The |popupFeatures| parameter will -// contain information about the style of popup window requested. Return false -// to have the framework create the new popup window based on the parameters -// in |windowInfo|. Return true to cancel creation of the popup window. By -// default, a newly created popup window will have the same client and -// settings as the parent window. To change the client for the new window -// modify the object that |client| points to. To change the settings for the -// new window modify the |settings| structure. -//----------------------------------------------------------------------------- -bool CClientHandler::OnBeforePopup(CefRefPtr parentBrowser, - const CefPopupFeatures& popupFeatures, - CefWindowInfo& windowInfo, - const CefString& url, - CefRefPtr& client, - CefBrowserSettings& settings) -{ - // If it's a steam:// url we already have a scheme handler installed, however that's too late to block the frame navigating - // and we'll end up loading a blank new window. So preempt that happening here and handle early returning that we've handled so - // chromium won't actually change URLs or navigate at all. - if ( url.size() > 0 && ( Q_stristr( url.c_str(), "steam://" ) || Q_stristr( url.c_str(), "steambeta://" ) ) && Q_stristr( url.c_str(), "/close" ) == NULL ) - { - CStrAutoEncode urlString( url.c_str() ); - CHTMLProtoBufMsg cmd( eHTMLCommands_OpenSteamURL ); - cmd.Body().set_url( urlString.ToString() ); - DISPATCH_MESSAGE( eHTMLCommands_OpenSteamURL ); - - return true; - } - - CStrAutoEncode urlString( url.c_str() ); - static bool bInPopup = false; - // if we get an empty url string when loading a new popup page just don't load it, we don't support the make a - // new popup and .write() into the buffer to make the contents because we want to make a whole new VGUI HTML object - // that contains the webkit widget for that popup, not allow this inline one - if ( urlString.ToString() && Q_strlen( urlString.ToString() ) > 0 ) - { - if ( !bInPopup ) - { - bInPopup = true; - CHTMLProtoBufMsg cmd( eHTMLCommands_PopupHTMLWindow ); - cmd.Body().set_url( urlString.ToString() ); - if ( popupFeatures.xSet ) - cmd.Body().set_x( popupFeatures.x ); - if ( popupFeatures.ySet ) - cmd.Body().set_y( popupFeatures.y ); - if ( popupFeatures.widthSet ) - cmd.Body().set_wide( popupFeatures.width ); - if ( popupFeatures.heightSet ) - cmd.Body().set_tall( popupFeatures.height ); - - DISPATCH_MESSAGE( eHTMLCommands_PopupHTMLWindow ); - bInPopup = false; - return true; - } - } - if ( !bInPopup ) - { - return true; - } - - return false; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Event called after a new window is created. The return value is currently -// ignored. -//----------------------------------------------------------------------------- -void CClientHandler::OnAfterCreated(CefRefPtr browser) -{ - Lock(); - if ( !m_Browser ) - { - // We need to keep the main child window, but not popup windows - m_Browser = browser; - browser->SetShowScrollBars( false ); - SetBrowserAgent( browser ); - if ( m_nExpectedWide > 0 && m_nExpectedTall > 0 ) - browser->SetSize( PET_VIEW, m_nExpectedWide, m_nExpectedTall ); - - CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserReady ); - DISPATCH_MESSAGE( eHTMLCommands_BrowserReady ); - } - Unlock(); -} - - - -//----------------------------------------------------------------------------- -// Purpose: -// Event called when the page title changes. The return value is currently -// ignored. -//----------------------------------------------------------------------------- -void CClientHandler::OnTitleChange(CefRefPtr browser, const CefString& title) -{ - if ( !title.empty() ) - { - CHTMLProtoBufMsg cmd( eHTMLCommands_SetHTMLTitle ); - cmd.Body().set_title( title ); - - DISPATCH_MESSAGE( eHTMLCommands_SetHTMLTitle ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Event called before browser navigation. The client has an opportunity to -// modify the |request| object if desired. Return RV_HANDLED to cancel -// navigation. -//----------------------------------------------------------------------------- -bool CClientHandler::OnBeforeBrowse(CefRefPtr browser, - CefRefPtr frame, - CefRefPtr request, - NavType navType, - bool isRedirect, - bool isNewTabRequest - ) -{ - std::string sURL = request->GetURL(); - - // If it's a steam:// url we already have a scheme handler installed, however that's too late to block the frame navigating - // and we'll end up loading a blank page. So preempt that happening here and handle early returning that we've handled so - // chromium won't actually change URLs or navigate at all. - if ( sURL.size() > 0 && (sURL.find( "steam://" ) == 0 || sURL.find( "steambeta://" ) == 0) && sURL.find( "/close" ) == std::wstring::npos ) - { - CHTMLProtoBufMsg cmd( eHTMLCommands_OpenSteamURL ); - cmd.Body().set_url( CStrAutoEncode( request->GetURL().c_str() ).ToString() ); - DISPATCH_MESSAGE( eHTMLCommands_OpenSteamURL ); - - return true ; - } - - if ( isNewTabRequest ) - return false; - - // We only care about these on the main frame - if( !frame.get() || !frame->IsMain() ) - return false; - - if ( request->GetPostData() ) - { - CefPostData::ElementVector elements; - request->GetPostData()->GetElements( elements ); - CefPostData::ElementVector::const_iterator it = elements.begin(); - m_strPostData = ""; - CUtlVector vecPostBytes; - while ( it != elements.end() ) - { - if ( it->get()->GetType() == PDE_TYPE_BYTES ) - { - size_t nBytes = it->get()->GetBytesCount(); - int curInsertPos = vecPostBytes.Count(); - vecPostBytes.EnsureCount( curInsertPos + nBytes + 1 ); - it->get()->GetBytes( nBytes, vecPostBytes.Base() + curInsertPos ); - vecPostBytes[ curInsertPos + nBytes ] = 0; - } - it++; - } - - m_strPostData = vecPostBytes.Base(); - } - else - m_strPostData = ""; - - CStrAutoEncode strURL( sURL.c_str() ); - - if ( isRedirect ) - m_strLastRedirectURL = strURL.ToString(); - - bool rv = false; - - { - // scope this so the wait below doesn't keep this allocation on the stack - CHTMLProtoBufMsg cmd( eHTMLCommands_StartRequest ); - cmd.Body().set_url( strURL.ToString() ); - CefString frameName = frame->GetName(); - if ( !frameName.empty() ) - cmd.Body().set_target( frameName.c_str() ); - cmd.Body().set_postdata( m_strPostData ); - cmd.Body().set_bisredirect( isRedirect ); - - DISPATCH_MESSAGE( eHTMLCommands_StartRequest ); - } - - HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_StartRequestResponse, m_iBrowser ); - if ( pBuf ) - { - CHTMLProtoBufMsg< CMsgStartRequestResponse > cmd( eHTMLCommands_StartRequestResponse ); - if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) - { - if ( !cmd.BodyConst().ballow() ) - rv = true ; - } - g_CEFThread.ReleaseCommandBuffer( pBuf ); - } - - if ( m_Snapshot.m_sURLSnapshot.IsValid() ) - m_Snapshot.m_flRequestTimeout = Plat_FloatTime(); // before we change URL lets queue up a snapshot for the next paint - - return rv; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Event called when the browser begins loading a page. The |frame| pointer -// will be empty if the event represents the overall load status and not the -// load status for a particular frame. The return value is currently ignored. -//----------------------------------------------------------------------------- -void CClientHandler::OnLoadStart(CefRefPtr browser, - CefRefPtr frame, bool bIsNewNavigation ) -{ - if ( !frame.get() ) - return; - - { - if ( !frame->IsMain() ) - return; - - std::wstring sURL = frame->GetURL(); - if ( sURL.empty() ) - return; - - CStrAutoEncode url( sURL.c_str() ); - m_strCurrentUrl = url.ToString(); - - if ( m_strCurrentUrl.IsEmpty() ) - return; - - bool bIsRedirect = false; - if ( m_strCurrentUrl == m_strLastRedirectURL ) - bIsRedirect = true; - - CHTMLProtoBufMsg cmd( eHTMLCommands_URLChanged ); - cmd.Body().set_url( url.ToString() ); - cmd.Body().set_bnewnavigation( bIsNewNavigation ); - - if ( !m_strPostData.IsEmpty() ) - cmd.Body().set_postdata( m_strPostData.String() ); - - cmd.Body().set_bisredirect( bIsRedirect ); - CefString frameName = frame->GetName(); - if ( !frameName.empty() ) - cmd.Body().set_pagetitle( frameName.c_str() ); - - DISPATCH_MESSAGE( eHTMLCommands_URLChanged ); -} - - { - CHTMLProtoBufMsg cmd( eHTMLCommands_CanGoBackandForward ); - cmd.Body().set_bgoback( browser->CanGoBack() ); - cmd.Body().set_bgoforward( browser->CanGoForward() ); - DISPATCH_MESSAGE( eHTMLCommands_CanGoBackandForward ); - } - - m_nPageSerial = m_nPendingPageSerial; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Event called when the browser is done loading a page. The |frame| pointer -// will be empty if the event represents the overall load status and not the -// load status for a particular frame. This event will be generated -// irrespective of whether the request completes successfully. The return -// value is currently ignored. -//----------------------------------------------------------------------------- -void CClientHandler::OnLoadEnd(CefRefPtr browser, - CefRefPtr frame, - int httpStatusCode, CefRefPtr request ) -{ - // We only care about these on the main frame - if( !frame.get() || !frame->IsMain() ) - return; - - { - CHTMLProtoBufMsg cmd( eHTMLCommands_FinishedRequest ); - cmd.Body().set_url( CStrAutoEncode( browser->GetMainFrame()->GetURL().c_str() ).ToString() ); - CefString frameName = browser->GetMainFrame()->GetName(); - if ( !frameName.empty() ) - cmd.Body().set_pagetitle( frameName.c_str() ); - - if ( request.get() ) - { - CefRequest::HeaderMap headerMap; - request->GetHeaderMap( headerMap ); - - CefRequest::HeaderMap::const_iterator it; - for(it = headerMap.begin(); it != headerMap.end(); ++it) - { - CHTMLHeader *pHeader = cmd.Body().add_headers(); - if ( !it->first.empty() ) - pHeader->set_key( it->first.c_str() ); - if ( !it->second.empty() ) - pHeader->set_value( it->second.c_str() ); - } - - CefRefPtr pRefSecurityDetails = request->SecurityDetails(); - CHTMLPageSecurityInfo *pSecurityInfo = cmd.Body().mutable_security_info(); - if ( pRefSecurityDetails.get() ) - { - pSecurityInfo->set_bissecure( pRefSecurityDetails->BIsSecure() ); - pSecurityInfo->set_bhascerterror( pRefSecurityDetails->BHasCertError() ); - pSecurityInfo->set_issuername( pRefSecurityDetails->PchCertIssuer() ); - pSecurityInfo->set_certname( pRefSecurityDetails->PchCertCommonName() ); - pSecurityInfo->set_certexpiry( pRefSecurityDetails->TCertExpiry() ); - pSecurityInfo->set_bisevcert( pRefSecurityDetails->BIsEVCert() ); - pSecurityInfo->set_ncertbits( pRefSecurityDetails->NCertBits() ); - } - else - { - pSecurityInfo->set_bissecure( false ); - } - } - - DISPATCH_MESSAGE( eHTMLCommands_FinishedRequest ); - } - - { - CHTMLProtoBufMsg cmd( eHTMLCommands_CanGoBackandForward ); - cmd.Body().set_bgoback( browser->CanGoBack() ); - cmd.Body().set_bgoforward( browser->CanGoForward() ); - DISPATCH_MESSAGE( eHTMLCommands_CanGoBackandForward ); - } - - if ( m_Snapshot.m_sURLSnapshot.IsValid() ) - m_Snapshot.m_flRequestTimeout = Plat_FloatTime(); // finished page load, lets queue up a snapshot for the next paint -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Called when the browser fails to load a resource. |errorCode| is the -// error code number and |failedUrl| is the URL that failed to load. To -// provide custom error text assign the text to |errorText| and return -// RV_HANDLED. Otherwise, return RV_CONTINUE for the default error text. -//----------------------------------------------------------------------------- -bool CClientHandler::OnLoadError(CefRefPtr browser, - CefRefPtr frame, - ErrorCode errorCode, - const CefString& failedUrl, - CefString& errorText) -{ - // If it's a steam:// url we always get an error, but we handle it ok internally already, just ignore - if ( failedUrl.size() > 0 && ( Q_stristr( failedUrl.c_str(), "steam://" ) || Q_stristr( failedUrl.c_str(), "steambeta://" ) ) ) - return false; - - const char *pchDetail = NULL; - switch ( errorCode ) - { - case ERR_ABORTED: - // We'll get this in cases where we just start another URL before finishing a previous and such, don't show it. - return false; - break; - case ERR_CACHE_MISS: - pchDetail = m_sErrorCacheMiss; - break; - case ERR_UNKNOWN_URL_SCHEME: - case ERR_INVALID_URL: - pchDetail = m_sErrorBadURL; - break; - case ERR_CONNECTION_CLOSED: - case ERR_CONNECTION_RESET: - case ERR_CONNECTION_REFUSED: - case ERR_CONNECTION_ABORTED: - case ERR_CONNECTION_FAILED: - case ERR_NAME_NOT_RESOLVED: - case ERR_INTERNET_DISCONNECTED: - case ERR_CONNECTION_TIMED_OUT: - pchDetail = m_sErrorConnectionProblem; - break; - case ERR_UNEXPECTED_PROXY_AUTH: - case ERR_EMPTY_PROXY_LIST: - pchDetail = m_sErrorProxyProblem; - break; - default: - pchDetail = m_sErrorUnknown; - break; - } - - char rgchError[4096]; - Q_snprintf( rgchError, Q_ARRAYSIZE( rgchError ), - "" - "" - "%s" - "" - "" - "

%s%d

" - "

" - "%s" - "

" - "" - "", - m_sErrorTitle.String(), - m_sErrorHeader.String(), - errorCode, - pchDetail ); - - errorText = rgchError; - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Event called before a resource is loaded. To allow the resource to load -// normally return RV_CONTINUE. To redirect the resource to a new url -// populate the |redirectUrl| value and return RV_CONTINUE. To specify -// data for the resource return a CefStream object in |resourceStream|, set -// 'mimeType| to the resource stream's mime type, and return RV_CONTINUE. -// To cancel loading of the resource return RV_HANDLED. -//----------------------------------------------------------------------------- -bool CClientHandler::OnBeforeResourceLoad(CefRefPtr browser, - CefRefPtr request, - CefString& redirectUrl, - CefRefPtr& resourceStream, - CefRefPtr response, - int loadFlags) -{ - CHTMLProtoBufMsg cmd( eHTMLCommands_LoadingResource ); - cmd.Body().set_url( CStrAutoEncode( request->GetURL().c_str() ).ToString() ); - DISPATCH_MESSAGE( eHTMLCommands_LoadingResource ); - - // insert custom headers - CefRequest::HeaderMap headerMap; - request->GetHeaderMap( headerMap ); - FOR_EACH_VEC( m_vecHeaders, i ) - { - headerMap.insert( m_vecHeaders[i] ); - } - - request->SetHeaderMap( headerMap ); - - return false; -} - - - -//----------------------------------------------------------------------------- -// Purpose: -// Run a JS alert message. Return RV_CONTINUE to display the default alert -// or RV_HANDLED if you displayed a custom alert. -//----------------------------------------------------------------------------- -bool CClientHandler::OnJSAlert(CefRefPtr browser, - CefRefPtr frame, - const CefString& message) -{ - { - // scope this so the wait below doesn't keep this allocation on the stack - CHTMLProtoBufMsg cmd( eHTMLCommands_JSAlert ); - cmd.Body().set_message( message.c_str() ); - DISPATCH_MESSAGE( eHTMLCommands_JSAlert ); - } - - HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_JSDialogResponse, m_iBrowser ); - if ( pBuf ) - { - CHTMLProtoBufMsg< CMsgJSDialogResponse > cmd( eHTMLCommands_JSDialogResponse ); - g_CEFThread.ReleaseCommandBuffer( pBuf ); - } - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Run a JS confirm request. Return RV_CONTINUE to display the default alert -// or RV_HANDLED if you displayed a custom alert. If you handled the alert -// set |CefHandler::RetVal| to true if the user accepted the confirmation. -//----------------------------------------------------------------------------- -bool CClientHandler::OnJSConfirm(CefRefPtr browser, - CefRefPtr frame, - const CefString& message, - bool& retval) -{ - { - // scope this so the wait below doesn't keep this allocation on the stack - CHTMLProtoBufMsg cmd( eHTMLCommands_JSConfirm ); - cmd.Body().set_message( message.c_str() ); - DISPATCH_MESSAGE( eHTMLCommands_JSConfirm ); - } - - retval = false; - - HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_JSDialogResponse, m_iBrowser ); - if ( pBuf ) - { - CHTMLProtoBufMsg< CMsgJSDialogResponse > cmd( eHTMLCommands_JSDialogResponse ); - if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) - { - if ( cmd.BodyConst().result() ) - retval = true ; - } - - g_CEFThread.ReleaseCommandBuffer( pBuf ); - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Run a JS prompt request. Return RV_CONTINUE to display the default prompt -// or RV_HANDLED if you displayed a custom prompt. If you handled the prompt -// set |CefHandler::RetVal| to true if the user accepted the prompt and request and -// |result| to the resulting value. -//----------------------------------------------------------------------------- -bool CClientHandler::OnJSPrompt(CefRefPtr browser, - CefRefPtr frame, - const CefString& message, - const CefString& defaultValue, - bool& retval, - CefString& result) -{ - retval = false; // just don't pop JS prompts for now - result = defaultValue; - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Called just before a window is closed. -//----------------------------------------------------------------------------- -void CClientHandler::OnBeforeClose(CefRefPtr browser) -{ - Lock(); - if ( m_Browser ) - { - // Free the browser pointer so that the browser can be destroyed - m_Browser = NULL; - - if ( !m_bBrowserClosing ) - { - CHTMLProtoBufMsg cmd( eHTMLCommands_Close ); - DISPATCH_MESSAGE( eHTMLCommands_Close ); - } - } - Unlock(); -} - - -//----------------------------------------------------------------------------- -// Purpose: show a html popup, a pulldown menu or the like -//----------------------------------------------------------------------------- -void CChromePainter::OnPopupShow(CefRefPtr browser, bool show) -{ - m_bPopupVisible = show; - int m_iBrowser = m_pParent->m_iBrowser; - if ( show ) - { - CHTMLProtoBufMsg cmd( eHTMLCommands_ShowPopup ); - DISPATCH_MESSAGE( eHTMLCommands_ShowPopup ); - } - else - { - CHTMLProtoBufMsg cmd( eHTMLCommands_HidePopup ); - DISPATCH_MESSAGE( eHTMLCommands_HidePopup ); - - // redraw the buffered texture behind the rectangle that was previously composited - for ( size_t i = 0; i < Q_ARRAYSIZE( m_Texture ); ++i ) - { - m_Texture[i].MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); - } - - // and notify the main thread to redraw the previously composited area as well - m_UpdateRect.MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: make the popup this big -//----------------------------------------------------------------------------- -void CChromePainter::OnPopupSize(CefRefPtr browser, const CefRect& rect ) -{ - if ( m_bPopupVisible ) - { - // redraw the buffered texture behind the rectangle that was previously composited - for ( size_t i = 0; i < Q_ARRAYSIZE( m_Texture ); ++i ) - { - m_Texture[i].MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); - } - - // and notify the main thread to redraw the previously composited area as well - m_UpdateRect.MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); - } - - m_bPopupVisible = true; - m_nPopupX = rect.x; - m_nPopupWide = rect.width; - m_nPopupY = rect.y; - m_nPopupTall = rect.height; - - int m_iBrowser = m_pParent->m_iBrowser; - CHTMLProtoBufMsg cmd( eHTMLCommands_SizePopup ); - cmd.Body().set_x( m_nPopupX ); - cmd.Body().set_y( m_nPopupY ); - cmd.Body().set_wide( m_nPopupWide ); - cmd.Body().set_tall( m_nPopupTall ); - DISPATCH_MESSAGE( eHTMLCommands_SizePopup ); -} - - -//----------------------------------------------------------------------------- -// Purpose: cef has status text for us -//----------------------------------------------------------------------------- -void CClientHandler::OnStatusMessage(CefRefPtr browser, const CefString& value, StatusType type) -{ - if ( !value.empty() ) - { - CHTMLProtoBufMsg cmd( eHTMLCommands_StatusText ); - cmd.Body().set_text( value.c_str() ); - DISPATCH_MESSAGE( eHTMLCommands_StatusText ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: show tooltip please -//----------------------------------------------------------------------------- -bool CClientHandler::OnTooltip(CefRefPtr browser, CefString& text) -{ - if ( !m_bShowingToolTip && !text.empty() ) - { - m_bShowingToolTip = true; - m_strToolTip = text.c_str(); - - CHTMLProtoBufMsg cmd( eHTMLCommands_ShowToolTip ); - cmd.Body().set_text( m_strToolTip ); - DISPATCH_MESSAGE( eHTMLCommands_ShowToolTip ); - } - else if ( m_bShowingToolTip && !text.empty() ) - { - if ( m_strToolTip != text.c_str() ) - { - m_strToolTip = text.c_str(); - - CHTMLProtoBufMsg cmd( eHTMLCommands_UpdateToolTip ); - cmd.Body().set_text( m_strToolTip ); - DISPATCH_MESSAGE( eHTMLCommands_UpdateToolTip ); - } - } - else if ( m_bShowingToolTip ) - { - CHTMLProtoBufMsg cmd( eHTMLCommands_HideToolTip ); - DISPATCH_MESSAGE( eHTMLCommands_HideToolTip ); - - m_bShowingToolTip = false; - m_strToolTip.Clear(); - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: set the mouse cursor to this image -//----------------------------------------------------------------------------- -bool CChromePainter::OnSetCursor( CefRefPtr browser, const CursorType type, const void *pchIconData, int iWide, int iTall, int xHotSpot, int yHotSpot ) -{ - int m_iBrowser = m_pParent->m_iBrowser; - CHTMLProtoBufMsg cmd( eHTMLCommands_SetCursor ); - - EMouseCursor cursor; - switch( type ) - { - case TypeCustom: - cursor = dc_last; - break; - case TypeCross: - cursor = dc_crosshair; - break; - case TypeHand: - cursor = dc_hand; - break; - case TypeIBeam: - cursor = dc_ibeam; - break; - case TypeWait: - cursor = dc_hourglass; - break; - case TypeHelp: - cursor = dc_help; - break; - case TypeEastResize: - cursor = dc_sizee; - break; - case TypeNorthResize: - cursor = dc_sizen; - break; - case TypeNorthEastResize: - cursor = dc_sizene; - break; - case TypeNorthWestResize: - cursor = dc_sizenw; - break; - case TypeSouthResize: - cursor = dc_sizes; - break; - case TypeSouthEastResize: - cursor = dc_sizese; - break; - case TypeSouthWestResize: - cursor = dc_sizesw; - break; - case TypeNorthSouthResize: - cursor = dc_sizes; - break; - case TypeEastWestResize: - cursor = dc_sizew; - break; - case TypeNorthEastSouthWestResize: - cursor = dc_sizeall; - break; - case TypeColumnResize: - cursor = dc_colresize; - break; - case TypeRowResize: - cursor = dc_rowresize; - break; - case TypeMiddlePanning: - cursor = dc_middle_pan; - break; - case TypeEastPanning: - cursor = dc_east_pan; - break; - case TypeNorthPanning: - cursor = dc_north_pan; - break; - case TypeNorthEastPanning: - cursor = dc_north_east_pan; - break; - case TypeNorthWestPanning: - cursor = dc_north_west_pan; - break; - case TypeSouthPanning: - cursor = dc_south_pan; - break; - case TypeSouthEastPanning: - cursor = dc_south_east_pan; - break; - case TypeSouthWestPanning: - cursor = dc_south_west_pan; - break; - case TypeWestPanning: - cursor = dc_west_pan; - break; - case TypeMove: - cursor = dc_sizeall; - break; - case TypeVerticalText: - cursor = dc_verticaltext; - break; - case TypeCell: - cursor = dc_cell; - break; - case TypeContextMenu: - cursor = dc_none; - break; - case TypeAlias: - cursor = dc_alias; - break; - case TypeProgress: - cursor = dc_waitarrow; - break; - case TypeNoDrop: - cursor = dc_no; - break; - case TypeCopy: - cursor = dc_copycur; - break; - case TypeNone: - cursor = dc_none; - break; - case TypeNotAllowed: - cursor = dc_no; - break; - case TypeZoomIn: - cursor = dc_zoomin; - break; - case TypeZoomOut: - cursor = dc_zoomout; - break; - case TypePointer: - default: - cursor = dc_arrow; - } - cmd.Body().set_cursor( cursor ); - cmd.Body().set_data( (uint32)pchIconData ); // we are relying on chrome keeping around the cursor data after this call completes, it does right now. - cmd.Body().set_wide( iWide ); - cmd.Body().set_tall( iTall ); - cmd.Body().set_xhotspot( xHotSpot ); - cmd.Body().set_yhotspot( yHotSpot ); - DISPATCH_MESSAGE( eHTMLCommands_SetCursor ); - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: file open dialog to be shown -//----------------------------------------------------------------------------- -bool CChromePainter::OnFileOpenDialog( CefRefPtr browser, bool bMultiSelect, const CefString &default_title, const CefString &default_file, CefWebFileChooserCallback *pCallback ) -{ - if ( !pCallback ) - return true; - - int m_iBrowser = m_pParent->m_iBrowser; - { - // scope this so this allocation doesn't stay on the stack during validate - CHTMLProtoBufMsg cmd( eHTMLCommands_FileLoadDialog ); - if ( !default_title.empty() ) - cmd.Body().set_title( default_title ); - if ( !default_file.empty() ) - cmd.Body().set_initialfile( default_file ); - DISPATCH_MESSAGE( eHTMLCommands_FileLoadDialog ); - } - - HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_FileLoadDialogResponse, m_iBrowser ); - if ( pBuf ) - { - CHTMLProtoBufMsg< CMsgFileLoadDialogResponse > cmd( eHTMLCommands_FileLoadDialogResponse ); - if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) - { - std::vector files; - for ( int i = 0; i < cmd.BodyConst().files_size(); i++ ) - { - if ( !cmd.BodyConst().files(i).empty() ) - { - CPathString path( cmd.BodyConst().files(i).c_str() ); - files.push_back( path.GetWCharPathPrePended() ); - } - } - - // if you have a DEBUG build and are crashing here it is because - // Chrome is a release library and the std::vector iterator isn't crossing - // the interface happyily. Build release and you will run fine. -#if defined(DEBUG) && defined(WIN32) - Assert( !"File select dialog not available in debug due to STL debug/release issues\n" ); -#else - pCallback->OnFileChoose( files ); -#endif - } - g_CEFThread.ReleaseCommandBuffer( pBuf ); - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: CEF is asking if it can show itself fullscreen -//----------------------------------------------------------------------------- -bool CChromePainter::OnEnterFullScreen( CefRefPtr browser ) -{ - int m_iBrowser = m_pParent->m_iBrowser; - { - // scope this so this allocation doesn't stay on the stack during validate - CHTMLProtoBufMsg cmd( eHTMLCommands_RequestFullScreen ); - DISPATCH_MESSAGE( eHTMLCommands_RequestFullScreen ); - } - - HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_RequestFullScreenResponse, m_iBrowser ); - if ( pBuf ) - { - CHTMLProtoBufMsg< CMsgRequestFullScreenResponse > cmd( eHTMLCommands_RequestFullScreenResponse ); - if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) - { - return cmd.BodyConst().ballow(); - } - g_CEFThread.ReleaseCommandBuffer( pBuf ); - } - - return false; -} - - -//----------------------------------------------------------------------------- -// Purpose: cef is spewing to its console, print it -//----------------------------------------------------------------------------- -bool CChromePainter::OnExitFullScreen( CefRefPtr browser ) -{ - int m_iBrowser = m_pParent->m_iBrowser; - { - // scope this so this allocation doesn't stay on the stack during validate - // tell the main thread we are exiting fullscreen - CHTMLProtoBufMsg cmd( eHTMLCommands_ExitFullScreen ); - DISPATCH_MESSAGE( eHTMLCommands_ExitFullScreen ); - } - - // BUGUBG - add a request/response here so you can disallow leaving fullscreen?? - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: cef is spewing to its console, print it -//----------------------------------------------------------------------------- -bool CClientHandler::OnConsoleMessage(CefRefPtr browser, - const CefString& message, - const CefString& source, - int line) -{ - // the console is very chatty and doesn't provide useful information for us app developers, just for html/css editors, so lets ignore this for now - //Msg( "Browser Message: %s - %s:%d\n", message.c_str(), source.c_str(), line ); - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: helper function to recurvisely search down the DOM for any input nodes and an input button name -//----------------------------------------------------------------------------- -void SearchForInputButtonAndOtherInputs_R( CefRefPtr root, CefRefPtr focusNode, bool &bHasMultipleTextInputNodes, CUtlString &sSearchButtonName, int nMaxRecurse ) -{ - CefRefPtr nodeChildren = root->GetFirstChild(); - while ( nodeChildren.get() ) - { - if ( !nodeChildren->IsSame( focusNode ) && nodeChildren->IsElement() ) - { - CUtlString sElementType = nodeChildren->GetElementTagName().c_str(); - if ( !Q_stricmp( "input", sElementType ) ) - { - CUtlString sChildControlType = nodeChildren->GetFormControlElementType().c_str(); - if ( sSearchButtonName.IsEmpty() && !Q_stricmp( sChildControlType, "submit" ) ) - { - if ( nodeChildren->HasElementAttribute( "value" ) ) - sSearchButtonName = nodeChildren->GetElementAttribute( "value" ).c_str(); - } - else if ( !Q_stricmp( "text", sChildControlType ) || !Q_stricmp( "password", sChildControlType ) || !Q_stricmp( "email", sChildControlType ) ) - { - //CefDOMNode::AttributeMap attrMap; - //nodeChildren->GetElementAttributes( attrMap ); - if ( !nodeChildren->HasElementAttribute( "disabled" ) ) - bHasMultipleTextInputNodes = true; - } - } - else if ( !Q_stricmp( "textarea", sElementType ) ) - { - if ( !nodeChildren->HasElementAttribute( "disabled" ) ) - bHasMultipleTextInputNodes = true; - } - else if ( nMaxRecurse > 0 /*&& !Q_stricmp( "div", sElementType ) || !Q_stricmp( "tr", sElementType ) || !Q_stricmp( "td", sElementType ) || !Q_stricmp( "table", sElementType ) || !Q_stricmp( "tbody", sElementType )*/ ) - { - SearchForInputButtonAndOtherInputs_R( nodeChildren, focusNode, bHasMultipleTextInputNodes, sSearchButtonName, nMaxRecurse - 1 ); - } - } - nodeChildren = nodeChildren->GetNextSibling(); - - if ( bHasMultipleTextInputNodes && sSearchButtonName.IsValid() ) - break; // if we found both multiple nodes and a search button name we can bail early - } -} - - -//----------------------------------------------------------------------------- -// Purpose: a new node in the DOM has focus now -//----------------------------------------------------------------------------- -void CClientHandler::OnFocusedNodeChanged(CefRefPtr browser, CefRefPtr frame, CefRefPtr node) -{ - VPROF_BUDGET( "CCEFThread - CClientHandler::OnFocusedNodeChanged()", VPROF_BUDGETGROUP_VGUI ); - - bool bIsInputNode = false; - CUtlString sElementType; - if ( node.get() ) - sElementType = node->GetElementTagName().c_str(); - - CUtlString sName; - if ( node.get() ) - sName = node->GetName().c_str(); - - CUtlString sSearchButtonName; - CUtlString sControlType; - bool bInputNode = !Q_stricmp( "input", sElementType ); - bool bHasMultipleInputNodes = false; - if ( sElementType.IsValid() && ( bInputNode || !Q_stricmp( "textarea", sElementType ) ) ) - { - sControlType = node->GetFormControlElementType().c_str(); - - // lets go searching for the submit button and grab the text it shows - bIsInputNode = true; - CefRefPtr nodeParent = node->GetParent(); - while( nodeParent.get() ) - { - CUtlString sParentElementType = nodeParent->GetElementTagName().c_str(); - if ( !Q_stricmp( "form", sParentElementType ) ) - break; - nodeParent = nodeParent->GetParent(); - } - - if ( nodeParent.get() ) - SearchForInputButtonAndOtherInputs_R( nodeParent, node, bHasMultipleInputNodes, sSearchButtonName, 32 ); - } - - if ( sElementType.IsValid() && !Q_stricmp( "div", sElementType ) ) - { - if ( node->HasElementAttribute( "contenteditable" ) ) - bIsInputNode = true; - } - - if ( sSearchButtonName.IsEmpty() ) - sSearchButtonName = "#Web_FormSubmit"; - - CHTMLProtoBufMsg cmd( eHTMLCommands_NodeGotFocus ); - cmd.Body().set_binput( bIsInputNode ); - if ( sName.IsValid() ) - cmd.Body().set_name( sName ); - if ( sElementType.IsValid() ) - cmd.Body().set_elementtagname( sElementType ); - if ( sSearchButtonName.IsValid() ) - cmd.Body().set_searchbuttontext( sSearchButtonName ); - cmd.Body().set_bhasmultipleinputs( bHasMultipleInputNodes ); - if ( sControlType.IsValid() ) - cmd.Body().set_input_type( sControlType ); - - DISPATCH_MESSAGE( eHTMLCommands_NodeGotFocus ); -} - - -//----------------------------------------------------------------------------- -// Purpose: a find has found matches on the page, feed back that info -//----------------------------------------------------------------------------- -void CClientHandler::OnFindResult(CefRefPtr browser, - int identifier, - int count, - const CefRect& selectionRect, - int activeMatchOrdinal, - bool finalUpdate) -{ - CHTMLProtoBufMsg cmd( eHTMLCommands_SearchResults ); - cmd.Body().set_activematch( activeMatchOrdinal ); - cmd.Body().set_results( count ); - DISPATCH_MESSAGE( eHTMLCommands_SearchResults ); -} - - -//----------------------------------------------------------------------------- -// Purpose: return a pointer to the CEF browser object -//----------------------------------------------------------------------------- -CefRefPtr CClientHandler::GetBrowser() -{ - return m_Browser; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CClientHandler::CloseBrowser() -{ - if ( m_Browser ) - { - m_bBrowserClosing = true; - m_Browser->CloseBrowser(); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CClientHandler::SetMouseLocation( int nMouseX, int nMouseY ) -{ - m_nMouseX = nMouseX; - m_nMouseY = nMouseY; - if ( m_Browser.get() ) - { - m_nMouseScrolledX = nMouseX + m_Browser->VerticalScroll(); - m_nMouseScrolledY = nMouseY + m_Browser->HorizontalScroll(); - m_bMouseFocus = true; - m_Browser->SendMouseMoveEvent( m_nMouseX, m_nMouseY, false ); -} -} - -//----------------------------------------------------------------------------- -// Purpose: check if window has scrolled and generate a fake mouse move event -// to force CEF to check for hover state changes (seems like a CEF bug...) -//----------------------------------------------------------------------------- -void CClientHandler::RefreshCEFHoverStatesAfterScroll() -{ - if ( m_Browser.get() && m_bMouseFocus ) - { - int nScrolledX = m_nMouseX + m_Browser->VerticalScroll(); - int nScrolledY = m_nMouseY + m_Browser->HorizontalScroll(); - if ( nScrolledX != m_nMouseScrolledX || nScrolledY != m_nMouseScrolledY ) - { - m_nMouseScrolledX = nScrolledX; - m_nMouseScrolledY = nScrolledY; - m_Browser->SendMouseMoveEvent( m_nMouseX, m_nMouseY, false ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: make the user agent for this browser -//----------------------------------------------------------------------------- -void CClientHandler::SetBrowserAgent( CefRefPtr browser ) -{ - static bool bGotIEVersion = false; - static char rgchWindowsVersion[64] = "Windows NT 5.1"; // XP SP1 - static char *rgchOS = ""; - - if ( !bGotIEVersion ) - { -#ifdef WIN32 - rgchOS = "Windows"; - // First get windows version - OSVERSIONINFO verInfo; - memset( &verInfo, 0, sizeof(OSVERSIONINFO) ); - verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - if ( ::GetVersionEx( &verInfo ) ) - { - // We only run on "Windows NT" os's, so we just need to append the major/minor version dynamically - Q_snprintf( rgchWindowsVersion, sizeof(rgchWindowsVersion), "Windows NT %u.%u", verInfo.dwMajorVersion, verInfo.dwMinorVersion ); - //Log( "Windows Version is: %u.%u\n", verInfo.dwMajorVersion, verInfo.dwMinorVersion ); - } - -#elif defined(OSX) - Q_snprintf( rgchWindowsVersion, sizeof(rgchWindowsVersion), "Macintosh" ); - rgchOS = "Macintosh"; -#elif defined(LINUX) - Q_snprintf( rgchWindowsVersion, sizeof(rgchWindowsVersion), "X11" );// strange, but that's what Firefox uses - rgchOS = "Linux"; -#endif - } - - // user agent is process wide for Chrome so you can only set it once and it appplies to everything you open - { - char szAgent[ 2048 ]; - Q_snprintf( szAgent, sizeof(szAgent), m_strUserAgent.String(), rgchOS, rgchWindowsVersion, m_strUserAgentIdentifier.String(), sm_ulBuildID, m_szUserAgentExtras ); - browser->SetUserAgent( szAgent ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: paint the cef control -//----------------------------------------------------------------------------- -void CClientHandler::Paint() -{ - Lock(); - if ( m_Browser ) - { - m_bPendingPaint |= m_Painter.BUpdated(); - m_Painter.SetUpdated( false ); - } - Unlock(); -} - - -//----------------------------------------------------------------------------- -// Purpose: did we have a paint that updated the texture buffer? -//----------------------------------------------------------------------------- -bool CClientHandler::BNeedsPaint() -{ - bool bVal = m_bPendingPaint; - m_bPendingPaint = false; - return bVal; -} - - -//----------------------------------------------------------------------------- -// Purpose: get the texture data for the control -//----------------------------------------------------------------------------- -const byte *CClientHandler::PComposedTextureData( uint32 iTexture ) -{ - VPROF_BUDGET( "CClientHandler::PTextureData", VPROF_BUDGETGROUP_VGUI ); - - return m_Painter.PComposedTextureData( iTexture ); - } - - -//----------------------------------------------------------------------------- -// Purpose: true if something valid has rendered (i.e not the blank page) -//----------------------------------------------------------------------------- -bool CClientHandler::IsVisuallyNonEmpty() -{ - if ( m_Browser ) - return m_Browser->IsVisuallyNonEmpty(); - - return false; -} - - -//----------------------------------------------------------------------------- -// Purpose: set the loc strings to display on error -//----------------------------------------------------------------------------- -void CClientHandler::SetErrorStrings( const char *pchTitle, const char *pchHeader, const char *pchCacheMiss, const char *pchBadURL, const char *pchConnectionProblem, - const char *pchProxyProblem, const char *pchUnknown ) -{ - m_sErrorTitle = pchTitle; - m_sErrorHeader = pchHeader; - m_sErrorCacheMiss = pchCacheMiss; - m_sErrorBadURL = pchBadURL; - m_sErrorConnectionProblem = pchConnectionProblem; - m_sErrorProxyProblem = pchProxyProblem; - m_sErrorUnknown = pchUnknown; -} - - -//----------------------------------------------------------------------------- -// Purpose: the user wants us to take a screenshot of a page -//----------------------------------------------------------------------------- -void CClientHandler::RequestScreenShot( const CHTMLProtoBufMsg &cmd ) -{ - m_Snapshot.m_sURLSnapshot = cmd.BodyConst().url().c_str(); - m_Snapshot.m_sFileNameSnapshot = cmd.BodyConst().filename().c_str(); - m_Snapshot.m_nWide = cmd.BodyConst().width(); - m_Snapshot.m_nTall = cmd.BodyConst().height(); - m_Snapshot.m_flRequestTimeout = Plat_FloatTime() + k_flMaxScreenshotWaitTime; -} - - -//----------------------------------------------------------------------------- -// Purpose: save a screenshot of the current html page to this file with this size -//----------------------------------------------------------------------------- -void CClientHandler::SavePageToJPEGIfNeeded( CefRefPtr browser, const byte *pRGBA, int wide, int tall ) -{ - if ( m_Snapshot.m_sURLSnapshot.IsValid() && wide && tall - && m_Snapshot.m_sURLSnapshot == CStrAutoEncode( browser->GetMainFrame()->GetURL().c_str() ).ToString() ) - { - VPROF_BUDGET( "CClientHandler::SavePageToJPEGIfNeeded", VPROF_BUDGETGROUP_TENFOOT ); - - CUtlBuffer bufRGB; - - bufRGB.Put( pRGBA, wide * tall *4 ); - if ( !BConvertRGBAToRGB( bufRGB, wide, tall ) ) - return; - - BResizeImageRGB( bufRGB, wide, tall, m_Snapshot.m_nWide, m_Snapshot.m_nTall ); - // input format is actually BGRA so now swizzle to rgb - byte *pBGR = (byte *)bufRGB.Base(); - for ( int i = 0; i < m_Snapshot.m_nTall; i++ ) - { - for ( int j = 0; j < m_Snapshot.m_nWide; j++ ) - { - char cR = pBGR[0]; - pBGR[0] = pBGR[2]; - pBGR[2] = cR; - pBGR += 3; - } - } - - if ( !ConvertRGBToJpeg( m_Snapshot.m_sFileNameSnapshot, k_ScreenshotQuality, m_Snapshot.m_nWide, m_Snapshot.m_nTall, bufRGB ) ) - return; - - CHTMLProtoBufMsg cmd( eHTMLCommands_SavePageToJPEGResponse ); - cmd.Body().set_url( m_Snapshot.m_sURLSnapshot ); - cmd.Body().set_filename( m_Snapshot.m_sFileNameSnapshot ); - DISPATCH_MESSAGE( eHTMLCommands_SavePageToJPEGResponse ); - - m_Snapshot.m_sURLSnapshot.Clear(); - m_Snapshot.m_flRequestTimeout = 0.0f; - - } -} - - -//----------------------------------------------------------------------------- -// Purpose: return the url located at this position if there is one -//----------------------------------------------------------------------------- -void CCEFThread::ThreadLinkAtPosition( const CHTMLProtoBufMsg &htmlCommand ) -{ - CefString pchURL; - int iClient = 0; - int bLiveLink = false; - int bInput = false; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - if ( m_listClientHandlers[iClient]->GetBrowser() ) - m_listClientHandlers[iClient]->GetBrowser()->GetLinkAtPosition( htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y(), - pchURL, bLiveLink, bInput); - } - - CHTMLProtoBufMsg cmd( eHTMLCommands_LinkAtPositionResponse ); - cmd.Body().set_x( htmlCommand.BodyConst().x() ); - cmd.Body().set_y( htmlCommand.BodyConst().y() ); - cmd.Body().set_blivelink( bLiveLink>0 ? true: false ); - cmd.Body().set_binput( bInput>0 ? true: false ); - if ( !pchURL.empty() ) - cmd.Body().set_url( pchURL ); - int m_iBrowser = htmlCommand.BodyConst().browser_handle(); - DISPATCH_MESSAGE( eHTMLCommands_LinkAtPositionResponse ); -} - - -//----------------------------------------------------------------------------- -// Purpose: zoom the screen to the element at this position -//----------------------------------------------------------------------------- -void CCEFThread::ThreadZoomToElementAtPosition( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - if ( m_listClientHandlers[iClient]->GetBrowser() ) - { - CefRect initialRect, finalRect; - float zoomLevel = m_listClientHandlers[iClient]->GetBrowser()->scalePageToFitElementAt( - htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y(), - initialRect, finalRect ); - int m_iBrowser = htmlCommand.BodyConst().browser_handle(); - ThreadBrowserVerticalScrollBarSizeHelper( m_iBrowser, true ); - ThreadBrowserHorizontalScrollBarSizeHelper( m_iBrowser, true ); - { - CHTMLProtoBufMsg cmd( eHTMLCommands_ZoomToElementAtPositionResponse ); - cmd.Body().set_zoom( zoomLevel ); - cmd.Body().set_initial_x( initialRect.x ); - cmd.Body().set_initial_y( initialRect.y ); - cmd.Body().set_initial_width( initialRect.width ); - cmd.Body().set_initial_height( initialRect.height ); - cmd.Body().set_final_x( finalRect.x ); - cmd.Body().set_final_y( finalRect.y ); - cmd.Body().set_final_width( finalRect.width ); - cmd.Body().set_final_height( finalRect.height ); - DISPATCH_MESSAGE( eHTMLCommands_ZoomToElementAtPositionResponse ); - } - } - } - } - - -//----------------------------------------------------------------------------- -// Purpose: zoom the screen to the element at this position -//----------------------------------------------------------------------------- -void CCEFThread::ThreadZoomToFocusedElement( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - if ( m_listClientHandlers[iClient]->GetBrowser() ) - { - CefRect initialRect, finalRect; - float zoomLevel = m_listClientHandlers[iClient]->GetBrowser()->scalePageToFocusedElement( htmlCommand.BodyConst().leftoffset(), htmlCommand.BodyConst().topoffset(), initialRect, finalRect ); - int m_iBrowser = htmlCommand.BodyConst().browser_handle(); - ThreadBrowserVerticalScrollBarSizeHelper( m_iBrowser, true ); - ThreadBrowserHorizontalScrollBarSizeHelper( m_iBrowser, true ); - { - CHTMLProtoBufMsg cmd( eHTMLCommands_ZoomToElementAtPositionResponse ); - cmd.Body().set_zoom( zoomLevel ); - cmd.Body().set_initial_x( initialRect.x ); - cmd.Body().set_initial_y( initialRect.y ); - cmd.Body().set_initial_width( initialRect.width ); - cmd.Body().set_initial_height( initialRect.height ); - cmd.Body().set_final_x( finalRect.x ); - cmd.Body().set_final_y( finalRect.y ); - cmd.Body().set_final_width( finalRect.width ); - cmd.Body().set_final_height( finalRect.height ); - DISPATCH_MESSAGE( eHTMLCommands_ZoomToElementAtPositionResponse ); - } - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: increment the scale factor on the page by an increment -//----------------------------------------------------------------------------- -void CCEFThread::ThreadSetPageScale( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CClientHandler *pHandler = m_listClientHandlers[iClient]; - if ( pHandler->GetBrowser() ) - { - int nPageHeightBefore = pHandler->GetBrowser()->VerticalScrollMax(); - int nPageWidthBefore = pHandler->GetBrowser()->HorizontalScrollMax(); - - float zoomLevel = pHandler->GetBrowser()->setPageScaleFactor( htmlCommand.BodyConst().scale(), htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y() ); - - int idx = m_mapSizeChangesPending.Find( htmlCommand.BodyConst().browser_handle() ); - if ( idx == m_mapSizeChangesPending.InvalidIndex() ) - { - SizeChange_t &sizeChange = m_mapSizeChangesPending [ m_mapSizeChangesPending.Insert( htmlCommand.BodyConst().browser_handle() ) ]; - sizeChange.iBrowser = htmlCommand.BodyConst().browser_handle(); - sizeChange.nBeforeHeight = nPageHeightBefore; - sizeChange.nBeforeWidth = nPageWidthBefore; - sizeChange.flNewZoom = zoomLevel; - } - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: fire off the details of any page scale changes we had pending from last frame -//----------------------------------------------------------------------------- -void CCEFThread::SendSizeChangeEvents() -{ - FOR_EACH_MAP_FAST( m_mapSizeChangesPending, i ) - { - int iClient = 0; - if ( BIsValidBrowserHandle( m_mapSizeChangesPending[i].iBrowser, iClient ) ) - { - CClientHandler *pHandler = m_listClientHandlers[iClient]; - if ( pHandler->GetBrowser() ) - { - int nPageHeightAfter = pHandler->GetBrowser()->VerticalScrollMax(); - int nPageWidthAfter = pHandler->GetBrowser()->HorizontalScrollMax(); - - int m_iBrowser = m_mapSizeChangesPending[i].iBrowser; - - ThreadBrowserVerticalScrollBarSizeHelper( m_iBrowser, true ); - ThreadBrowserHorizontalScrollBarSizeHelper( m_iBrowser, true ); - { - CHTMLProtoBufMsg cmd( eHTMLCommands_ScaleToValueResponse ); - cmd.Body().set_zoom( m_mapSizeChangesPending[i].flNewZoom ); - cmd.Body().set_width_delta( nPageWidthAfter - m_mapSizeChangesPending[i].nBeforeWidth ); - cmd.Body().set_height_delta( nPageHeightAfter - m_mapSizeChangesPending[i].nBeforeHeight ); - DISPATCH_MESSAGE( eHTMLCommands_ScaleToValueResponse ); - } - } - } - } - m_mapSizeChangesPending.RemoveAll(); -} - - -//----------------------------------------------------------------------------- -// Purpose: exit from fullscreen if in it -//----------------------------------------------------------------------------- -void CCEFThread::ThreadExitFullScreen( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - m_listClientHandlers[ iClient ]->GetBrowser()->ExitFullScreen(); - } - -} - - -//----------------------------------------------------------------------------- -// Purpose: the user has requested we save this url to a file on local disk -//----------------------------------------------------------------------------- -void CCEFThread::ThreadSavePageToJPEG( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - m_listClientHandlers[ iClient ]->RequestScreenShot( htmlCommand ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: mouse moved to this x,y on the page -//----------------------------------------------------------------------------- -void CCEFThread::ThreadMouseMove( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - m_listClientHandlers[ iClient ]->SetMouseLocation( htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: mouse left the control, tell cef -//----------------------------------------------------------------------------- -void CCEFThread::ThreadMouseLeave( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - - m_listClientHandlers[ iClient ]->SetMouseFocus( false ); - - int mx, my; - m_listClientHandlers[ iClient ]->GetMouseLocation( mx, my ); - browser->SendMouseMoveEvent( mx, my, true ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: helper to convert UI mouse codes to CEF ones -//----------------------------------------------------------------------------- -CefBrowser::MouseButtonType ConvertMouseCodeToCEFCode( int code ) -{ - // BUGBUG - switch( code ) - { - case 0: - return MBT_LEFT; - break; - case 1: - return MBT_RIGHT; - break; - case 2: - return MBT_MIDDLE; - break; - default: - return MBT_LEFT; - break; - } -} - - -//----------------------------------------------------------------------------- -// Purpose: mouse button pressed -//----------------------------------------------------------------------------- -void CCEFThread::ThreadMouseButtonDown( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - int nMouseX, nMouseY; - m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); - - browser->SendMouseClickEvent( nMouseX, nMouseY, ConvertMouseCodeToCEFCode( htmlCommand.BodyConst().mouse_button() ), false, 1 ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: mouse button released -//----------------------------------------------------------------------------- -void CCEFThread::ThreadMouseButtonUp( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - int nMouseX, nMouseY; - m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); - - browser->SendMouseClickEvent( nMouseX, nMouseY, ConvertMouseCodeToCEFCode( htmlCommand.BodyConst().mouse_button() ), true, 1 ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: mouse button double pressed -//----------------------------------------------------------------------------- -void CCEFThread::ThreadMouseButtonDlbClick( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - int nMouseX, nMouseY; - m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); - - browser->SendMouseClickEvent( nMouseX, nMouseY, ConvertMouseCodeToCEFCode( htmlCommand.BodyConst().mouse_button() ), false, 2 ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: mouse was wheeled -//----------------------------------------------------------------------------- -void CCEFThread::ThreadMouseWheel( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - int nMouseX, nMouseY; - m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); - - browser->SendMouseWheelEvent( nMouseX, nMouseY, 0, htmlCommand.BodyConst().delta() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: unicode character was typed -//----------------------------------------------------------------------------- -void CCEFThread::ThreadKeyTyped( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - - CefKeyInfo keyInfo; -#ifdef OSX - keyInfo.character = htmlCommand.BodyConst().unichar(); -#else - keyInfo.key = htmlCommand.BodyConst().unichar(); -#endif - browser->SendKeyEvent( KT_CHAR, keyInfo, 0 ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: raw key was pressed -//----------------------------------------------------------------------------- -void CCEFThread::ThreadKeyDown( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - - CefKeyInfo keyInfo; -#ifdef OSX - keyInfo.keyCode = htmlCommand.BodyConst().keycode(); -#else - keyInfo.key = htmlCommand.BodyConst().keycode(); -#endif - browser->SendKeyEvent( KT_KEYDOWN, keyInfo, htmlCommand.BodyConst().modifiers() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: raw key was released -//----------------------------------------------------------------------------- -void CCEFThread::ThreadKeyUp( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - - CefKeyInfo keyInfo; -#ifdef OSX - keyInfo.keyCode = htmlCommand.BodyConst().keycode(); -#else - keyInfo.key = htmlCommand.BodyConst().keycode(); -#endif - browser->SendKeyEvent( KT_KEYUP, keyInfo, htmlCommand.BodyConst().modifiers() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: please close any fullscreen flash controls you see -//----------------------------------------------------------------------------- -void CCEFThread::ThreadCloseFullScreenFlashIfOpen( const CHTMLProtoBufMsg &htmlCommand ) -{ - CheckForFullScreenFlashControl(); - if ( m_bFullScreenFlashVisible ) - { -#ifdef WIN32 - ::PostMessageA( m_flashfullscreenHWND, WM_KEYDOWN, VK_ESCAPE, 0 ); - ::PostMessageA( m_flashfullscreenHWND, WM_KEYUP, VK_ESCAPE, 0 ); -#endif - } -} - - -//----------------------------------------------------------------------------- -// Purpose: please close any fullscreen flash controls you see -//----------------------------------------------------------------------------- -void CCEFThread::ThreadPauseFullScreenFlashMovieIfOpen( const CHTMLProtoBufMsg &htmlCommand ) -{ - CheckForFullScreenFlashControl(); - if ( m_bFullScreenFlashVisible ) - { -#ifdef WIN32 - ::PostMessageA( m_flashfullscreenHWND, WM_KEYDOWN, VK_SPACE, 0 ); - ::PostMessageA( m_flashfullscreenHWND, WM_KEYUP, VK_SPACE, 0 ); -#endif - } -} - - - -//----------------------------------------------------------------------------- -// Purpose: helper class to get the focused node in the dom -//----------------------------------------------------------------------------- -class CVisitor : public CefDOMVisitor -{ -public: - CVisitor( CThreadEvent *pEvent, CUtlString *psValue ) - { - m_pEvent = pEvent; - m_psValue = psValue; - } - - ~CVisitor() - { - m_pEvent->Set(); - } - - virtual void Visit(CefRefPtr document) { - CefRefPtr focusedNode = document->GetFocusedNode(); - *m_psValue = focusedNode->GetValue().c_str(); - } - - -private: - CThreadEvent *m_pEvent; - CUtlString *m_psValue; - - IMPLEMENT_REFCOUNTING(CVisitor); -}; - - -//----------------------------------------------------------------------------- -// Purpose: get the text out of the current dom field that has focus -//----------------------------------------------------------------------------- -void CCEFThread::ThreadGetFocusedNodeText( const CHTMLProtoBufMsg &htmlCommand ) -{ - int iClient = 0; - if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) - { - CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); - if ( !browser.get() ) - return; - - CThreadEvent event; - CUtlString sValue; - browser->GetFocusedFrame()->VisitDOM( new CVisitor( &event, &sValue ) ); - do - { - CefDoMessageLoopWork(); - } - while ( !event.Wait( 100 ) ); // keep pumping CEF until it has done our walk - - { - int m_iBrowser = htmlCommand.BodyConst().browser_handle(); - CHTMLProtoBufMsg cmd( eHTMLCommands_GetFocusedNodeValueResponse ); - cmd.Body().set_value( sValue ); - DISPATCH_MESSAGE( eHTMLCommands_GetFocusedNodeValueResponse ); - } - } -} diff --git a/vgui2/chromehtml/html_chrome.h b/vgui2/chromehtml/html_chrome.h deleted file mode 100644 index 5611180d..00000000 --- a/vgui2/chromehtml/html_chrome.h +++ /dev/null @@ -1,637 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -//=============================================================================// - -#ifndef HTML_CHROME_H -#define HTML_CHROME_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "cef/include/cef_render_handler.h" -#include "cef/include/cef_client.h" -#include "cef/include/cef_app.h" -#include "cef/include/cef_browser.h" -#include "cef/include/cef_command_line.h" -#include "cef/include/cef_frame.h" -#include "cef/include/cef_runnable.h" -#include "cef/include/cef_web_urlrequest.h" -#include "cef/include/cef_request_handler.h" -#include "cef/include/cef_load_handler.h" -#include "cef/include/cef_display_handler.h" -#include "cef/include/cef_life_span_handler.h" -#include "cef/include/cef_render_handler.h" - -#include "tier0/platform.h" -#include "tier0/vprof.h" -#include "tier1/utlarray.h" -#include "tier1/utlbuffer.h" -#include "fileio.h" -//#include "constants.h" -#include "tier0/validator.h" -#include "tier1/utlmap.h" -#include "tier1/utlstring.h" -#include "tier0/tslist.h" -#include "html/ihtmlchrome.h" -#include "html/htmlprotobuf.h" -// These must be undefed so that the MacOS build will work -- their STL -// fails if min and max are defined. I'm undefing them in all builds to -// avoid having a Windows dependency on min/max creep in. -#undef min -#undef max -#include "htmlmessages.pb.h" - -class CClientHandler; -class CChromePainter; -class ICookieCallback; - -bool ChromeSetWebCookie( const char *pchHostname, const char *pchName, const char *pchValue, const char *pchPath, RTime32 nExpires ); -bool ChromeGetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ); - -//----------------------------------------------------------------------------- -// Purpose: track dirty rects, shuttle bits between renderer and main thread -//----------------------------------------------------------------------------- -class CChromeUpdateRegion -{ -public: - CChromeUpdateRegion() { MarkAllClean(); } - int GetUpdateX( int clampWide ) const { return clamp( m_nUpdateX0, 0, clampWide ); } - int GetUpdateY( int clampTall ) const { return clamp( m_nUpdateY0, 0, clampTall ); } - int GetUpdateWide( int clampWide ) const { return clamp( m_nUpdateX1, 0, clampWide ) - GetUpdateX( clampWide ); } - int GetUpdateTall( int clampTall ) const { return clamp( m_nUpdateY1, 0, clampTall ) - GetUpdateY( clampTall ); } - - void MarkAllClean() { m_nUpdateX0 = m_nUpdateY0 = INT_MAX; m_nUpdateX1 = m_nUpdateY1 = 0; } - void MarkAllDirty() { m_nUpdateX0 = m_nUpdateY0 = 0; m_nUpdateX1 = m_nUpdateY1 = INT_MAX; } - void MarkDirtyRect( int x0, int y0, int x1, int y1 ) - { - if ( x0 >= x1 || y0 >= y1 ) return; - if ( m_nUpdateX0 > x0 ) m_nUpdateX0 = x0; - if ( m_nUpdateY0 > y0 ) m_nUpdateY0 = y0; - if ( m_nUpdateX1 < x1 ) m_nUpdateX1 = x1; - if ( m_nUpdateY1 < y1 ) m_nUpdateY1 = y1; - } - void MarkDirtyRect( const CChromeUpdateRegion& other ) - { - MarkDirtyRect( other.m_nUpdateX0, other.m_nUpdateY0, other.m_nUpdateX1, other.m_nUpdateY1 ); - } - -protected: - int m_nUpdateX0; - int m_nUpdateY0; - int m_nUpdateX1; - int m_nUpdateY1; -}; - -class CChromeRenderBuffer : public CChromeUpdateRegion -{ -public: - CChromeRenderBuffer() { m_nWide = m_nTall = 0; } - void SetSize( int wide, int tall ) - { - if ( wide != m_nWide || tall != m_nTall ) - { - m_nWide = wide; - m_nTall = tall; - MarkAllDirty(); - m_Texture.EnsureCapacity( wide * tall * 4 ); - } - } - int GetWide() const { return m_nWide; } - int GetTall() const { return m_nTall; } - byte *GetPixels() { return m_Texture.Base(); } - - bool BUpdatePixels( byte *pOther, int wide, int tall ) - { - SetSize( wide, tall ); - int x0 = clamp( m_nUpdateX0, 0, wide ); - int y0 = clamp( m_nUpdateY0, 0, tall ); - int x1 = clamp( m_nUpdateX1, 0, wide ); - int y1 = clamp( m_nUpdateY1, 0, tall ); - if ( x0 >= x1 || y0 >= y1 ) - return false; - - if ( x0 == 0 && x1 == wide ) - { - byte *pDst = GetPixels() + y0*wide*4; - byte *pSrc = pOther + y0*wide*4; - Q_memcpy( pDst, pSrc, wide * ( y1 - y0 ) * 4 ); - } - else - { - byte *pDst = GetPixels() + y0*wide*4 + x0*4; - byte *pSrc = pOther + y0*wide*4 + x0*4; - int nCopyBytesPerRow = (x1 - x0)*4; - for ( int rows = y1 - y0; rows > 0; --rows ) - { - Q_memcpy( pDst, pSrc, nCopyBytesPerRow ); - pSrc += wide * 4; - pDst += wide * 4; - } - } - return true; - } - -#ifdef DBGFLAG_VALIDATE - virtual void Validate( CValidator &validator, const char *pchName ) - { - VALIDATE_SCOPE(); - ValidateObj( m_Texture ); - } -#endif - -protected: - int m_nWide; // dimensions of the buffer - int m_nTall; - CUtlVector m_Texture; // rgba data -}; - -//----------------------------------------------------------------------------- -// Purpose: interface Chrome uses to send up paint messages -//----------------------------------------------------------------------------- -class CChromePainter : public CefRenderHandler -{ -public: - CChromePainter( CClientHandler *pParent ); - ~CChromePainter(); - - virtual bool GetViewRect(CefRefPtr browser, CefRect& rect) OVERRIDE { return false; } - virtual bool GetScreenRect(CefRefPtr browser, CefRect& rect) OVERRIDE { return false; } - virtual bool GetScreenPoint(CefRefPtr browser, int viewX, int viewY, int& screenX, int& screenY) OVERRIDE { return false; } - - virtual void OnPopupShow(CefRefPtr browser, bool show) OVERRIDE; - virtual void OnPopupSize(CefRefPtr browser, const CefRect& rect) OVERRIDE; - - virtual void OnPaint(CefRefPtr browser, PaintElementType type, const RectList& dirtyRects, const void* buffer) OVERRIDE; - virtual void OnCursorChange(CefRefPtr browser, CefCursorHandle cursor) OVERRIDE {} - virtual bool OnSetCursor( CefRefPtr browser, const CursorType type, const void *pchIconData, int iWide, int iTall, int xHotSpot, int yHotSpot ) OVERRIDE; - virtual bool OnFileOpenDialog( CefRefPtr browser, bool bMultiSelect, const CefString &default_title, const CefString &default_file, CefWebFileChooserCallback *pCallback ) OVERRIDE; - virtual bool OnEnterFullScreen( CefRefPtr browser ) OVERRIDE; - virtual bool OnExitFullScreen( CefRefPtr browser ) OVERRIDE; - - bool BUpdated(); - void SetUpdated( bool state ); - - int GetPopupTall() const { return m_nPopupTall; } - int GetPopupWide() const { return m_nPopupWide; } - int GetPopupX() const { return m_nPopupX; } - int GetPopupY() const { return m_nPopupY; } - const byte *PPopupTextureData() - { - return m_PopupTexture.Base(); - } - - uint32 FlipTexture(); - void SetTextureUploaded( uint32 id ); - bool BPaintBufferAvailable(); - - byte *PComposedTextureData( uint32 iTexture ); - int GetTall() const { return m_MainTexture.GetTall(); } - int GetWide() const { return m_MainTexture.GetWide(); } - int GetUpdateX() const { return m_UpdateRect.GetUpdateX( GetWide() ); } - int GetUpdateY() const { return m_UpdateRect.GetUpdateY( GetTall() ); } - int GetUpdateWide() const { return m_UpdateRect.GetUpdateWide( GetWide() ); } - int GetUpdateTall() const { return m_UpdateRect.GetUpdateTall( GetTall() ); } - void ClearUpdateRect() { m_UpdateRect.MarkAllClean(); } - - // XXX not shuttled safely between threads, should use real buffering - const byte *PPopupTextureDataCached(); - - bool BPopupVisible() const { return m_bPopupVisible; } - // WebKit will show popups before they have been given a size and painted and we may do - // a drawing pass during that time, so we want to make sure to only do something - // with the popup when it has an actual size and content. - bool BPopupVisibleAndPainted() const - { - return m_bPopupVisible && - m_nPopupWide != 0 && - m_nPopupTall != 0 && - m_PopupTexture.Count() >= m_nPopupWide * m_nPopupTall * 4; - } - void PopupRect( int &x, int &y, int &wide, int &tall ) const { x = m_nPopupX; y = m_nPopupY; wide = m_nPopupWide; tall = m_nPopupTall; } - -#ifdef DBGFLAG_VALIDATE - virtual void Validate( CValidator &validator, const char *pchName ) - { - VALIDATE_SCOPE(); - for ( int i = 0; i < Q_ARRAYSIZE(m_Texture); i++ ) - ValidateObj( m_Texture[i] ); - - ValidateObj( m_PopupTextureCache ); - ValidateObj( m_PopupTexture ); - ValidateObj( m_MainTexture ); - } -#endif - IMPLEMENT_REFCOUNTING(CChromePainter); - -private: - uint32 m_iNextTexture; - uint32 m_iTexturesInFlightBits; - int m_nPopupWide; - int m_nPopupTall; - CChromeRenderBuffer m_MainTexture; - CChromeRenderBuffer m_Texture[2]; // buffering -- XXX should use atomic swap, not push multiple buffers to command buffer - CChromeUpdateRegion m_UpdateRect; - CUtlVector m_PopupTextureCache; - CUtlVector m_PopupTexture; - bool m_bUpdated; - CClientHandler *m_pParent; - bool m_bPopupVisible; - int m_nPopupX, m_nPopupY; -}; - - - -//----------------------------------------------------------------------------- -// Purpose: CEF callback object -//----------------------------------------------------------------------------- -class CClientHandler : public CefClient, - public CefLifeSpanHandler, - public CefLoadHandler, - public CefRequestHandler, - public CefDisplayHandler, - - public CefJSDialogHandler, - public CefFindHandler, - public CefMenuHandler, - public CefFocusHandler, - public CefPermissionHandler -{ -public: - CClientHandler( int iBrowser, const char *pchUserAgent, uint16 nSerial ); - ~CClientHandler(); - - // CefClient methods - virtual CefRefPtr GetLifeSpanHandler() OVERRIDE { - return this; - } - virtual CefRefPtr GetLoadHandler() OVERRIDE { - return this; - } - virtual CefRefPtr GetRequestHandler() OVERRIDE { - return this; - } - virtual CefRefPtr GetDisplayHandler() OVERRIDE { - return this; - } - virtual CefRefPtr GetRenderHandler() OVERRIDE { - return &m_Painter; - } - - virtual CefRefPtr GetFocusHandler() OVERRIDE { - return this; - } - - virtual CefRefPtr GetMenuHandler() OVERRIDE { - return this; - } - virtual CefRefPtr GetPermissionHandler() OVERRIDE { - return this; - } - - virtual CefRefPtr GetFindHandler() OVERRIDE { - return this; - } - virtual CefRefPtr GetJSDialogHandler() OVERRIDE { - return this; - } - - - // CefLifeSpanHandler methods - - virtual bool OnBeforePopup(CefRefPtr parentBrowser, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, const CefString& url, CefRefPtr& client, CefBrowserSettings& settings) OVERRIDE; - virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; - virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; - virtual bool DoClose(CefRefPtr browser) { return false; } - virtual bool OnNewTab(CefRefPtr parentBrowser, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, const CefString& url, bool bForeground, CefRefPtr& client, CefBrowserSettings& settings ); - - // CefLoadHandler methods - virtual void OnLoadStart(CefRefPtr browser, CefRefPtr frame, bool bIsNewNavigation ) OVERRIDE; - - virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode, CefRefPtr request ) OVERRIDE; - virtual bool OnLoadError(CefRefPtr browser, CefRefPtr frame, ErrorCode errorCode, const CefString& failedUrl, CefString& errorText); - - // CefRequestHandler methods - virtual bool OnBeforeBrowse(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, NavType navType, bool isRedirect, bool isNewTabRequest ); - virtual bool OnBeforeResourceLoad(CefRefPtr browser, CefRefPtr request, CefString& redirectUrl, CefRefPtr& resourceStream, CefRefPtr response, int loadFlags); - - // CefDisplayHandler methods - virtual void OnNavStateChange(CefRefPtr browser, bool canGoBack, bool canGoForward) OVERRIDE {} - virtual void OnAddressChange(CefRefPtr browser, CefRefPtr frame, const CefString& url) OVERRIDE { } - virtual void OnTitleChange(CefRefPtr browser, const CefString& title) OVERRIDE; - - virtual bool OnTooltip(CefRefPtr browser, CefString& text); - virtual void OnStatusMessage(CefRefPtr browser, const CefString& value, StatusType type); - virtual bool OnConsoleMessage(CefRefPtr browser, const CefString& message, const CefString& source, int line); - - virtual void OnTakeFocus(CefRefPtr browser, bool next) {} - virtual bool OnSetFocus(CefRefPtr browser, FocusSource source) { return true; } - virtual void OnFocusedNodeChanged(CefRefPtr browser, CefRefPtr frame, CefRefPtr node); - - virtual bool OnBeforeMenu(CefRefPtr browser, const CefMenuInfo& menuInfo) { return true; } - virtual void GetMenuLabel(CefRefPtr browser, MenuId menuId, CefString& label) {} - virtual bool OnMenuAction(CefRefPtr browser, MenuId menuId) { return true; } - virtual bool OnBeforeScriptExtensionLoad(CefRefPtr browser, CefRefPtr frame, const CefString& extensionName) { return false; } - - virtual void OnFindResult(CefRefPtr browser, int identifier, int count, const CefRect& selectionRect, int activeMatchOrdinal, bool finalUpdate); - virtual bool OnJSAlert(CefRefPtr browser, CefRefPtr frame, const CefString& message); - virtual bool OnJSConfirm(CefRefPtr browser, CefRefPtr frame, const CefString& message, bool& retval); - virtual bool OnJSPrompt(CefRefPtr browser, CefRefPtr frame, const CefString& message, const CefString& defaultValue, bool& retval, CefString& result); - - void FileOpenDialogResult( const char *pchFileName ); - - - // paint helpers - void Paint(); - bool BNeedsPaint(); - - int GetTextureTall() const { return m_Painter.GetTall(); } - int GetTextureWide() const { return m_Painter.GetWide(); } - int GetUpdateX() const { return m_Painter.GetUpdateX(); } - int GetUpdateY() const { return m_Painter.GetUpdateY(); } - int GetUpdateWide() const { return m_Painter.GetUpdateWide(); } - int GetUpdateTall() const { return m_Painter.GetUpdateTall(); } - - const byte *PPopupTextureDataCached() { return m_Painter.PPopupTextureDataCached(); } - bool BPopupVisible() const { return m_Painter.BPopupVisible(); } - bool BPopupVisibleAndPainted() const { return m_Painter.BPopupVisibleAndPainted(); } - void PopupRect( int &x, int &y, int &wide, int &tall ) const { m_Painter.PopupRect( x, y, wide, tall ); } - - const byte *PComposedTextureData( uint32 iTexture ); - uint32 FlipTexture() { return m_Painter.FlipTexture(); } - void SetTextureUploaded( uint32 iTexture ) { m_Painter.SetTextureUploaded( iTexture ); } - void ClearUpdateRect() { m_Painter.ClearUpdateRect(); } - bool BPaintBufferReady() { return m_Painter.BPaintBufferAvailable(); } - - // Helpers - CefRefPtr GetBrowser(); - void CloseBrowser(); - uint32 GetPageSerial() { return m_nPageSerial; } - void SetPendingPageSerial( uint32 nPageSerial ) - { - m_nPendingPageSerial = nPageSerial; - } - - - void SetUserAgent( const char *pchAgent ) { Q_strncpy( m_szUserAgentExtras, pchAgent, sizeof(m_szUserAgentExtras) ); } - const char *PchCurrentURL() { return m_strCurrentUrl.String(); } - bool IsVisuallyNonEmpty(); - void SetErrorStrings( const char *pchTitle, const char *pchHeader, const char *pchCacheMiss, const char *pchBadURL, const char *pchConnectionProblem, - const char *pchProxyProblem, const char *pchUnknown ); - void SetMouseLocation( int x, int y ); - void GetMouseLocation( int &x, int &y ) { x = m_nMouseX; y = m_nMouseY; } - void SetMouseFocus( bool bFocus ) { m_bMouseFocus = bFocus; } - void SetSize( int wide, int tall ) { m_nExpectedWide = wide; m_nExpectedTall = tall; } - void GetExpectedSize( int &wide, int &tall ) { wide = m_nExpectedWide; tall =m_nExpectedTall; } - - //----------------------------------------------------------------------------- - // Purpose: Adds a custom header to all requests - //----------------------------------------------------------------------------- - void AddHeader( const char *pchHeader, const char *pchValue ) - { - m_vecHeaders.AddToTail( std::make_pair( CStrAutoEncode( pchHeader ).ToWString(), CStrAutoEncode( pchValue ).ToWString() ) ); - } - - void RequestScreenShot( const CHTMLProtoBufMsg &cmd ); - void SavePageToJPEGIfNeeded( CefRefPtr browser, const byte *pRGBA, int wide, int tall ); - bool BPendingScreenShot() - { - return m_Snapshot.m_flRequestTimeout > 0.0f && m_Snapshot.m_sURLSnapshot.IsValid() && m_Snapshot.m_flRequestTimeout < Plat_FloatTime(); - } - - void SetUserAgentIdentifier( const char *pchIdent ) - { - m_strUserAgentIdentifier = pchIdent; - } - - uint16 NSerial() { return m_nSerial; } - - void RefreshCEFHoverStatesAfterScroll(); - -#ifdef DBGFLAG_VALIDATE - virtual void Validate( CValidator &validator, const char *pchName ) - { - VALIDATE_SCOPE(); - ValidateObj( m_strCurrentUrl ); - ValidateObj( m_strPostData ); - ValidateObj( m_strLastRedirectURL ); - ValidateObj( m_vecHeaders ); - ValidateObj( m_strUserAgent ); - ValidateObj( m_Painter ); - ValidateObj( m_sErrorTitle ); - ValidateObj( m_sErrorHeader ); - ValidateObj( m_sErrorCacheMiss ); - ValidateObj( m_sErrorBadURL ); - ValidateObj( m_sErrorConnectionProblem ); - ValidateObj( m_sErrorProxyProblem ); - ValidateObj( m_sErrorUnknown ); - ValidateObj( m_strUserAgentIdentifier ); - // ValidateObj( m_vecHCursor ); - } -#endif - - IMPLEMENT_REFCOUNTING(CClientHandler); - IMPLEMENT_LOCKING(CClientHandler); -private: - friend class CChromePainter; - friend class CCEFThread; - - void SetBrowserAgent( CefRefPtr browser ); - - // The child browser window - CefRefPtr m_Browser; - - CefRenderHandler::CefWebFileChooserCallback *m_pOpenFileCallback; - - uint16 m_nSerial; - char m_szUserAgentExtras[ 256 ]; - CUtlString m_strCurrentUrl; - CUtlString m_strPostData; - CUtlString m_strLastRedirectURL; - CUtlString m_strUserAgent; - CUtlString m_strUserAgentIdentifier; - CUtlString m_strToolTip; - bool m_bShowingToolTip; - bool m_bPendingPaint; - bool m_bBrowserClosing; - bool m_bMouseFocus; - CChromePainter m_Painter; - CUtlVector< std::pair< std::wstring, std::wstring > > m_vecHeaders; - int m_iBrowser; - int m_nExpectedWide; - int m_nExpectedTall; - uint32 m_nPageSerial; - uint32 m_nPendingPageSerial; - - CUtlString m_sErrorTitle; - CUtlString m_sErrorHeader; - CUtlString m_sErrorCacheMiss; - CUtlString m_sErrorBadURL; - CUtlString m_sErrorConnectionProblem; - CUtlString m_sErrorProxyProblem; - CUtlString m_sErrorUnknown; - int m_nMouseX; - int m_nMouseY; - int m_nMouseScrolledX; - int m_nMouseScrolledY; - - struct SnapshotData_t - { - CUtlString m_sURLSnapshot; - CUtlString m_sFileNameSnapshot; - int m_nWide, m_nTall; - float m_flRequestTimeout; - }; - - SnapshotData_t m_Snapshot; - - // Scroll bar state is cached and compared to CEF's current values every frame; - // any changes are passed on to the client handler as serialized update messages. - struct CachedScrollBarState_t - { - int m_nX; - int m_nY; - int m_nWide; - int m_nTall; - int m_nMax; - int m_nScroll; - int m_bVisible; // using 'int' to avoid padding bytes so memcmp can be used - }; - CachedScrollBarState_t m_CachedVScroll; - CachedScrollBarState_t m_CachedHScroll; -}; - - - -//----------------------------------------------------------------------------- -// Purpose: CEF thinking thread -//----------------------------------------------------------------------------- -class CCEFThread : public CValidatableThread -{ -public: - CCEFThread(); - ~CCEFThread(); - void SetCEFPaths( const char *pchHTMLCacheDir, const char *pchCookiePath ); - void TriggerShutdown(); - void WakeThread(); - virtual int Run(); - - bool BHasPendingMessages() { return m_tslResponseBuffers.Count() > 0; } - - HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ); - void ReleaseCommandBuffer( HTMLCommandBuffer_t *pBuf ); - void PushCommand( HTMLCommandBuffer_t * ); - void PushResponse( HTMLCommandBuffer_t * ); - bool GetMainThreadCommand( HTMLCommandBuffer_t ** ); - HTMLCommandBuffer_t *BWaitForCommand( EHTMLCommands eCmd, int iBrowser ); - HTMLCommandBuffer_t *BWaitForResponse( EHTMLCommands eCmd, int iBrowser ); - bool GetCEFThreadCommand( HTMLCommandBuffer_t **pBuf ); - -#ifdef DBGFLAG_VALIDATE - virtual void SleepForValidate() { CValidatableThread::SleepForValidate(); m_evWaitingForCommand.Set(); WakeThread(); } - virtual void Validate( CValidator &validator, const tchar *pchName ); -#endif - - -private: - void RunCurrentCommands(); - const char *PchWebkitUserAgent(); - void AppGetSettings(CefSettings& settings, CefRefPtr& app); - void CleanupTempFolders(); - - void ThreadCreateBrowser( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadRemoveBrowser( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserSize( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserPosition( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserPostURL( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserStopLoad( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserReload( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserGoForward( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserGoBack( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserCopy( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserPaste( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserExecuteJavascript( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserSetFocus( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserHorizontalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserVerticalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserFind( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserStopFind( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserSetHorizontalScroll( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserSetVerticalScroll( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserSetZoomLevel( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserViewSource( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadNeedsPaintResponse( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadBrowserErrorStrings( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadAddHeader( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadGetZoom( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadHidePopup( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadGetCookiesForURL( const CHTMLProtoBufMsg &htmlCommand ); - - void ThreadKeyDown( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadKeyUp( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadKeyTyped( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadMouseButtonDown( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadMouseButtonUp( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadMouseButtonDlbClick( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadMouseWheel( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadMouseMove( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadMouseLeave( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadLinkAtPosition( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadZoomToElementAtPosition( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadZoomToFocusedElement( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadSavePageToJPEG( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadSetCookie( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadSetTargetFrameRate( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadFullRepaint( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadSetPageScale( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadExitFullScreen( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadCloseFullScreenFlashIfOpen( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadPauseFullScreenFlashMovieIfOpen( const CHTMLProtoBufMsg &htmlCommand ); - void ThreadGetFocusedNodeText( const CHTMLProtoBufMsg &htmlCommand ); - - void ThreadBrowserVerticalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ); - void ThreadBrowserHorizontalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ); - - bool BIsValidBrowserHandle( uint32 nHandle, int &iClient ); - void SendSizeChangeEvents(); - void CheckForFullScreenFlashControl(); - - CThreadEvent m_WakeEvent; - CUtlString m_sHTMLCacheDir; - CUtlString m_sCookiePath; - bool m_bExit; - CThreadEvent m_eventDidExit; - - CUtlLinkedList m_listClientHandlers; - - CTSQueue m_tslCommandBuffers; - CUtlVector m_vecQueueCommands; - CTSQueue m_tslResponseBuffers; - CUtlVector m_vecQueueResponses; - - CTSList m_tslUnsedBuffers; - - CThreadEvent m_evWaitingForCommand; - CThreadEvent m_evWaitingForResponse; - int m_nTargetFrameRate; - uint16 m_nBrowserSerial; - bool m_bFullScreenFlashVisible; -#ifdef WIN32 - HWND m_flashfullscreenHWND; -#endif - bool m_bSawUserInputThisFrame; - - struct SizeChange_t - { - int iBrowser; - int nBeforeWidth; - int nBeforeHeight; - float flNewZoom; - }; - CUtlMap< int, SizeChange_t, int > m_mapSizeChangesPending; -}; - -CCEFThread &AccessHTMLWrapper(); - -#endif // HTML_CHROME_H diff --git a/vgui2/chromehtml/html_mac.mm b/vgui2/chromehtml/html_mac.mm deleted file mode 100644 index f85f091a..00000000 --- a/vgui2/chromehtml/html_mac.mm +++ /dev/null @@ -1,16 +0,0 @@ -//=========== Copyright Valve Corporation, All rights reserved. ===============// -// -// Purpose: -//=============================================================================// - -#include - -extern "C" void *CreateAutoReleasePool() -{ - return [[NSAutoreleasePool alloc] init]; -} - -extern "C" void ReleaseAutoReleasePool( void *pool ) -{ - [pool release]; -} \ No newline at end of file diff --git a/vgui2/chromehtml/htmlmanager.h b/vgui2/chromehtml/htmlmanager.h deleted file mode 100644 index 02b3728f..00000000 --- a/vgui2/chromehtml/htmlmanager.h +++ /dev/null @@ -1,30 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -//=============================================================================// - -#ifndef HTMLMANAGER_H -#define HTMLMANAGER_H - -#ifdef _WIN32 -#pragma once -#endif - -//----------------------------------------------------------------------------- -// Purpose: helper funcs to pump chrome -//----------------------------------------------------------------------------- -void ChromeInit( const char *pchHTMLCacheDir, const char *pchCookiePath ); -void ChromeShutdown(); - -#ifdef DBGFLAG_VALIDATE -void ChromeValidate( CValidator &validator, const char *pchName ); -bool ChromeResumeFromValidate(); -bool ChromePrepareForValidate(); -#endif - -bool ChromeSetWebCookie( const char *pchHostname, const char *pchName, const char *pchValue, const char *pchPath ); -void ChromeSetClientBuildID( uint64 ulBuildID ); - -enum EMouseState { UP,DOWN,MOVE,DBLCLICK }; - -#endif // HTMLMANAGER_H diff --git a/vgui2/chromehtml/htmlmessages.proto b/vgui2/chromehtml/htmlmessages.proto deleted file mode 100644 index 355f0942..00000000 --- a/vgui2/chromehtml/htmlmessages.proto +++ /dev/null @@ -1,1025 +0,0 @@ -//====== Copyright 1996-2010, Valve Corporation, All rights reserved. ======= -// -// Purpose: The file defines our Google Protocol Buffers which are used in IPC -// and inter-thread communcations in the tenfoot UI rendering system. -// -//============================================================================= - -// We care more about speed than code size -option optimize_for = SPEED; - -// We don't use the service generation functionality -option cc_generic_services = false; - -// -// STYLE NOTES: -// -// Use CamelCase CMsgMyMessageName style names for messages. -// -// Use lowercase _ delimited names like my_steam_id for field names, this is non-standard for Steam, -// but plays nice with the Google formatted code generation. -// -// Try not to use required fields ever. Only do so if you are really really sure you'll never want them removed. -// Optional should be preffered as it will make versioning easier and cleaner in the future if someone refactors -// your message and wants to remove or rename fields. This is especially important for messages sent from the server -// to clients. We may be able to safely remove a field if it's optional even if an old client expects it, but if it -// was required we can't remove it. Using required doesn't really offer any advantages at all as you'll just end up -// with an empty message with all default values if you receive a message missing a required field, so there is no -// real advantage to using it ever. -// -// Use fixed64 for JobId_t, GID_t, or SteamID or GameID. This is appropriate for any field that is normally -// going to be larger than 2^56. Otherwise use int64 for 64 bit values that are frequently smaller -// than 2^56 as it will safe space on the wire in those cases. -// -// Similar to fixed64, use fixed32 for RTime32 or other 32 bit values that are frequently larger than -// 2^28. It will safe space in those cases, otherwise use int32 which will safe space for smaller values. -// An exception to this rule for RTime32 is if the value will frequently be zero rather than set to an actual -// time. -// -// Use uint32 with [default = 2] for EResult values in messages. The default is important since the normal int/uint -// default of 0 is not a valid EResult value. 2 is k_EResultFail. -// -// See: http://code.google.com/apis/protocolbuffers/docs/proto.html for a complete language guide. -// - - -// -// key up - eHTMLCommands_KeyUp -// -message CMsgKeyUp -{ - optional uint32 browser_handle = 1; - optional uint32 keyCode = 2; - optional uint32 modifiers = 3; -} - - -// -// key down - eHTMLCommands_KeyDown -// -message CMsgKeyDown -{ - optional uint32 browser_handle = 1; - optional uint32 keyCode = 2; - optional uint32 modifiers = 3; -} - - -// -// key unichar - eHTMLCommands_KeyChar -// -message CMsgKeyChar -{ - optional uint32 browser_handle = 1; - optional uint32 unichar = 2; -} - - -// -// mouse down - eHTMLCommands_MouseDown -// -message CMsgMouseDown -{ - optional uint32 browser_handle = 1; - optional uint32 mouse_button = 2; -} - - -// -// mouse up - eHTMLCommands_MouseUp -// -message CMsgMouseUp -{ - optional uint32 browser_handle = 1; - optional uint32 mouse_button = 2; -} - - -// -// mouse dbl click - eHTMLCommands_MouseDblClick -// -message CMsgMouseDblClick -{ - optional uint32 browser_handle = 1; - optional uint32 mouse_button = 2; -} - - -// -// mouse wheel - eHTMLCommands_MouseWheel -// -message CMsgMouseWheel -{ - optional uint32 browser_handle = 1; - optional int32 delta = 2; -} - - -// -// mouse move - eHTMLCommands_MouseMove -// -message CMsgMouseMove -{ - optional uint32 browser_handle = 1; - optional int32 x = 2; - optional int32 y = 3; -} - - -// -// mouse leave - eHTMLCommands_MouseLeave -// -message CMsgMouseLeave -{ - optional uint32 browser_handle = 1; -} - - -// -// make a cef control - eHTMLCommands_BrowserCreate -// -message CMsgBrowserCreate -{ - optional uint32 request_id = 1; - optional bool popup = 2 [default = false]; - optional string useragent = 3; -} - - -// -// ack to the main thread a control was made - eHTMLCommands_BrowserCreateResponse -// -message CMsgBrowserCreateResponse -{ - optional uint32 browser_handle = 1; - optional uint32 request_id = 2; -} - - -// -// delete a browser - eHTMLCommands_BrowserRemove -// -message CMsgBrowserRemove -{ - optional uint32 browser_handle = 1; -} - - -// -// send loc strings over to use for error page - eHTMLCommands_BrowserErrorStrings -// -message CMsgBrowserErrorStrings -{ - optional uint32 browser_handle = 1; - optional string title = 2; - optional string header = 3; - optional string cache_miss = 4; - optional string bad_url = 5; - optional string connection_problem = 6; - optional string proxy_problem = 7; - optional string unknown = 8; -} - - -// -// Set a browser to this size - eHTMLCommands_BrowserSize -// -message CMsgBrowserSize -{ - optional uint32 browser_handle = 1; - optional uint32 width = 2; - optional uint32 height = 3; -} - - -// -// Set position in the window - eHTMLCommands_BrowserPosition -// -message CMsgBrowserPosition -{ - optional uint32 browser_handle = 1; - optional uint32 x = 2; - optional uint32 y = 3; -} - - -// -// load this url - eHTMLCommands_PostURL -// -message CMsgPostURL -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional string post = 3; - optional uint32 pageserial = 4; -} - - -// -// have cef send this html header for all page loads -eHTMLCommands_AddHeader -// -message CMsgAddHeader -{ - optional uint32 browser_handle = 1; - optional string key = 2; - optional string value = 3; -} - - -// -// stop loading a page - eHTMLCommands_StopLoad -// -message CMsgStopLoad -{ - optional uint32 browser_handle = 1; -} - - -// -// reload a page - eHTMLCommands_Reload -// -message CMsgReload -{ - optional uint32 browser_handle = 1; -} - - -// -// next page - eHTMLCommands_GoForward -// -message CMsgGoForward -{ - optional uint32 browser_handle = 1; -} - - -// -// back a page in the stack - eHTMLCommands_GoBack -// -message CMsgGoBack -{ - optional uint32 browser_handle = 1; -} - - -// -// copy the currently selected text - eHTMLCommands_Copy -// -message CMsgCopy -{ - optional uint32 browser_handle = 1; -} - - -// -// paste text here from the clipboard - eHTMLCommands_Paste -// -message CMsgPaste -{ - optional uint32 browser_handle = 1; -} - - -// -// run this javascript on the current page - eHTMLCommands_ExecuteJavaScript -// -message CMsgExecuteJavaScript -{ - optional uint32 browser_handle = 1; - optional string script = 2; -} - - -// -// tell it that it has key focus - eHTMLCommands_SetFocus -// -message CMsgSetFocus -{ - optional uint32 browser_handle = 1; - optional bool focus = 2; -} - - -// -// how big is the scroll bar plz - eHTMLCommands_HorizontalScrollBarSize -// -message CMsgHorizontalScrollBarSize -{ - optional uint32 browser_handle = 1; -} - - -// -// its this big! - eHTMLCommands_HorizontalScrollBarSizeResponse -// -message CMsgHorizontalScrollBarSizeResponse -{ - optional uint32 browser_handle = 1; - optional uint32 x = 2; - optional uint32 y = 3; - optional uint32 wide = 4; - optional uint32 tall = 5; - optional uint32 scroll_max = 6; - optional uint32 scroll = 7; - optional float zoom = 8; - optional bool visible = 9; -} - - -// -// eHTMLCommands_VerticalScrollBarSize -// -message CMsgVerticalScrollBarSize -{ - optional uint32 browser_handle = 1; -} - - -// -// eHTMLCommands_VerticalScrollBarSizeResponse -// -message CMsgVerticalScrollBarSizeResponse -{ - optional uint32 browser_handle = 1; - optional uint32 x = 2; - optional uint32 y = 3; - optional uint32 wide = 4; - optional uint32 tall = 5; - optional uint32 scroll_max = 6; - optional uint32 scroll = 7; - optional float zoom = 8; - optional bool visible = 9; -} - - -// -// find this string in the page - eHTMLCommands_Find -// -message CMsgFind -{ - optional uint32 browser_handle = 1; - optional string find = 2; - optional bool infind = 3; - optional bool reverse = 4 [ default = false ]; -} - -// -// done finding - eHTMLCommands_StopFind -// -message CMsgStopFind -{ - optional uint32 browser_handle = 1; -} - -// -// scroll here - eHTMLCommands_SetHorizontalScroll -// -message CMsgSetHorizontalScroll -{ - optional uint32 browser_handle = 1; - optional uint32 scroll = 2; -} - - -// -// scroll here - eHTMLCommands_SetHorizontalScroll -// -message CMsgSetVerticalScroll -{ - optional uint32 browser_handle = 1; - optional uint32 scroll = 2; -} - - -// -// zoom the page this much, 0 to 100 - eHTMLCommands_SetZoomLevel -// -message CMsgSetZoomLevel -{ - optional uint32 browser_handle = 1; - optional uint32 zoom = 2; -} - - -// -// look at the page source in notepad - eHTMLCommands_ViewSource -// -message CMsgViewSource -{ - optional uint32 browser_handle = 1; -} - - -// -// browser is setup and ready to load pages after a create - eHTMLCommands_BrowserReady -// -message CMsgBrowserReady -{ - optional uint32 browser_handle = 1; -} - - -// -// new url loaded - eHTMLCommands_URLChanged -// -message CMsgURLChanged -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional string postData = 3; - optional bool bIsRedirect = 4; - optional string pagetitle = 5; - optional bool bNewNavigation = 6; -} - - -message CHTMLHeader -{ - optional string key = 1; - optional string value = 2; -} - -message CHTMLPageSecurityInfo -{ - optional bool bIsSecure = 1 [default = false]; - optional bool bHasCertError = 2 [default = false]; - optional string issuerName = 3 [default = ""]; - optional string certName = 4 [default = "" ]; - optional int32 certExpiry = 5 [default = 0]; - optional int32 nCertBits = 6 [default = 0]; - optional bool bIsEVCert = 7 [default = false]; - -} - -// -// finished loading a page - eHTMLCommands_FinishedRequest -// -message CMsgFinishedRequest -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional string pageTitle = 3; - optional CHTMLPageSecurityInfo security_info = 4; - repeated CHTMLHeader headers = 5; -} - - -// -// starting a page load - eHTMLCommands_StartRequest -// -message CMsgStartRequest -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional string target = 3; - optional string postData = 4; - optional bool bIsRedirect = 5; -} - - -// -// do we want to allow this load - eHTMLCommands_StartRequestResponse -// -message CMsgStartRequestResponse -{ - optional uint32 browser_handle = 1; - optional bool bAllow = 2; -} - - -// -// a html popup is showing - eHTMLCommands_ShowPopup -// -message CMsgShowPopup -{ - optional uint32 browser_handle = 1; -} - - -// -// done with the popup - eHTMLCommands_HidePopup -// -message CMsgHidePopup -{ - optional uint32 browser_handle = 1; -} - - -// -// a html popup is changing size - eHTMLCommands_SizePopup -// -message CMsgSizePopup -{ - optional uint32 browser_handle = 1; - optional uint32 x = 2; - optional uint32 y = 3; - optional uint32 wide = 4; - optional uint32 tall = 5; -} - - -// -// new tab plz - eHTMLCommands_OpenNewTab -// -message CMsgOpenNewTab -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional bool bForeground = 3; -} - - -// -// do we allow the tab - eHTMLCommands_OpenNewTabResponse -// -message CMsgOpenNewTabResponse -{ - optional uint32 browser_handle = 1; - optional bool bAllow = 2; -} - - -// -// popup a new page here please - eHTMLCommands_PopupHTMLWindow -// -message CMsgPopupHTMLWindow -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional uint32 x = 3; - optional uint32 y = 4; - optional uint32 wide = 5; - optional uint32 tall = 6; -} - - -// -// do we allow the popup - eHTMLCommands_PopupHTMLWindowResponse -// -message CMsgPopupHTMLWindowResponse -{ - optional uint32 browser_handle = 1; - optional bool bAllow = 2; -} - - -// -// title for the page - eHTMLCommands_SetHTMLTitle -// -message CMsgSetHTMLTitle -{ - optional uint32 browser_handle = 1; - optional string title = 2; -} - -// -// loading a url on a page - eHTMLCommands_LoadingResource -// -message CMsgLoadingResource -{ - optional uint32 browser_handle = 1; - optional string url = 2; -} - -// -// status to display - eHTMLCommands_StatusText -// -message CMsgStatusText -{ - optional uint32 browser_handle = 1; - optional string text = 2; -} - -// -// mouse cursor to this - eHTMLCommands_SetCursor -// -message CMsgSetCursor -{ - optional uint32 browser_handle = 1; - optional uint32 cursor = 2; - optional uint32 data = 3; - optional uint32 wide = 4; - optional uint32 tall = 5; - optional uint32 xhotspot = 6; - optional uint32 yhotspot = 7; -} - -// -// let the user pick a file - eHTMLCommands_FileLoadDialog -// -message CMsgFileLoadDialog -{ - optional uint32 browser_handle = 1; - optional string title = 2; - optional string initialFile = 3; -} - -// -// the user picked this - eHTMLCommands_FileLoadDialogResponse -// -message CMsgFileLoadDialogResponse -{ - optional uint32 browser_handle = 1; - repeated string files = 2; -} - - -// -// show a tooltip - eHTMLCommands_ShowToolTip -// -message CMsgShowToolTip -{ - optional uint32 browser_handle = 1; - optional string text = 2; -} - - -// -// update tooltip - eHTMLCommands_UpdateToolTip -// -message CMsgUpdateToolTip -{ - optional uint32 browser_handle = 1; - optional string text = 2; -} - - -// -// done with tooltip - eHTMLCommands_HideToolTip -// -message CMsgHideToolTip -{ - optional uint32 browser_handle = 1; -} - - -// -// got search answers - eHTMLCommands_SearchResults -// -message CMsgSearchResults -{ - optional uint32 browser_handle = 1; - optional int32 activeMatch = 2; - optional int32 results = 3; -} - - -// -// close this window plz - eHTMLCommands_Close -// -message CMsgClose -{ - optional uint32 browser_handle = 1; -} - - -// -// need image for the page - eHTMLCommands_NeedsPaint -// -message CMsgNeedsPaint -{ - optional uint32 browser_handle = 1; - optional uint64 rgba = 2; - optional uint32 wide = 3; - optional uint32 tall = 4; - optional uint32 textureid = 5; - optional uint32 updatex = 6; - optional uint32 updatey = 7; - optional uint32 updatewide = 8; - optional uint32 updatetall = 9; - optional uint32 scrollx = 10; - optional uint32 scrolly = 11; - - optional uint64 combobox_rgba = 12 [default = 0]; - optional uint32 combobox_wide = 13 [default = 0]; - optional uint32 combobox_tall = 14 [default = 0]; - - optional uint32 pageserial = 15; -} - - -// -// all done with the paint pointer - eHTMLCommands_NeedsPaintResponse -// -message CMsgNeedsPaintResponse -{ - optional uint32 browser_handle = 1; - optional uint32 textureid = 2; -} - -// -// what zoom lvl we at? - eHTMLCommands_GetZoom -// -message CMsgGetZoom -{ - optional uint32 browser_handle = 1; -} - - -// -// this zoom level! - eHTMLCommands_GetZoomResponse -// -message CMsgGetZoomResponse -{ - optional uint32 browser_handle = 1; - optional float zoom = 2; -} - - -// -// get the link at this x,y - eHTMLCommands_LinkAtPosition -// -message CMsgLinkAtPosition -{ - optional uint32 browser_handle = 1; - optional uint32 x = 2; - optional uint32 y = 3; -} - - -// -// link at this pos - eHTMLCommands_LinkAtPosition -// -message CMsgLinkAtPositionResponse -{ - optional uint32 browser_handle = 1; - optional uint32 x = 2; - optional uint32 y = 3; - optional string url = 4; - optional bool blivelink = 5; - optional bool binput = 6; -} - - -// -// scale the page to the element at this position on the page, for at least this size -// -message CMsgZoomToElementAtPosition -{ - optional uint32 browser_handle = 1; - optional uint32 x = 2; - optional uint32 y = 3; -} - -// -// response from the zoom, what rect did we pick and what zoom factor -// -message CMsgZoomToElementAtPositionResponse -{ - optional uint32 browser_handle = 1; - optional sint32 initial_x = 2; - optional sint32 initial_y = 3; - optional uint32 initial_width = 4; - optional uint32 initial_height = 5; - optional sint32 final_x = 6; - optional sint32 final_y = 7; - optional uint32 final_width = 8; - optional uint32 final_height = 9; - optional float zoom = 10; -} - - -// -// increase (or decrease if negative) the page scale factor used on this page -// -message CMsgScalePageToValue -{ - optional uint32 browser_handle = 1; - optional float scale = 2; - optional float x = 3; - optional float y = 4; -} - - -// -// increase (or decrease if negative) the page scale factor used on this page -// -message CMsgScalePageToValueResponse -{ - optional uint32 browser_handle = 1; - optional float zoom = 2; - optional int32 width_delta = 3; - optional int32 height_delta = 4; -} - -// -// request a screenshot get written for this loaded url -// -message CMsgSavePageToJPEG -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional string filename = 3; - optional uint32 width = 4; - optional uint32 height = 5; -} - - -// -// screenshot taken, tell the main thread we did it -// -message CMsgSavePageToJPEGResponse -{ - optional uint32 browser_handle = 1; - optional string url = 2; - optional string filename = 3; -} - - -// -// web control wants to pop an alert dialog -// -message CMsgJSAlert -{ - optional uint32 browser_handle = 1; - optional string message = 2; -} - -// -// web control wants to pop an confirmation dialog -// -message CMsgJSConfirm -{ - optional uint32 browser_handle = 1; - optional string message = 2; -} - - -// -// done showing the confirmation -// -message CMsgJSDialogResponse -{ - optional uint32 browser_handle = 1; - optional bool result = 2; -} - -// -// web control telling us the forward and back state -// -message CMsgCanGoBackAndForward -{ - optional uint32 browser_handle = 1; - optional bool bgoback = 2; - optional bool bgoforward = 3; -} - -// -// web control telling us to open a steam dialog -// -message CMsgOpenSteamURL -{ - optional uint32 browser_handle = 1; - optional string url = 2; -} - - -// -// set a cookie for the cef instance -// -message CMsgSetCookie -{ - optional string key = 1; - optional string value = 2; - optional string path = 3; - optional string host = 4; - optional uint32 expires = 5; -} - - -// -// tell cef that html isn't active so run slow -// -message CMsgSetTargetFrameRate -{ - optional uint32 nTargetFrameRate = 1; // FPS to run the CEF think loop at -} - - -// -// request a full repaint of the control -// -message CMsgFullRepaint -{ - optional uint32 browser_handle = 1; -} - - -// -// CEF wants to go fullscreen please -// -message CMsgRequestFullScreen -{ - optional uint32 browser_handle = 1; -} - - -// -// do we allow fullscreen -// -message CMsgRequestFullScreenResponse -{ - optional uint32 browser_handle = 1; - optional bool ballow = 2; -} - - -// -// exit fullscreen if we are in it -// -message CMsgExitFullScreen -{ - optional uint32 browser_handle = 1; -} - - -// -// request all the cookies for this url -// -message CMsgGetCookiesForURL -{ - optional uint32 browser_handle = 1; - optional string url = 2; -} - - -message CCookie -{ - optional string name = 1; - optional string value = 2; - optional string domain = 3; - optional string path = 4; -} - - -// -// return all the cookies for this url -// -message CMsgGetCookiesForURLResponse -{ - optional uint32 browser_handle = 1; - optional string url = 2; - repeated CCookie cookies = 3; -} - - -// -// sent when a html node gets key focus -// -message CMsgNodeHasFocus -{ - optional uint32 browser_handle = 1; - optional bool bInput = 2; - optional string name = 3; - optional string elementtagname = 4; - optional string searchbuttontext = 5; - optional bool bHasMultipleInputs = 6; - optional string input_type = 7; // type of input, if node is input; otherwise unset -} - - -// -// zoom the html control to the node with input focus -// -message CMsgZoomToFocusedElement -{ - optional uint32 browser_handle = 1; - optional uint32 leftoffset = 2 [default = 0]; - optional uint32 topoffset = 3 [default = 0]; -} - - -// -// ask a fullscreen flash control to close if open -// -message CMsgCloseFullScreenFlashIfOpen -{ - optional uint32 browser_handle = 1; -} - -// -// ask a fullscreen flash control to pause itself if open -// -message CMsgPauseFullScreenFlashMovieIfOpen -{ - optional uint32 browser_handle = 1; -} - - -// -// get the string currently contained in the focused node -// -message CMsgFocusedNodeText -{ - optional uint32 browser_handle = 1; -} - - -// -// what text is in the focused node -// -message CMsgFocusedNodeTextResponse -{ - optional uint32 browser_handle = 1; - optional string value = 2; -} diff --git a/vgui2/chromehtml/stdafx.h b/vgui2/chromehtml/stdafx.h deleted file mode 100644 index 9746e141..00000000 --- a/vgui2/chromehtml/stdafx.h +++ /dev/null @@ -1,19 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -#ifndef STDAFX_H -#define STDAFX_H - -#include "tier0/platform.h" -#include "tier0/vprof.h" -#include "tier1/utlarray.h" -#include "tier1/utlbuffer.h" -#include "fileio.h" -//#include "constants.h" -#include "steam/steamtypes.h" -#include "tier0/validator.h" -#include "tier1/utlmap.h" -#include "tier1/utlstring.h" -#include "tier0/tslist.h" -#include "html/ihtmlchrome.h" -#include "html/htmlprotobuf.h" - -#endif diff --git a/vgui2/vgui_controls/AnimationController.cpp b/vgui2/vgui_controls/AnimationController.cpp index d7d32e36..ce3a1e45 100644 --- a/vgui2/vgui_controls/AnimationController.cpp +++ b/vgui2/vgui_controls/AnimationController.cpp @@ -345,7 +345,7 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) } // walk the commands - while (token && token[0]) + while (token[0]) { // get the command type pMem = ParseFile(pMem, token, NULL); diff --git a/vgui2/vgui_controls/HTML.cpp b/vgui2/vgui_controls/HTML.cpp index d7f68f10..8da568ea 100644 --- a/vgui2/vgui_controls/HTML.cpp +++ b/vgui2/vgui_controls/HTML.cpp @@ -13,17 +13,6 @@ #include #include -#include -#include -#include "htmlmessages.pb.h" -#include -#include - -#include "html/ipainthtml.h" -#include "html/ihtmlchrome.h" -#include "html/ichromehtmlwrapper.h" -#include "html/htmlprotobuf.h" - #include "filesystem.h" #include "../vgui2/src/vgui_key_translation.h" @@ -37,20 +26,6 @@ using namespace vgui; -// helper to send IPC messages to the CEF thread -#define DISPATCH_MESSAGE( eCmd ) \ - if (surface()->AccessChromeHTMLController()) \ - { \ - cmd.Body().set_browser_handle( m_iBrowser );\ - HTMLCommandBuffer_t *pBuf = surface()->AccessChromeHTMLController()->GetFreeCommandBuffer( eCmd, m_iBrowser ); \ - cmd.SerializeCrossProc( &pBuf->m_Buffer ); \ - if ( m_iBrowser == -1 ) { m_vecPendingMessages.AddToTail( pBuf ); } \ - else \ - { \ - surface()->AccessChromeHTMLController()->PushCommand( pBuf ); \ - surface()->AccessChromeHTMLController()->WakeThread(); \ - }\ - } \ const int k_nMaxCustomCursors = 2; // the max number of custom cursors we keep cached PER html control @@ -118,7 +93,6 @@ public: private: HTML *m_pParent; - CUtlVector m_vecPendingMessages; }; @@ -187,7 +161,32 @@ private: //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- -HTML::HTML(Panel *parent, const char *name, bool allowJavaScript, bool bPopupWindow) : Panel(parent, name) +HTML::HTML(Panel *parent, const char *name, bool allowJavaScript, bool bPopupWindow) : Panel(parent, name), +m_NeedsPaint( this, &HTML::BrowserNeedsPaint ), +m_ComboNeedsPaint( this, &HTML::BrowserComboNeedsPaint ), +m_StartRequest( this, &HTML::BrowserStartRequest ), +m_URLChanged( this, &HTML::BrowserURLChanged ), +m_FinishedRequest( this, &HTML::BrowserFinishedRequest ), +m_ShowPopup( this, &HTML::BrowserShowPopup ), +m_HidePopup( this, &HTML::BrowserHidePopup ), +m_SizePopup( this, &HTML::BrowserSizePopup ), +m_LinkInNewTab( this, &HTML::BrowserOpenNewTab ), +m_ChangeTitle( this, &HTML::BrowserSetHTMLTitle ), +m_FileLoadDialog( this, &HTML::BrowserFileLoadDialog ), +m_SearchResults( this, &HTML::BrowserSearchResults ), +m_CloseBrowser( this, &HTML::BrowserClose ), +m_HorizScroll( this, &HTML::BrowserHorizontalScrollBarSizeResponse ), +m_VertScroll( this, &HTML::BrowserVerticalScrollBarSizeResponse ), +m_LinkAtPosResp( this, &HTML::BrowserLinkAtPositionResponse ), +m_JSAlert( this, &HTML::BrowserJSAlert ), +m_JSConfirm( this, &HTML::BrowserJSConfirm ), +m_CanGoBackForward( this, &HTML::BrowserCanGoBackandForward ), +m_NewWindow( this, &HTML::BrowserPopupHTMLWindow ), +m_SetCursor( this, &HTML::BrowserSetCursor ), +m_StatusText( this, &HTML::BrowserStatusText ), +m_ShowTooltip( this, &HTML::BrowserShowToolTip ), +m_UpdateTooltip( this, &HTML::BrowserUpdateToolTip ), +m_HideTooltip( this, &HTML::BrowserHideToolTip ) { m_iHTMLTextureID = 0; m_iComboBoxTextureID = 0; @@ -197,18 +196,22 @@ HTML::HTML(Panel *parent, const char *name, bool allowJavaScript, bool bPopupWin m_bRequestingDragURL = false; m_bRequestingCopyLink = false; m_flZoom = 100.0f; - m_iBrowser = -1; m_bNeedsFullTextureUpload = false; m_pInteriorPanel = new HTMLInterior( this ); SetPostChildPaintEnabled( true ); - if (surface() && surface()->AccessChromeHTMLController()) + + m_unBrowserHandle = INVALID_HTTMLBROWSER; + m_SteamAPIContext.Init(); + if ( m_SteamAPIContext.SteamHTMLSurface() ) { - surface()->AccessChromeHTMLController()->CreateBrowser( this, bPopupWindow, surface()->GetWebkitHTMLUserAgentString() ); + m_SteamAPIContext.SteamHTMLSurface()->Init(); + SteamAPICall_t hSteamAPICall = m_SteamAPIContext.SteamHTMLSurface()->CreateBrowser( surface()->GetWebkitHTMLUserAgentString(), NULL ); + m_SteamCallResultBrowserReady.Set( hSteamAPICall, this, &HTML::OnBrowserReady ); } else { - Warning("Unable to access ChromeHTMLController"); + Warning("Unable to access SteamHTMLSurface"); } m_iScrollBorderX=m_iScrollBorderY=0; m_bScrollBarEnabled = true; @@ -250,6 +253,22 @@ HTML::HTML(Panel *parent, const char *name, bool allowJavaScript, bool bPopupWin } +//----------------------------------------------------------------------------- +// Purpose: browser is ready to show pages +//----------------------------------------------------------------------------- +void HTML::OnBrowserReady( HTML_BrowserReady_t *pBrowserReady, bool bIOFailure ) +{ + m_unBrowserHandle = pBrowserReady->unBrowserHandle; + BrowserResize(); + + if (!m_sPendingURLLoad.IsEmpty()) + { + PostURL( m_sPendingURLLoad, m_sPendingPostData, false ); + m_sPendingURLLoad.Clear(); + } +} + + //----------------------------------------------------------------------------- // Purpose: Destructor //----------------------------------------------------------------------------- @@ -257,9 +276,9 @@ HTML::~HTML() { m_pContextMenu->MarkForDeletion(); - if (surface()->AccessChromeHTMLController()) + if ( m_SteamAPIContext.SteamHTMLSurface() ) { - surface()->AccessChromeHTMLController()->RemoveBrowser( this ); + m_SteamAPIContext.SteamHTMLSurface()->RemoveBrowser( m_unBrowserHandle ); } FOR_EACH_VEC( m_vecHCursor, i ) @@ -412,10 +431,6 @@ void HTML::OnMove() // tell cef where we are on the screen so plugins can correctly render int nPanelAbsX, nPanelAbsY; ipanel()->GetAbsPos( GetVPanel(), nPanelAbsX, nPanelAbsY ); - CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserPosition ); - cmd.Body().set_x( nPanelAbsX ); - cmd.Body().set_y( nPanelAbsY ); - DISPATCH_MESSAGE( eHTMLCommands_BrowserPosition ); if ( m_pComboBoxHost && m_pComboBoxHost->IsVisible() ) { @@ -424,129 +439,6 @@ void HTML::OnMove() } -//----------------------------------------------------------------------------- -// Purpose: calculates the need for and position of both horizontal and vertical scroll bars -//----------------------------------------------------------------------------- -void HTML::CalcScrollBars(int w, int h) -{ - bool bScrollbarVisible = _vbar->IsVisible(); - - if ( m_bScrollBarEnabled ) - { - for ( int i = 0; i < 2; i++ ) - { - int scrollx, scrolly, scrollwide, scrolltall; - bool bVisible = false; - if ( i==0 ) - { - scrollx = m_scrollHorizontal.m_nX; - scrolly = m_scrollHorizontal.m_nY; - scrollwide = m_scrollHorizontal.m_nWide; - scrolltall = m_scrollHorizontal.m_nTall; - bVisible = m_scrollHorizontal.m_bVisible; - - // scrollbar positioning tweaks - should be moved into a resource file - scrollwide += 14; - scrolltall += 5; - } - else - { - scrollx = m_scrollVertical.m_nX; - scrolly = m_scrollVertical.m_nY; - scrollwide = m_scrollVertical.m_nWide; - scrolltall = m_scrollVertical.m_nTall; - bVisible = m_scrollVertical.m_bVisible; - - // scrollbar positioning tweaks - should be moved into a resource file - //scrollx -= 3; - if ( m_scrollHorizontal.m_bVisible ) - scrolltall += 16; - else - scrolltall -= 2; - - scrollwide += 5; - } - - if ( bVisible && scrollwide && scrolltall ) - { - int panelWide, panelTall; - GetSize( panelWide, panelTall ); - - ScrollBar *bar = _vbar; - if ( i == 0 ) - bar = _hbar; - - if (!bar->IsVisible()) - { - bar->SetVisible(true); - // displayable area has changed, need to force an update - PostMessage(this, new KeyValues("OnSliderMoved"), 0.02f); - } - - int rangeWindow = panelTall - scrollwide; - if ( i==0 ) - rangeWindow = panelWide - scrolltall; - int range = m_scrollVertical.m_nMax + m_scrollVertical.m_nTall; - if ( i == 0 ) - range = m_scrollHorizontal.m_nMax + m_scrollVertical.m_nWide; - int curValue = m_scrollVertical.m_nScroll; - if ( i == 0 ) - curValue = m_scrollHorizontal.m_nScroll; - - bar->SetEnabled(false); - bar->SetRangeWindow( rangeWindow ); - bar->SetRange( 0, range ); // we want the range [0.. (img_h - h)], but the scrollbar actually returns [0..(range-rangeWindow)] so make sure -h gets deducted from the max range value - bar->SetButtonPressedScrollValue( 5 ); - if ( curValue > ( bar->GetValue() + 5 ) || curValue < (bar->GetValue() - 5 ) ) - bar->SetValue( curValue ); - - if ( i == 0 ) - { - bar->SetPos( 0, h - scrolltall - 1 ); - bar->SetWide( scrollwide ); - bar->SetTall( scrolltall ); - } - else - { - bar->SetPos( w - scrollwide, 0 ); - bar->SetTall( scrolltall ); - bar->SetWide( scrollwide ); - } - - if ( i == 0 ) - m_iScrollBorderY=scrolltall; - else - m_iScrollBorderX=scrollwide; - } - else - { - if ( i == 0 ) - { - m_iScrollBorderY=0; - _hbar->SetVisible( false ); - } - else - { - m_iScrollBorderX=0; - _vbar->SetVisible( false ); - - } - } - } - } - else - { - m_iScrollBorderX = 0; - m_iScrollBorderY=0; - _vbar->SetVisible(false); - _hbar->SetVisible(false); - } - - if ( bScrollbarVisible != _vbar->IsVisible() ) - InvalidateLayout(); -} - - //----------------------------------------------------------------------------- // Purpose: opens the URL, will accept any URL that IE accepts //----------------------------------------------------------------------------- @@ -560,7 +452,7 @@ void HTML::OpenURL(const char *URL, const char *postData, bool force) //----------------------------------------------------------------------------- void HTML::PostURL(const char *URL, const char *pchPostData, bool force) { - if ( m_iBrowser < 0 ) + if ( m_unBrowserHandle == INVALID_HTTMLBROWSER ) { m_sPendingURLLoad = URL; m_sPendingPostData = pchPostData; @@ -587,33 +479,27 @@ void HTML::PostURL(const char *URL, const char *pchPostData, bool force) g_pFullFileSystem->GetLocalPath( baseDir, fileLocation, sizeof(fileLocation) ); Q_snprintf(htmlLocation, sizeof(htmlLocation), "file://%s", fileLocation); - CHTMLProtoBufMsg cmd( eHTMLCommands_PostURL ); - cmd.Body().set_url( htmlLocation ); - DISPATCH_MESSAGE( eHTMLCommands_PostURL ); - + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->LoadURL( m_unBrowserHandle, htmlLocation, NULL ); } else { - CHTMLProtoBufMsg cmd( eHTMLCommands_PostURL ); - cmd.Body().set_url( URL ); - DISPATCH_MESSAGE( eHTMLCommands_PostURL ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->LoadURL( m_unBrowserHandle, URL, NULL ); } } else { if ( pchPostData && Q_strlen(pchPostData) > 0 ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_PostURL ); - cmd.Body().set_url( URL ); - cmd.Body().set_post( pchPostData ); - DISPATCH_MESSAGE( eHTMLCommands_PostURL ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->LoadURL( m_unBrowserHandle, URL, pchPostData ); } else { - CHTMLProtoBufMsg cmd( eHTMLCommands_PostURL ); - cmd.Body().set_url( URL ); - DISPATCH_MESSAGE( eHTMLCommands_PostURL ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->LoadURL( m_unBrowserHandle, URL, NULL ); } } } @@ -624,8 +510,8 @@ void HTML::PostURL(const char *URL, const char *pchPostData, bool force) //----------------------------------------------------------------------------- bool HTML::StopLoading() { - CHTMLProtoBufMsg cmd( eHTMLCommands_StopLoad ); - DISPATCH_MESSAGE( eHTMLCommands_StopLoad ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->StopLoad( m_unBrowserHandle ); return true; } @@ -635,8 +521,8 @@ bool HTML::StopLoading() //----------------------------------------------------------------------------- bool HTML::Refresh() { - CHTMLProtoBufMsg cmd( eHTMLCommands_Reload ); - DISPATCH_MESSAGE( eHTMLCommands_Reload ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->Reload( m_unBrowserHandle ); return true; } @@ -646,8 +532,8 @@ bool HTML::Refresh() //----------------------------------------------------------------------------- void HTML::GoBack() { - CHTMLProtoBufMsg cmd( eHTMLCommands_GoBack ); - DISPATCH_MESSAGE( eHTMLCommands_GoBack ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->GoBack( m_unBrowserHandle ); } @@ -656,8 +542,8 @@ void HTML::GoBack() //----------------------------------------------------------------------------- void HTML::GoForward() { - CHTMLProtoBufMsg cmd( eHTMLCommands_GoForward ); - DISPATCH_MESSAGE( eHTMLCommands_GoForward ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->GoForward( m_unBrowserHandle ); } @@ -686,15 +572,6 @@ void HTML::OnSizeChanged(int wide,int tall) { BaseClass::OnSizeChanged(wide,tall); UpdateSizeAndScrollBars(); - UpdateCachedHTMLValues(); -#ifdef WIN32 - // under windows we get stuck in the windows message loop pushing out WM_WINDOWPOSCHANGED without returning in the windproc loop - // so we need to manually pump the html dispatching of messages here - if ( surface() && surface()->AccessChromeHTMLController() ) - { - surface()->AccessChromeHTMLController()->RunFrame(); - } -#endif } @@ -703,9 +580,8 @@ void HTML::OnSizeChanged(int wide,int tall) //----------------------------------------------------------------------------- void HTML::RunJavascript( const char *pchScript ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_ExecuteJavaScript ); - cmd.Body().set_script( pchScript ); - DISPATCH_MESSAGE( eHTMLCommands_ExecuteJavaScript ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->ExecuteJavascript( m_unBrowserHandle, pchScript ); } @@ -714,21 +590,19 @@ void HTML::RunJavascript( const char *pchScript ) //----------------------------------------------------------------------------- // Purpose: helper to convert UI mouse codes to CEF ones //----------------------------------------------------------------------------- -int ConvertMouseCodeToCEFCode( MouseCode code ) +ISteamHTMLSurface::EHTMLMouseButton ConvertMouseCodeToCEFCode( MouseCode code ) { switch( code ) { + default: case MOUSE_LEFT: - return IInputEventHTML::eButtonLeft; + return ISteamHTMLSurface::eHTMLMouseButton_Left; break; case MOUSE_RIGHT: - return IInputEventHTML::eButtonRight; + return ISteamHTMLSurface::eHTMLMouseButton_Right; break; case MOUSE_MIDDLE: - return IInputEventHTML::eButtonMiddle; - break; - default: - return IInputEventHTML::eButtonLeft; + return ISteamHTMLSurface::eHTMLMouseButton_Middle; break; } } @@ -768,9 +642,8 @@ void HTML::OnMousePressed(MouseCode code) // ignore right clicks if context menu has been disabled if ( code != MOUSE_RIGHT ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_MouseDown ); - cmd.Body().set_mouse_button( ConvertMouseCodeToCEFCode( code ) ); - DISPATCH_MESSAGE( eHTMLCommands_MouseDown ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->MouseDown( m_unBrowserHandle, ConvertMouseCodeToCEFCode( code ) ); } if ( code == MOUSE_LEFT ) @@ -815,9 +688,8 @@ void HTML::OnMouseReleased(MouseCode code) m_sDragURL = NULL; } - CHTMLProtoBufMsg cmd( eHTMLCommands_MouseUp ); - cmd.Body().set_mouse_button( ConvertMouseCodeToCEFCode( code ) ); - DISPATCH_MESSAGE( eHTMLCommands_MouseUp ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->MouseUp( m_unBrowserHandle, ConvertMouseCodeToCEFCode( code ) ); } @@ -832,10 +704,8 @@ void HTML::OnCursorMoved(int x,int y) m_iMouseX = x; m_iMouseY = y; - CHTMLProtoBufMsg cmd( eHTMLCommands_MouseMove ); - cmd.Body().set_x( m_iMouseX ); - cmd.Body().set_y( m_iMouseY ); - DISPATCH_MESSAGE( eHTMLCommands_MouseMove ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->MouseMove( m_unBrowserHandle, m_iMouseX, m_iMouseY ); } else if ( !m_sDragURL.IsEmpty() ) { @@ -866,9 +736,34 @@ void HTML::OnCursorMoved(int x,int y) //----------------------------------------------------------------------------- void HTML::OnMouseDoublePressed(MouseCode code) { - CHTMLProtoBufMsg cmd( eHTMLCommands_MouseDblClick ); - cmd.Body().set_mouse_button( ConvertMouseCodeToCEFCode( code ) ); - DISPATCH_MESSAGE( eHTMLCommands_MouseDblClick ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->MouseDoubleClick( m_unBrowserHandle, ConvertMouseCodeToCEFCode( code ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: return the bitmask of any modifier keys that are currently down +//----------------------------------------------------------------------------- +int GetKeyModifiers() +{ + // Any time a key is pressed reset modifier list as well + int nModifierCodes = 0; + if (vgui::input()->IsKeyDown( KEY_LCONTROL ) || vgui::input()->IsKeyDown( KEY_RCONTROL )) + nModifierCodes |= ISteamHTMLSurface::eHTMLKeyModifier_CrtlDown; + + if (vgui::input()->IsKeyDown( KEY_LALT ) || vgui::input()->IsKeyDown( KEY_RALT )) + nModifierCodes |= ISteamHTMLSurface::eHTMLKeyModifier_AltDown; + + if (vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT )) + nModifierCodes |= ISteamHTMLSurface::eHTMLKeyModifier_ShiftDown; + +#ifdef OSX + // for now pipe through the cmd-key to be like the control key so we get copy/paste + if (vgui::input()->IsKeyDown( KEY_LWIN ) || vgui::input()->IsKeyDown( KEY_RWIN )) + nModifierCodes |= ISteamHTMLSurface::eHTMLKeyModifier_CrtlDown; +#endif + + return nModifierCodes; } @@ -877,9 +772,8 @@ void HTML::OnMouseDoublePressed(MouseCode code) //----------------------------------------------------------------------------- void HTML::OnKeyTyped(wchar_t unichar) { - CHTMLProtoBufMsg cmd( eHTMLCommands_KeyChar ); - cmd.Body().set_unichar( unichar ); - DISPATCH_MESSAGE( eHTMLCommands_KeyChar ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->KeyChar( m_unBrowserHandle, unichar, (ISteamHTMLSurface::EHTMLKeyModifiers)GetKeyModifiers() ); } @@ -950,32 +844,6 @@ bool HTML::FindDialogVisible() } -//----------------------------------------------------------------------------- -// Purpose: return the bitmask of any modifier keys that are currently down -//----------------------------------------------------------------------------- -int GetKeyModifiers() -{ - // Any time a key is pressed reset modifier list as well - int nModifierCodes = 0; - if( vgui::input()->IsKeyDown( KEY_LCONTROL ) || vgui::input()->IsKeyDown( KEY_RCONTROL ) ) - nModifierCodes |= IInputEventHTML::CrtlDown; - - if( vgui::input()->IsKeyDown( KEY_LALT ) || vgui::input()->IsKeyDown( KEY_RALT ) ) - nModifierCodes |= IInputEventHTML::AltDown; - - if( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) ) - nModifierCodes |= IInputEventHTML::ShiftDown; - -#ifdef OSX - // for now pipe through the cmd-key to be like the control key so we get copy/paste - if( vgui::input()->IsKeyDown( KEY_LWIN ) || vgui::input()->IsKeyDown( KEY_RWIN ) ) - nModifierCodes |= IInputEventHTML::CrtlDown; -#endif - - return nModifierCodes; -} - - //----------------------------------------------------------------------------- // Purpose: passes key presses to the browser //----------------------------------------------------------------------------- @@ -1038,10 +906,8 @@ void HTML::OnKeyCodeTyped(KeyCode code) } } - CHTMLProtoBufMsg cmd( eHTMLCommands_KeyDown ); - cmd.Body().set_keycode( KeyCode_VGUIToVirtualKey(code) ); - cmd.Body().set_modifiers( GetKeyModifiers() ); - DISPATCH_MESSAGE( eHTMLCommands_KeyDown ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->KeyDown( m_unBrowserHandle, KeyCode_VGUIToVirtualKey(code), (ISteamHTMLSurface::EHTMLKeyModifiers)GetKeyModifiers() ); } @@ -1050,10 +916,8 @@ void HTML::OnKeyCodeTyped(KeyCode code) //----------------------------------------------------------------------------- void HTML::OnKeyCodeReleased(KeyCode code) { - CHTMLProtoBufMsg cmd( eHTMLCommands_KeyUp ); - cmd.Body().set_keycode( KeyCode_VGUIToVirtualKey(code) ); - cmd.Body().set_modifiers( GetKeyModifiers() ); - DISPATCH_MESSAGE( eHTMLCommands_KeyUp ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->KeyUp( m_unBrowserHandle, KeyCode_VGUIToVirtualKey( code ), (ISteamHTMLSurface::EHTMLKeyModifiers)GetKeyModifiers() ); } @@ -1069,9 +933,8 @@ void HTML::OnMouseWheeled(int delta) _vbar->SetValue(val); } - CHTMLProtoBufMsg cmd( eHTMLCommands_MouseWheel ); - cmd.Body().set_delta( delta ); - DISPATCH_MESSAGE( eHTMLCommands_MouseWheel ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->MouseWheel( m_unBrowserHandle, delta* 100.0/3.0 ); } @@ -1091,6 +954,9 @@ void HTML::AddCustomURLHandler(const char *customProtocolName, vgui::Panel *targ //----------------------------------------------------------------------------- void HTML::BrowserResize() { + if (m_unBrowserHandle == INVALID_HTTMLBROWSER) + return; + int w,h; GetSize( w, h ); int right = 0, bottom = 0; @@ -1104,6 +970,7 @@ void HTML::BrowserResize() } */ + if ( m_iWideLastHTMLSize != ( w - m_iScrollBorderX - right ) || m_iTalLastHTMLSize != ( h - m_iScrollBorderY - bottom ) ) { m_iWideLastHTMLSize = w - m_iScrollBorderX - right; @@ -1115,10 +982,8 @@ void HTML::BrowserResize() } { - CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserSize ); - cmd.Body().set_width( m_iWideLastHTMLSize ); - cmd.Body().set_height( m_iTalLastHTMLSize ); - DISPATCH_MESSAGE( eHTMLCommands_BrowserSize ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->SetSize( m_unBrowserHandle, m_iWideLastHTMLSize, m_iTalLastHTMLSize ); } @@ -1127,16 +992,10 @@ void HTML::BrowserResize() int scrollV = _vbar->GetValue(); int scrollH = _hbar->GetValue(); - { - CHTMLProtoBufMsg cmd( eHTMLCommands_SetHorizontalScroll ); - cmd.Body().set_scroll( scrollH ); - DISPATCH_MESSAGE( eHTMLCommands_SetHorizontalScroll ); - } - { - CHTMLProtoBufMsg cmd( eHTMLCommands_SetVerticalScroll ); - cmd.Body().set_scroll( scrollV ); - DISPATCH_MESSAGE( eHTMLCommands_SetVerticalScroll ); - } + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->SetHorizontalScroll( m_unBrowserHandle, scrollH ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->SetVerticalScroll( m_unBrowserHandle, scrollV ); } } @@ -1149,18 +1008,16 @@ void HTML::OnSliderMoved() { if(_hbar->IsVisible()) { - int scrollX =_hbar->GetValue(); - CHTMLProtoBufMsg cmd( eHTMLCommands_SetHorizontalScroll ); - cmd.Body().set_scroll( scrollX ); - DISPATCH_MESSAGE( eHTMLCommands_SetHorizontalScroll ); + int scrollX = _hbar->GetValue(); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->SetHorizontalScroll( m_unBrowserHandle, scrollX ); } if(_vbar->IsVisible()) { int scrollY=_vbar->GetValue(); - CHTMLProtoBufMsg cmd( eHTMLCommands_SetVerticalScroll ); - cmd.Body().set_scroll( scrollY ); - DISPATCH_MESSAGE( eHTMLCommands_SetVerticalScroll ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->SetVerticalScroll( m_unBrowserHandle, scrollY ); } // post a message that the slider has moved @@ -1241,10 +1098,8 @@ void HTML::PostChildPaint() //----------------------------------------------------------------------------- void HTML::AddHeader( const char *pchHeader, const char *pchValue ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_AddHeader ); - cmd.Body().set_key( pchHeader ); - cmd.Body().set_value( pchValue ); - DISPATCH_MESSAGE( eHTMLCommands_AddHeader ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->AddHeader( m_unBrowserHandle, pchHeader, pchValue ); } @@ -1253,10 +1108,10 @@ void HTML::AddHeader( const char *pchHeader, const char *pchValue ) //----------------------------------------------------------------------------- void HTML::OnSetFocus() { + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->SetKeyFocus( m_unBrowserHandle, true ); + BaseClass::OnSetFocus(); - CHTMLProtoBufMsg cmd( eHTMLCommands_SetFocus ); - cmd.Body().set_focus( true ); - DISPATCH_MESSAGE( eHTMLCommands_SetFocus ); } @@ -1275,9 +1130,8 @@ void HTML::OnKillFocus() if ( m_pComboBoxHost->HasFocus() ) return; - CHTMLProtoBufMsg cmd( eHTMLCommands_SetFocus ); - cmd.Body().set_focus( false ); - DISPATCH_MESSAGE( eHTMLCommands_SetFocus ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->SetKeyFocus( m_unBrowserHandle, false ); } @@ -1304,18 +1158,18 @@ void HTML::OnCommand( const char *pchCommand ) } else if ( !Q_stricmp( pchCommand, "viewsource" ) ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_ViewSource ); - DISPATCH_MESSAGE( eHTMLCommands_ViewSource ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->ViewSource( m_unBrowserHandle ); } else if ( !Q_stricmp( pchCommand, "copy" ) ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_Copy ); - DISPATCH_MESSAGE( eHTMLCommands_Copy ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->CopyToClipboard( m_unBrowserHandle ); } else if ( !Q_stricmp( pchCommand, "paste" ) ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_Paste ); - DISPATCH_MESSAGE( eHTMLCommands_Paste ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->PasteFromClipboard( m_unBrowserHandle ); } else if ( !Q_stricmp( pchCommand, "copyurl" ) ) { @@ -1342,9 +1196,10 @@ void HTML::OnCommand( const char *pchCommand ) //----------------------------------------------------------------------------- void HTML::OnFileSelected( const char *pchSelectedFile ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_FileLoadDialogResponse ); - cmd.Body().add_files( pchSelectedFile ); - DISPATCH_MESSAGE( eHTMLCommands_FileLoadDialogResponse ); + const char *ppchSelectedFiles[] = { pchSelectedFile, NULL }; + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->FileLoadDialogResponse( m_unBrowserHandle , ppchSelectedFiles ); + m_hFileOpenDialog->Close(); } @@ -1353,8 +1208,9 @@ void HTML::OnFileSelected( const char *pchSelectedFile ) //----------------------------------------------------------------------------- void HTML::OnFileSelectionCancelled() { - CHTMLProtoBufMsg cmd( eHTMLCommands_FileLoadDialogResponse ); - DISPATCH_MESSAGE( eHTMLCommands_FileLoadDialogResponse ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->FileLoadDialogResponse( m_unBrowserHandle, NULL ); + m_hFileOpenDialog->Close(); } @@ -1369,10 +1225,8 @@ void HTML::Find( const char *pchSubStr ) m_sLastSearchString = pchSubStr; - CHTMLProtoBufMsg cmd( eHTMLCommands_Find ); - cmd.Body().set_find( pchSubStr ); - cmd.Body().set_infind( m_bInFind ); - DISPATCH_MESSAGE( eHTMLCommands_Find ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->Find( m_unBrowserHandle, pchSubStr, m_bInFind, false ); } @@ -1381,11 +1235,8 @@ void HTML::Find( const char *pchSubStr ) //----------------------------------------------------------------------------- void HTML::FindPrevious() { - CHTMLProtoBufMsg cmd( eHTMLCommands_Find ); - cmd.Body().set_find( m_sLastSearchString ); - cmd.Body().set_infind( m_bInFind ); - cmd.Body().set_reverse( true ); - DISPATCH_MESSAGE( eHTMLCommands_Find ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->Find( m_unBrowserHandle, m_sLastSearchString, m_bInFind, true ); } @@ -1403,9 +1254,8 @@ void HTML::FindNext() //----------------------------------------------------------------------------- void HTML::StopFind( ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_StopFind ); - DISPATCH_MESSAGE( eHTMLCommands_StopFind ); - + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->StopFind( m_unBrowserHandle ); m_bInFind = false; } @@ -1456,11 +1306,7 @@ void HTMLComboBoxHost::OnCursorMoved(int x,int y) // Only do this when we are over the current panel if ( vgui::input()->GetMouseOver() == GetVPanel() ) { - int m_iBrowser = m_pParent->BrowserGetIndex(); - CHTMLProtoBufMsg cmd( eHTMLCommands_MouseMove ); - cmd.Body().set_x( x ); - cmd.Body().set_y( y ); - DISPATCH_MESSAGE( eHTMLCommands_MouseMove ); + m_pParent->OnHTMLMouseMoved( x, y ); } } @@ -1548,92 +1394,11 @@ void HTML::CHTMLFindBar::OnCommand( const char *pchCmd ) } -//----------------------------------------------------------------------------- -// Purpose: TEMPORARY WORKAROUND FOR VS2005 INTERFACE ISSUES -//----------------------------------------------------------------------------- -#define TMP_HTML_MSG_FUNC( eHTMLCommand, bodyType, commandFunc ) \ - case eHTMLCommand: \ - { \ - CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ - if ( cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ - commandFunc( &cmd.BodyConst() ); \ - } \ - break; \ - -void HTML::_DeserializeAndDispatch( HTMLCommandBuffer_t *pCmd ) -{ - switch ( pCmd->m_eCmd ) - { - default: - break; - TMP_HTML_MSG_FUNC( eHTMLCommands_BrowserReady, CMsgBrowserReady, BrowserReady ); - TMP_HTML_MSG_FUNC( eHTMLCommands_NeedsPaint, CMsgNeedsPaint, BrowserNeedsPaint ); - TMP_HTML_MSG_FUNC( eHTMLCommands_StartRequest, CMsgStartRequest, BrowserStartRequest ); - TMP_HTML_MSG_FUNC( eHTMLCommands_URLChanged, CMsgURLChanged, BrowserURLChanged ); - TMP_HTML_MSG_FUNC( eHTMLCommands_FinishedRequest, CMsgFinishedRequest, BrowserFinishedRequest ); - TMP_HTML_MSG_FUNC( eHTMLCommands_ShowPopup, CMsgShowPopup, BrowserShowPopup ); - TMP_HTML_MSG_FUNC( eHTMLCommands_HidePopup, CMsgHidePopup, BrowserHidePopup ); - TMP_HTML_MSG_FUNC( eHTMLCommands_OpenNewTab, CMsgOpenNewTab, BrowserOpenNewTab ); - TMP_HTML_MSG_FUNC( eHTMLCommands_PopupHTMLWindow, CMsgPopupHTMLWindow, BrowserPopupHTMLWindow ); - TMP_HTML_MSG_FUNC( eHTMLCommands_SetHTMLTitle, CMsgSetHTMLTitle, BrowserSetHTMLTitle ); - TMP_HTML_MSG_FUNC( eHTMLCommands_LoadingResource, CMsgLoadingResource, BrowserLoadingResource ); - TMP_HTML_MSG_FUNC( eHTMLCommands_StatusText, CMsgStatusText, BrowserStatusText ); - TMP_HTML_MSG_FUNC( eHTMLCommands_SetCursor, CMsgSetCursor, BrowserSetCursor ); - TMP_HTML_MSG_FUNC( eHTMLCommands_FileLoadDialog, CMsgFileLoadDialog, BrowserFileLoadDialog ); - TMP_HTML_MSG_FUNC( eHTMLCommands_ShowToolTip, CMsgShowToolTip, BrowserShowToolTip ); - TMP_HTML_MSG_FUNC( eHTMLCommands_UpdateToolTip, CMsgUpdateToolTip, BrowserUpdateToolTip ); - TMP_HTML_MSG_FUNC( eHTMLCommands_HideToolTip, CMsgHideToolTip, BrowserHideToolTip ); - TMP_HTML_MSG_FUNC( eHTMLCommands_SearchResults, CMsgSearchResults, BrowserSearchResults ); - TMP_HTML_MSG_FUNC( eHTMLCommands_Close, CMsgClose, BrowserClose ); - TMP_HTML_MSG_FUNC( eHTMLCommands_GetZoomResponse, CMsgGetZoomResponse, BrowserGetZoomResponse ); - TMP_HTML_MSG_FUNC( eHTMLCommands_HorizontalScrollBarSizeResponse, CMsgHorizontalScrollBarSizeResponse, BrowserHorizontalScrollBarSizeResponse ); - TMP_HTML_MSG_FUNC( eHTMLCommands_VerticalScrollBarSizeResponse, CMsgVerticalScrollBarSizeResponse, BrowserVerticalScrollBarSizeResponse ); - TMP_HTML_MSG_FUNC( eHTMLCommands_LinkAtPositionResponse, CMsgLinkAtPositionResponse, BrowserLinkAtPositionResponse ); - TMP_HTML_MSG_FUNC( eHTMLCommands_ZoomToElementAtPositionResponse, CMsgZoomToElementAtPositionResponse, BrowserZoomToElementAtPositionResponse ); - TMP_HTML_MSG_FUNC( eHTMLCommands_JSAlert, CMsgJSAlert, BrowserJSAlert ); - TMP_HTML_MSG_FUNC( eHTMLCommands_JSConfirm, CMsgJSConfirm, BrowserJSConfirm ); - TMP_HTML_MSG_FUNC( eHTMLCommands_OpenSteamURL, CMsgOpenSteamURL, BrowserOpenSteamURL ); - TMP_HTML_MSG_FUNC( eHTMLCommands_CanGoBackandForward, CMsgCanGoBackAndForward, BrowserCanGoBackandForward ); - TMP_HTML_MSG_FUNC( eHTMLCommands_SizePopup, CMsgSizePopup, BrowserSizePopup ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: browser has been constructed on the cef thread, lets use it -//----------------------------------------------------------------------------- -void HTML::BrowserReady( const CMsgBrowserReady *pCmd ) -{ - const char *pchTitle = g_pVGuiLocalize->FindAsUTF8( "#cef_error_title" ); - const char *pchHeader = g_pVGuiLocalize->FindAsUTF8( "#cef_error_header" ); - const char *pchDetailCacheMiss = g_pVGuiLocalize->FindAsUTF8( "#cef_cachemiss" ); - const char *pchDetailBadUURL = g_pVGuiLocalize->FindAsUTF8( "#cef_badurl" ); - const char *pchDetailConnectionProblem = g_pVGuiLocalize->FindAsUTF8( "#cef_connectionproblem" ); - const char *pchDetailProxyProblem = g_pVGuiLocalize->FindAsUTF8( "#cef_proxyconnectionproblem" ); - const char *pchDetailUnknown = g_pVGuiLocalize->FindAsUTF8( "#cef_unknown" ); - - // tell it utf8 loc strings to use - CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserErrorStrings ); - cmd.Body().set_title( pchTitle ); - cmd.Body().set_header( pchHeader ); - cmd.Body().set_cache_miss( pchDetailCacheMiss ); - cmd.Body().set_bad_url( pchDetailBadUURL ); - cmd.Body().set_connection_problem( pchDetailConnectionProblem ); - cmd.Body().set_proxy_problem( pchDetailProxyProblem ); - cmd.Body().set_unknown( pchDetailUnknown ); - DISPATCH_MESSAGE( eHTMLCommands_BrowserErrorStrings ); - - if ( !m_sPendingURLLoad.IsEmpty() ) - { - PostURL( m_sPendingURLLoad, m_sPendingPostData, false ); - m_sPendingURLLoad.Clear(); - } -} - //----------------------------------------------------------------------------- // Purpose: we have a new texture to update //----------------------------------------------------------------------------- -void HTML::BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) +void HTML::BrowserNeedsPaint( HTML_NeedsPaint_t *pCallback ) { int tw = 0, tt = 0; if ( m_iHTMLTextureID != 0 ) @@ -1642,18 +1407,14 @@ void HTML::BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) tt = m_allocedTextureHeight; } - if ( m_iHTMLTextureID != 0 && ( ( _vbar->IsVisible() && pCmd->scrolly() > 0 && abs( (int)pCmd->scrolly() - m_scrollVertical.m_nScroll) > 5 ) || ( _hbar->IsVisible() && pCmd->scrollx() > 0 && abs( (int)pCmd->scrollx() - m_scrollHorizontal.m_nScroll ) > 5 ) ) ) + if ( m_iHTMLTextureID != 0 && ( ( _vbar->IsVisible() && pCallback->unScrollY > 0 && abs( (int)pCallback->unScrollY - m_scrollVertical.m_nScroll) > 5 ) || ( _hbar->IsVisible() && pCallback->unScrollX > 0 && abs( (int)pCallback->unScrollX - m_scrollHorizontal.m_nScroll ) > 5 ) ) ) { - // this isn't an update from a scroll position we expect, ignore it and ask for a refresh of our update pos2 - CHTMLProtoBufMsg cmd( eHTMLCommands_NeedsPaintResponse ); - cmd.Body().set_textureid( pCmd->textureid() ); - DISPATCH_MESSAGE( eHTMLCommands_NeedsPaintResponse ); m_bNeedsFullTextureUpload = true; return; } // update the vgui texture - if ( m_bNeedsFullTextureUpload || m_iHTMLTextureID == 0 || tw != (int)pCmd->wide() || tt != (int)pCmd->tall() ) + if ( m_bNeedsFullTextureUpload || m_iHTMLTextureID == 0 || tw != (int)pCallback->unWide || tt != (int)pCallback->unTall ) { m_bNeedsFullTextureUpload = false; if ( m_iHTMLTextureID != 0 ) @@ -1662,22 +1423,33 @@ void HTML::BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) // if the dimensions changed we also need to re-create the texture ID to support the overlay properly (it won't resize a texture on the fly, this is the only control that needs // to so lets have a tiny bit more code here to support that) m_iHTMLTextureID = surface()->CreateNewTextureID( true ); - surface()->DrawSetTextureRGBAEx( m_iHTMLTextureID, (const unsigned char *)pCmd->rgba(), pCmd->wide(), pCmd->tall(), IMAGE_FORMAT_BGRA8888 );// BR FIXME - this call seems to shift by some number of pixels? - m_allocedTextureWidth = pCmd->wide(); - m_allocedTextureHeight = pCmd->tall(); + surface()->DrawSetTextureRGBAEx( m_iHTMLTextureID, (const unsigned char *)pCallback->pBGRA, pCallback->unWide, pCallback->unTall, IMAGE_FORMAT_BGRA8888 );// BR FIXME - this call seems to shift by some number of pixels? + m_allocedTextureWidth = pCallback->unWide; + m_allocedTextureHeight = pCallback->unTall; } - else if ( (int)pCmd->updatewide() > 0 && (int)pCmd->updatetall() > 0 ) + else if ( (int)pCallback->unUpdateWide > 0 && (int)pCallback->unUpdateTall > 0 ) { // same size texture, just bits changing in it, lets twiddle - surface()->DrawUpdateRegionTextureRGBA( m_iHTMLTextureID, pCmd->updatex(), pCmd->updatey(), (const unsigned char *)pCmd->rgba(), pCmd->updatewide(), pCmd->updatetall(), IMAGE_FORMAT_BGRA8888 ); + surface()->DrawUpdateRegionTextureRGBA( m_iHTMLTextureID, pCallback->unUpdateX, pCallback->unUpdateY, (const unsigned char *)pCallback->pBGRA, pCallback->unUpdateWide, pCallback->unUpdateTall, IMAGE_FORMAT_BGRA8888 ); } else { - surface()->DrawSetTextureRGBAEx( m_iHTMLTextureID, (const unsigned char *)pCmd->rgba(), pCmd->wide(), pCmd->tall(), IMAGE_FORMAT_BGRA8888 ); + surface()->DrawSetTextureRGBAEx( m_iHTMLTextureID, (const unsigned char *)pCallback->pBGRA,pCallback->unWide, pCallback->unTall, IMAGE_FORMAT_BGRA8888 ); } + // need a paint next time + Repaint(); +} + + +//----------------------------------------------------------------------------- +// Purpose: we have a new texture to update +//----------------------------------------------------------------------------- +void HTML::BrowserComboNeedsPaint( HTML_ComboNeedsPaint_t *pCallback ) +{ if ( m_pComboBoxHost->IsVisible() ) { + int tw = 0, tt = 0; // update the combo box texture also if ( m_iComboBoxTextureID != 0 ) { @@ -1685,7 +1457,7 @@ void HTML::BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) tt = m_allocedComboBoxHeight; } - if ( m_iComboBoxTextureID == 0 || tw != (int)pCmd->combobox_wide() || tt != (int)pCmd->combobox_tall() ) + if ( m_iComboBoxTextureID == 0 || tw != (int)pCallback->unWide || tt != (int)pCallback->unTall ) { if ( m_iComboBoxTextureID != 0 ) surface()->DeleteTextureByID( m_iComboBoxTextureID ); @@ -1693,23 +1465,16 @@ void HTML::BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) // if the dimensions changed we also need to re-create the texture ID to support the overlay properly (it won't resize a texture on the fly, this is the only control that needs // to so lets have a tiny bit more code here to support that) m_iComboBoxTextureID = surface()->CreateNewTextureID( true ); - surface()->DrawSetTextureRGBAEx( m_iComboBoxTextureID, (const unsigned char *)pCmd->combobox_rgba(), pCmd->combobox_wide(), pCmd->combobox_tall(), IMAGE_FORMAT_BGRA8888 ); - m_allocedComboBoxWidth = (int)pCmd->combobox_wide(); - m_allocedComboBoxHeight = (int)pCmd->combobox_tall(); + surface()->DrawSetTextureRGBAEx( m_iComboBoxTextureID, (const unsigned char *)pCallback->pBGRA, pCallback->unWide, pCallback->unTall, IMAGE_FORMAT_BGRA8888 ); + m_allocedComboBoxWidth = (int)pCallback->unWide; + m_allocedComboBoxHeight = (int)pCallback->unTall; } else { // same size texture, just bits changing in it, lets twiddle - surface()->DrawUpdateRegionTextureRGBA( m_iComboBoxTextureID, 0, 0, (const unsigned char *)pCmd->combobox_rgba(), pCmd->combobox_wide(), pCmd->combobox_tall(), IMAGE_FORMAT_BGRA8888 ); + surface()->DrawUpdateRegionTextureRGBA( m_iComboBoxTextureID, 0, 0, (const unsigned char *)pCallback->pBGRA, pCallback->unWide, pCallback->unTall, IMAGE_FORMAT_BGRA8888 ); } } - - // need a paint next time - Repaint(); - - CHTMLProtoBufMsg cmd( eHTMLCommands_NeedsPaintResponse ); - cmd.Body().set_textureid( pCmd->textureid() ); - DISPATCH_MESSAGE( eHTMLCommands_NeedsPaintResponse ); } @@ -1771,70 +1536,54 @@ bool HTML::OnStartRequest( const char *url, const char *target, const char *pchP //----------------------------------------------------------------------------- // Purpose: callback from cef thread, load a url please //----------------------------------------------------------------------------- -void HTML::BrowserStartRequest( const CMsgStartRequest *pCmd ) +void HTML::BrowserStartRequest( HTML_StartRequest_t *pCmd ) { - bool bRes = OnStartRequest( pCmd->url().c_str(), pCmd->target().c_str(), pCmd->postdata().c_str(), pCmd->bisredirect() ); + bool bRes = OnStartRequest( pCmd->pchURL, pCmd->pchTarget, pCmd->pchPostData, pCmd->bIsRedirect ); - CHTMLProtoBufMsg cmd( eHTMLCommands_StartRequestResponse ); - cmd.Body().set_ballow( bRes ); - DISPATCH_MESSAGE( eHTMLCommands_StartRequestResponse ); - - UpdateCachedHTMLValues(); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->AllowStartRequest( m_unBrowserHandle, bRes ); } //----------------------------------------------------------------------------- // Purpose: browser went to a new url //----------------------------------------------------------------------------- -void HTML::BrowserURLChanged( const CMsgURLChanged *pCmd ) +void HTML::BrowserURLChanged( HTML_URLChanged_t *pCmd ) { - m_sCurrentURL = pCmd->url().c_str(); + m_sCurrentURL = pCmd->pchURL; KeyValues *pMessage = new KeyValues( "OnURLChanged" ); - pMessage->SetString( "url", pCmd->url().c_str() ); - pMessage->SetString( "postdata", pCmd->postdata().c_str() ); - pMessage->SetInt( "isredirect", pCmd->bisredirect() ? 1 : 0 ); + pMessage->SetString( "url", pCmd->pchURL ); + pMessage->SetString( "postdata", pCmd->pchPostData ); + pMessage->SetInt( "isredirect", pCmd->bIsRedirect ? 1 : 0 ); PostActionSignal( pMessage ); - OnURLChanged( m_sCurrentURL, pCmd->postdata().c_str(), pCmd->bisredirect() ); + OnURLChanged( m_sCurrentURL, pCmd->pchPostData, pCmd->bIsRedirect ); } //----------------------------------------------------------------------------- // Purpose: finished loading this page //----------------------------------------------------------------------------- -void HTML::BrowserFinishedRequest( const CMsgFinishedRequest *pCmd ) +void HTML::BrowserFinishedRequest( HTML_FinishedRequest_t *pCmd ) { - PostActionSignal( new KeyValues( "OnFinishRequest", "url", pCmd->url().c_str() ) ); - if ( pCmd->pagetitle().length() ) - PostActionSignal( new KeyValues( "PageTitleChange", "title", pCmd->pagetitle().c_str() ) ); - KeyValues *pKVSecure = new KeyValues( "SecurityStatus" ); - pKVSecure->SetString( "url", pCmd->url().c_str() ); - pKVSecure->SetInt( "secure", pCmd->security_info().bissecure() ); - pKVSecure->SetInt( "certerror", pCmd->security_info().bhascerterror() ); - pKVSecure->SetInt( "isevcert", pCmd->security_info().bisevcert() ); - pKVSecure->SetString( "certname", pCmd->security_info().certname().c_str() ); - PostActionSignal( pKVSecure ); + PostActionSignal( new KeyValues( "OnFinishRequest", "url", pCmd->pchURL ) ); + if ( pCmd->pchPageTitle && pCmd->pchPageTitle[0] ) + PostActionSignal( new KeyValues( "PageTitleChange", "title", pCmd->pchPageTitle ) ); CUtlMap < CUtlString, CUtlString > mapHeaders; SetDefLessFunc( mapHeaders ); - for ( int i = 0; i < pCmd->headers_size(); i++ ) - { - const CHTMLHeader &header = pCmd->headers(i); - mapHeaders.Insert( header.key().c_str(), header.value().c_str() ); - } + // headers are no longer reported on loads - OnFinishRequest( pCmd->url().c_str(), pCmd->pagetitle().c_str(), mapHeaders ); - - UpdateCachedHTMLValues(); + OnFinishRequest( pCmd->pchURL, pCmd->pchPageTitle, mapHeaders ); } //----------------------------------------------------------------------------- // Purpose: show a popup dialog //----------------------------------------------------------------------------- -void HTML::BrowserShowPopup( const CMsgShowPopup *pCmd ) +void HTML::BrowserShowPopup( HTML_ShowPopup_t *pCmd ) { m_pComboBoxHost->SetVisible( true ); } @@ -1852,7 +1601,7 @@ void HTML::HidePopup() //----------------------------------------------------------------------------- // Purpose: browser wants us to hide a popup //----------------------------------------------------------------------------- -void HTML::BrowserHidePopup( const CMsgHidePopup *pCmd ) +void HTML::BrowserHidePopup( HTML_HidePopup_t *pCmd ) { HidePopup(); } @@ -1861,18 +1610,18 @@ void HTML::BrowserHidePopup( const CMsgHidePopup *pCmd ) //----------------------------------------------------------------------------- // Purpose: browser wants us to position a popup //----------------------------------------------------------------------------- -void HTML::BrowserSizePopup( const CMsgSizePopup *pCmd ) +void HTML::BrowserSizePopup( HTML_SizePopup_t *pCmd ) { int nAbsX, nAbsY; ipanel()->GetAbsPos( GetVPanel(), nAbsX, nAbsY ); - m_pComboBoxHost->SetBounds( pCmd->x() + 1 + nAbsX, pCmd->y() + nAbsY, pCmd->wide(), pCmd->tall() ); + m_pComboBoxHost->SetBounds( pCmd->unX + 1 + nAbsX, pCmd->unY+ nAbsY, pCmd->unWide, pCmd->unTall ); } //----------------------------------------------------------------------------- // Purpose: browser wants to open a new tab //----------------------------------------------------------------------------- -void HTML::BrowserOpenNewTab( const CMsgOpenNewTab *pCmd ) +void HTML::BrowserOpenNewTab( HTML_OpenLinkInNewTab_t *pCmd ) { (pCmd); // Not suppored by default, if a child class overrides us and knows how to handle tabs, then it can do this. @@ -1882,20 +1631,20 @@ void HTML::BrowserOpenNewTab( const CMsgOpenNewTab *pCmd ) //----------------------------------------------------------------------------- // Purpose: display a new html window //----------------------------------------------------------------------------- -void HTML::BrowserPopupHTMLWindow( const CMsgPopupHTMLWindow *pCmd ) +void HTML::BrowserPopupHTMLWindow( HTML_NewWindow_t *pCmd ) { - HTMLPopup *p = new HTMLPopup( this, pCmd->url().c_str(), "" ); - int wide = pCmd->wide(); - int tall = pCmd->tall(); + HTMLPopup *p = new HTMLPopup( this, pCmd->pchURL, "" ); + int wide = pCmd->unWide; + int tall = pCmd->unTall; if ( wide == 0 || tall == 0 ) { wide = MAX( 640, GetWide() ); tall = MAX( 480, GetTall() ); } - p->SetBounds( pCmd->x(), pCmd->y(), wide, tall ); + p->SetBounds( pCmd->unX, pCmd->unY, wide, tall ); p->SetDeleteSelfOnClose( true ); - if ( pCmd->x() == 0 || pCmd->y() == 0 ) + if ( pCmd->unX == 0 || pCmd->unY == 0 ) p->MoveToCenterOfScreen(); p->Activate(); @@ -1905,51 +1654,162 @@ void HTML::BrowserPopupHTMLWindow( const CMsgPopupHTMLWindow *pCmd ) //----------------------------------------------------------------------------- // Purpose: browser telling us the page title //----------------------------------------------------------------------------- -void HTML::BrowserSetHTMLTitle( const CMsgSetHTMLTitle *pCmd ) +void HTML::BrowserSetHTMLTitle( HTML_ChangedTitle_t *pCmd ) { - PostMessage( GetParent(), new KeyValues( "OnSetHTMLTitle", "title", pCmd->title().c_str() ) ); - OnSetHTMLTitle( pCmd->title().c_str() ); -} - - -//----------------------------------------------------------------------------- -// Purpose: still loading stuff for this page -//----------------------------------------------------------------------------- -void HTML::BrowserLoadingResource( const CMsgLoadingResource *pCmd ) -{ - UpdateCachedHTMLValues(); + PostMessage( GetParent(), new KeyValues( "OnSetHTMLTitle", "title", pCmd->pchTitle ) ); + OnSetHTMLTitle( pCmd->pchTitle ); } //----------------------------------------------------------------------------- // Purpose: status bar details //----------------------------------------------------------------------------- -void HTML::BrowserStatusText( const CMsgStatusText *pCmd ) +void HTML::BrowserStatusText( HTML_StatusText_t *pCmd ) { - PostActionSignal( new KeyValues( "OnSetStatusText", "status", pCmd->text().c_str() ) ); + PostActionSignal( new KeyValues( "OnSetStatusText", "status", pCmd->pchMsg ) ); } //----------------------------------------------------------------------------- // Purpose: browser telling us to use this cursor //----------------------------------------------------------------------------- -void HTML::BrowserSetCursor( const CMsgSetCursor *pCmd ) +void HTML::BrowserSetCursor( HTML_SetCursor_t *pCmd ) { - // Mouse cursor value in CMsgSetCursor is set to one of EMouseCursor, - // by CChromePainter::OnSetCursor in html_chrome.cpp - // Code below relies on start of EMouseCursor being exactly same as vgui::CursorCode - - vgui::CursorCode cursor; - uint32 msgCursor = pCmd->cursor(); + vgui::CursorCode cursor = dc_last; - if ( msgCursor >= (uint32)(dc_last) ) + switch ( pCmd->eMouseCursor ) + { + case ISteamHTMLSurface::dc_user: + cursor = dc_user; + break; + case ISteamHTMLSurface::dc_none: + cursor = dc_none; + break; + default: + case ISteamHTMLSurface::dc_arrow: + cursor = dc_arrow; + break; + case ISteamHTMLSurface::dc_ibeam: + cursor = dc_ibeam; + break; + case ISteamHTMLSurface::dc_hourglass: + cursor = dc_hourglass; + break; + case ISteamHTMLSurface::dc_waitarrow: + cursor = dc_waitarrow; + break; + case ISteamHTMLSurface::dc_crosshair: + cursor = dc_crosshair; + break; + case ISteamHTMLSurface::dc_up: + cursor = dc_up; + break; + /*case ISteamHTMLSurface::dc_sizenw: + cursor = dc_sizenw; + break; + case ISteamHTMLSurface::dc_sizese: + cursor = dc_sizese; + break; + case ISteamHTMLSurface::dc_sizene: + cursor = dc_sizene; + break; + case ISteamHTMLSurface::dc_sizesw: + cursor = dc_sizesw; + break; + case ISteamHTMLSurface::dc_sizew: + cursor = dc_sizew; + break; + case ISteamHTMLSurface::dc_sizee: + cursor = dc_sizee; + break; + case ISteamHTMLSurface::dc_sizen: + cursor = dc_sizen; + break; + case ISteamHTMLSurface::dc_sizes: + cursor = dc_sizes; + break;*/ + case ISteamHTMLSurface::dc_sizewe: + cursor = dc_sizewe; + break; + case ISteamHTMLSurface::dc_sizens: + cursor = dc_sizens; + break; + case ISteamHTMLSurface::dc_sizeall: + cursor = dc_sizeall; + break; + case ISteamHTMLSurface::dc_no: + cursor = dc_no; + break; + case ISteamHTMLSurface::dc_hand: + cursor = dc_hand; + break; + case ISteamHTMLSurface::dc_blank: + cursor = dc_blank; + break; +/* case ISteamHTMLSurface::dc_middle_pan: + cursor = dc_middle_pan; + break; + case ISteamHTMLSurface::dc_north_pan: + cursor = dc_north_pan; + break; + case ISteamHTMLSurface::dc_north_east_pan: + cursor = dc_north_east_pan; + break; + case ISteamHTMLSurface::dc_east_pan: + cursor = dc_east_pan; + break; + case ISteamHTMLSurface::dc_south_east_pan: + cursor = dc_south_east_pan; + break; + case ISteamHTMLSurface::dc_south_pan: + cursor = dc_south_pan; + break; + case ISteamHTMLSurface::dc_south_west_pan: + cursor = dc_south_west_pan; + break; + case ISteamHTMLSurface::dc_west_pan: + cursor = dc_west_pan; + break; + case ISteamHTMLSurface::dc_north_west_pan: + cursor = dc_north_west_pan; + break; + case ISteamHTMLSurface::dc_alias: + cursor = dc_alias; + break; + case ISteamHTMLSurface::dc_cell: + cursor = dc_cell; + break; + case ISteamHTMLSurface::dc_colresize: + cursor = dc_colresize; + break; + case ISteamHTMLSurface::dc_copycur: + cursor = dc_copycur; + break; + case ISteamHTMLSurface::dc_verticaltext: + cursor = dc_verticaltext; + break; + case ISteamHTMLSurface::dc_rowresize: + cursor = dc_rowresize; + break; + case ISteamHTMLSurface::dc_zoomin: + cursor = dc_zoomin; + break; + case ISteamHTMLSurface::dc_zoomout: + cursor = dc_zoomout; + break; + case ISteamHTMLSurface::dc_custom: + cursor = dc_custom; + break; + case ISteamHTMLSurface::dc_help: + cursor = dc_help; + break;*/ + + } + + if ( cursor >= dc_last ) { cursor = dc_arrow; } - else - { - cursor = (CursorCode)msgCursor; - } SetCursor( cursor ); } @@ -1958,40 +1818,28 @@ void HTML::BrowserSetCursor( const CMsgSetCursor *pCmd ) //----------------------------------------------------------------------------- // Purpose: browser telling to show the file loading dialog //----------------------------------------------------------------------------- -void HTML::BrowserFileLoadDialog( const CMsgFileLoadDialog *pCmd ) +void HTML::BrowserFileLoadDialog( HTML_FileOpenDialog_t *pCmd ) { - /* - // try and use the OS-specific file dialog first - char rgchFileName[MAX_UNICODE_PATH_IN_UTF8]; - if ( surface()->OpenOSFileOpenDialog( pCmd->title().c_str(), pCmd->initialfile().c_str(), NULL, rgchFileName, sizeof(rgchFileName) ) ) + // couldn't access an OS-specific dialog, use the internal one + if ( m_hFileOpenDialog.Get() ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_FileLoadDialogResponse ); - cmd.Body().add_files( rgchFileName ); - DISPATCH_MESSAGE( eHTMLCommands_FileLoadDialogResponse ); - } - else*/ - { - // couldn't access an OS-specific dialog, use the internal one - if ( m_hFileOpenDialog.Get() ) - { - delete m_hFileOpenDialog.Get(); - m_hFileOpenDialog = NULL; - } - m_hFileOpenDialog = new FileOpenDialog( this, pCmd->title().c_str(), true ); - m_hFileOpenDialog->SetStartDirectory( pCmd->initialfile().c_str() ); - m_hFileOpenDialog->AddActionSignalTarget( this ); - m_hFileOpenDialog->SetAutoDelete( true ); - m_hFileOpenDialog->DoModal(false); + delete m_hFileOpenDialog.Get(); + m_hFileOpenDialog = NULL; } + m_hFileOpenDialog = new FileOpenDialog( this, pCmd->pchTitle, true ); + m_hFileOpenDialog->SetStartDirectory( pCmd->pchInitialFile ); + m_hFileOpenDialog->AddActionSignalTarget( this ); + m_hFileOpenDialog->SetAutoDelete( true ); + m_hFileOpenDialog->DoModal(false); } //----------------------------------------------------------------------------- // Purpose: browser asking to show a tooltip //----------------------------------------------------------------------------- -void HTML::BrowserShowToolTip( const CMsgShowToolTip *pCmd ) +void HTML::BrowserShowToolTip( HTML_ShowToolTip_t *pCmd ) { - /* +/* BR FIXME Tooltip *tip = GetTooltip(); tip->SetText( pCmd->text().c_str() ); @@ -2000,13 +1848,14 @@ void HTML::BrowserShowToolTip( const CMsgShowToolTip *pCmd ) tip->SetMaxToolTipWidth( MAX( 200, GetWide()/2 ) ); tip->ShowTooltip( this ); */ + } //----------------------------------------------------------------------------- // Purpose: browser telling us to update tool tip text //----------------------------------------------------------------------------- -void HTML::BrowserUpdateToolTip( const CMsgUpdateToolTip *pCmd ) +void HTML::BrowserUpdateToolTip( HTML_UpdateToolTip_t *pCmd ) { // GetTooltip()->SetText( pCmd->text().c_str() ); } @@ -2015,7 +1864,7 @@ void HTML::BrowserUpdateToolTip( const CMsgUpdateToolTip *pCmd ) //----------------------------------------------------------------------------- // Purpose: browser telling that it is done with the tip //----------------------------------------------------------------------------- -void HTML::BrowserHideToolTip( const CMsgHideToolTip *pCmd ) +void HTML::BrowserHideToolTip( HTML_HideToolTip_t *pCmd ) { // GetTooltip()->HideTooltip(); // DeleteToolTip(); @@ -2025,17 +1874,17 @@ void HTML::BrowserHideToolTip( const CMsgHideToolTip *pCmd ) //----------------------------------------------------------------------------- // Purpose: callback when performing a search //----------------------------------------------------------------------------- -void HTML::BrowserSearchResults( const CMsgSearchResults *pCmd ) +void HTML::BrowserSearchResults( HTML_SearchResults_t *pCmd ) { - if ( pCmd->results() == 0 ) + if ( pCmd->unResults == 0 ) m_pFindBar->HideCountLabel(); else m_pFindBar->ShowCountLabel(); - if ( pCmd->results() > 0 ) - m_pFindBar->SetDialogVariable( "findcount", (int)pCmd->results() ); - if ( pCmd->activematch() > 0 ) - m_pFindBar->SetDialogVariable( "findactive", (int)pCmd->activematch() ); + if ( pCmd->unResults > 0 ) + m_pFindBar->SetDialogVariable( "findcount", (int)pCmd->unResults ); + if ( pCmd->unCurrentMatch > 0 ) + m_pFindBar->SetDialogVariable( "findactive", (int)pCmd->unCurrentMatch ); m_pFindBar->InvalidateLayout(); } @@ -2043,7 +1892,7 @@ void HTML::BrowserSearchResults( const CMsgSearchResults *pCmd ) //----------------------------------------------------------------------------- // Purpose: browser telling us it had a close requested //----------------------------------------------------------------------------- -void HTML::BrowserClose( const CMsgClose *pCmd ) +void HTML::BrowserClose( HTML_CloseBrowser_t *pCmd ) { PostActionSignal( new KeyValues( "OnCloseWindow" ) ); } @@ -2052,17 +1901,13 @@ void HTML::BrowserClose( const CMsgClose *pCmd ) //----------------------------------------------------------------------------- // Purpose: browser telling us the size of the horizontal scrollbars //----------------------------------------------------------------------------- -void HTML::BrowserHorizontalScrollBarSizeResponse( const CMsgHorizontalScrollBarSizeResponse *pCmd ) +void HTML::BrowserHorizontalScrollBarSizeResponse( HTML_HorizontalScroll_t *pCmd ) { ScrollData_t scrollHorizontal; - scrollHorizontal.m_nX = pCmd->x(); - scrollHorizontal.m_nY = pCmd->y(); - scrollHorizontal.m_nWide = pCmd->wide(); - scrollHorizontal.m_nTall = pCmd->tall(); - scrollHorizontal.m_nScroll = pCmd->scroll(); - scrollHorizontal.m_nMax = pCmd->scroll_max(); - scrollHorizontal.m_bVisible = ( m_scrollHorizontal.m_nTall > 0 ); - scrollHorizontal.m_flZoom = pCmd->zoom(); + scrollHorizontal.m_nScroll = pCmd->unScrollCurrent; + scrollHorizontal.m_nMax = pCmd->unScrollMax; + scrollHorizontal.m_bVisible = pCmd->bVisible; + scrollHorizontal.m_flZoom = pCmd->flPageScale; if ( scrollHorizontal != m_scrollHorizontal ) { @@ -2078,17 +1923,13 @@ void HTML::BrowserHorizontalScrollBarSizeResponse( const CMsgHorizontalScrollBar //----------------------------------------------------------------------------- // Purpose: browser telling us the size of the vertical scrollbars //----------------------------------------------------------------------------- -void HTML::BrowserVerticalScrollBarSizeResponse( const CMsgVerticalScrollBarSizeResponse *pCmd ) +void HTML::BrowserVerticalScrollBarSizeResponse( HTML_VerticalScroll_t *pCmd ) { ScrollData_t scrollVertical; - scrollVertical.m_nX = pCmd->x(); - scrollVertical.m_nY = pCmd->y(); - scrollVertical.m_nWide = pCmd->wide(); - scrollVertical.m_nTall = pCmd->tall(); - scrollVertical.m_nScroll = pCmd->scroll(); - scrollVertical.m_nMax = pCmd->scroll_max(); - scrollVertical.m_bVisible = ( m_scrollVertical.m_nTall > 0 ); - scrollVertical.m_flZoom = pCmd->zoom(); + scrollVertical.m_nScroll = pCmd->unScrollCurrent; + scrollVertical.m_nMax = pCmd->unScrollMax; + scrollVertical.m_bVisible = pCmd->bVisible; + scrollVertical.m_flZoom = pCmd->flPageScale; if ( scrollVertical != m_scrollVertical ) { @@ -2101,27 +1942,14 @@ void HTML::BrowserVerticalScrollBarSizeResponse( const CMsgVerticalScrollBarSize } -//----------------------------------------------------------------------------- -// Purpose: browser telling us the current page zoom -//----------------------------------------------------------------------------- -void HTML::BrowserGetZoomResponse( const CMsgGetZoomResponse *pCmd ) -{ - m_flZoom = pCmd->zoom(); - if ( m_flZoom == 0.0f ) - m_flZoom = 100.0f; - m_flZoom /= 100; // scale zoom to 1.0 being 100%, webkit gives us 100 for normal scale - -} - - //----------------------------------------------------------------------------- // Purpose: browser telling us what is at this location on the page //----------------------------------------------------------------------------- -void HTML::BrowserLinkAtPositionResponse( const CMsgLinkAtPositionResponse *pCmd ) +void HTML::BrowserLinkAtPositionResponse( HTML_LinkAtPosition_t *pCmd ) { - m_LinkAtPos.m_sURL = pCmd->url().c_str(); - m_LinkAtPos.m_nX = pCmd->x(); - m_LinkAtPos.m_nY = pCmd->y(); + m_LinkAtPos.m_sURL = pCmd->pchURL; + m_LinkAtPos.m_nX = pCmd->x; + m_LinkAtPos.m_nY = pCmd->y; m_pContextMenu->SetItemVisible( m_iCopyLinkMenuItemID, !m_LinkAtPos.m_sURL.IsEmpty() ? true : false ); if ( m_bRequestingDragURL ) @@ -2148,21 +1976,12 @@ void HTML::BrowserLinkAtPositionResponse( const CMsgLinkAtPositionResponse *pCmd } -//----------------------------------------------------------------------------- -// Purpose: browser telling us that a zoom to element is done -//----------------------------------------------------------------------------- -void HTML::BrowserZoomToElementAtPositionResponse( const CMsgZoomToElementAtPositionResponse *pCmd ) -{ - -} - - //----------------------------------------------------------------------------- // Purpose: browser telling us to pop a javascript alert dialog //----------------------------------------------------------------------------- -void HTML::BrowserJSAlert( const CMsgJSAlert *pCmd ) +void HTML::BrowserJSAlert( HTML_JSAlert_t *pCmd ) { - MessageBox *pDlg = new MessageBox( m_sCurrentURL, (const char *)pCmd->message().c_str(), this ); + MessageBox *pDlg = new MessageBox( m_sCurrentURL, (const char *)pCmd->pchMessage, this ); pDlg->AddActionSignalTarget( this ); pDlg->SetCommand( new KeyValues( "DismissJSDialog", "result", false ) ); pDlg->DoModal(); @@ -2172,9 +1991,9 @@ void HTML::BrowserJSAlert( const CMsgJSAlert *pCmd ) //----------------------------------------------------------------------------- // Purpose: browser telling us to pop a js confirm dialog //----------------------------------------------------------------------------- -void HTML::BrowserJSConfirm( const CMsgJSConfirm *pCmd ) +void HTML::BrowserJSConfirm( HTML_JSConfirm_t *pCmd ) { - QueryBox *pDlg = new QueryBox( m_sCurrentURL, (const char *)pCmd->message().c_str(), this ); + QueryBox *pDlg = new QueryBox( m_sCurrentURL, (const char *)pCmd->pchMessage, this ); pDlg->AddActionSignalTarget( this ); pDlg->SetOKCommand( new KeyValues( "DismissJSDialog", "result", true ) ); pDlg->SetCancelCommand( new KeyValues( "DismissJSDialog", "result", false ) ); @@ -2187,50 +2006,18 @@ void HTML::BrowserJSConfirm( const CMsgJSConfirm *pCmd ) //----------------------------------------------------------------------------- void HTML::DismissJSDialog( int bResult ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_JSDialogResponse ); - cmd.Body().set_result( bResult==1 ); - DISPATCH_MESSAGE( eHTMLCommands_JSDialogResponse ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->JSDialogResponse( m_unBrowserHandle, bResult ); }; //----------------------------------------------------------------------------- // Purpose: browser telling us the state of back and forward buttons //----------------------------------------------------------------------------- -void HTML::BrowserCanGoBackandForward( const CMsgCanGoBackAndForward *pCmd ) +void HTML::BrowserCanGoBackandForward( HTML_CanGoBackAndForward_t *pCmd ) { - m_bCanGoBack = pCmd->bgoback(); - m_bCanGoForward = pCmd->bgoforward(); -} - - -//----------------------------------------------------------------------------- -// Purpose: browser telling us a steam url was asked to be loaded -//----------------------------------------------------------------------------- -void HTML::BrowserOpenSteamURL( const CMsgOpenSteamURL *pCmd ) -{ - vgui::ivgui()->PostMessage( surface()->GetEmbeddedPanel(), - new KeyValues( "OpenSteamDialog", "cmd", pCmd->url().c_str() ), NULL, 0.3f ); -} - - -//----------------------------------------------------------------------------- -// Purpose: update the value of the cached variables we keep -//----------------------------------------------------------------------------- -void HTML::UpdateCachedHTMLValues() -{ - // request scroll bar sizes - { - CHTMLProtoBufMsg cmd( eHTMLCommands_VerticalScrollBarSize ); - DISPATCH_MESSAGE( eHTMLCommands_VerticalScrollBarSize ); - } - { - CHTMLProtoBufMsg cmd( eHTMLCommands_HorizontalScrollBarSize ); - DISPATCH_MESSAGE( eHTMLCommands_HorizontalScrollBarSize ); - } - { - CHTMLProtoBufMsg cmd( eHTMLCommands_GetZoom ); - DISPATCH_MESSAGE( eHTMLCommands_GetZoom ); - } + m_bCanGoBack = pCmd->bCanGoBack; + m_bCanGoForward = pCmd->bCanGoForward; } @@ -2239,39 +2026,17 @@ void HTML::UpdateCachedHTMLValues() //----------------------------------------------------------------------------- void HTML::GetLinkAtPosition( int x, int y ) { - CHTMLProtoBufMsg cmd( eHTMLCommands_LinkAtPosition ); - cmd.Body().set_x( x ); - cmd.Body().set_y( y ); - DISPATCH_MESSAGE( eHTMLCommands_LinkAtPosition ); + if (m_SteamAPIContext.SteamHTMLSurface()) + m_SteamAPIContext.SteamHTMLSurface()->GetLinkAtPosition( m_unBrowserHandle, x, y ); } -//----------------------------------------------------------------------------- -// Purpose: send any queued html messages we have -//----------------------------------------------------------------------------- -void HTML::SendPendingHTMLMessages() -{ - FOR_EACH_VEC( m_vecPendingMessages, i ) - { - m_vecPendingMessages[i]->m_iBrowser = m_iBrowser; - surface()->AccessChromeHTMLController()->PushCommand( m_vecPendingMessages[i] ); - surface()->AccessChromeHTMLController()->WakeThread(); - } - m_vecPendingMessages.RemoveAll(); -} //----------------------------------------------------------------------------- // Purpose: update the size of the browser itself and scrollbars it shows //----------------------------------------------------------------------------- void HTML::UpdateSizeAndScrollBars() { - // Tell IE BrowserResize(); - - // Do this after we tell IE! - int w,h; - GetSize( w, h ); - CalcScrollBars(w,h); - InvalidateLayout(); } diff --git a/vgui2/vgui_controls/ImagePanel.cpp b/vgui2/vgui_controls/ImagePanel.cpp index bce00908..0baeee9f 100644 --- a/vgui2/vgui_controls/ImagePanel.cpp +++ b/vgui2/vgui_controls/ImagePanel.cpp @@ -38,6 +38,7 @@ ImagePanel::ImagePanel(Panel *parent, const char *name) : Panel(parent, name) m_bTileImage = false; m_bTileHorizontally = false; m_bTileVertically = false; + m_bPositionImage = true; m_fScaleAmount = 0.0f; m_FillColor = Color(0, 0, 0, 0); m_DrawColor = Color(255,255,255,255); @@ -143,25 +144,28 @@ void ImagePanel::PaintBackground() // HPE_END //============================================================================= - if ( m_bCenterImage ) + if ( m_bPositionImage ) { - int wide, tall; - GetSize(wide, tall); - - int imageWide, imageTall; - m_pImage->GetSize( imageWide, imageTall ); - - if ( m_bScaleImage && m_fScaleAmount > 0.0f ) + if ( m_bCenterImage ) { - imageWide = static_cast( static_cast(imageWide) * m_fScaleAmount ); - imageTall = static_cast( static_cast(imageTall) * m_fScaleAmount ); - } + int wide, tall; + GetSize(wide, tall); - m_pImage->SetPos( (wide - imageWide) / 2, (tall - imageTall) / 2 ); - } - else - { - m_pImage->SetPos(0, 0); + int imageWide, imageTall; + m_pImage->GetSize( imageWide, imageTall ); + + if ( m_bScaleImage && m_fScaleAmount > 0.0f ) + { + imageWide = static_cast( static_cast(imageWide) * m_fScaleAmount ); + imageTall = static_cast( static_cast(imageTall) * m_fScaleAmount ); + } + + m_pImage->SetPos( (wide - imageWide) / 2, (tall - imageTall) / 2 ); + } + else + { + m_pImage->SetPos(0, 0); + } } if (m_bScaleImage) @@ -217,7 +221,11 @@ void ImagePanel::PaintBackground() if ( !m_bTileVertically ) break; } - m_pImage->SetPos(0, 0); + + if ( m_bPositionImage ) + { + m_pImage->SetPos(0, 0); + } } else { @@ -259,6 +267,7 @@ void ImagePanel::GetSettings(KeyValues *outResourceData) outResourceData->SetString("border", GetBorder()->GetName()); } + outResourceData->GetInt("positionImage", m_bPositionImage ); outResourceData->SetInt("scaleImage", m_bScaleImage); outResourceData->SetFloat("scaleAmount", m_fScaleAmount); outResourceData->SetInt("tileImage", m_bTileImage); @@ -278,6 +287,7 @@ void ImagePanel::ApplySettings(KeyValues *inResourceData) m_pszFillColorName = NULL; m_pszDrawColorName = NULL; // HPE addition + m_bPositionImage = inResourceData->GetInt("positionImage", 1); m_bScaleImage = inResourceData->GetInt("scaleImage", 0); m_fScaleAmount = inResourceData->GetFloat("scaleAmount", 0.0f); m_bTileImage = inResourceData->GetInt("tileImage", 0); diff --git a/vgui2/vgui_controls/Panel.cpp b/vgui2/vgui_controls/Panel.cpp index 7fb2e630..9ec6c5d5 100644 --- a/vgui2/vgui_controls/Panel.cpp +++ b/vgui2/vgui_controls/Panel.cpp @@ -1858,6 +1858,15 @@ void Panel::InternalMousePressed(int code) } } +#ifdef STAGING_ONLY + // If holding CTRL + ALT, invalidate layout. For debugging purposes + if ( ( vgui::input()->IsKeyDown(KEY_LCONTROL) || vgui::input()->IsKeyDown(KEY_RCONTROL) ) + && ( vgui::input()->IsKeyDown(KEY_LALT) || vgui::input()->IsKeyDown(KEY_RALT) ) ) + { + InvalidateLayout( true, true ); + } +#endif + Panel *pMouseHandler = m_hMouseEventHandler.Get(); if ( pMouseHandler ) { @@ -3911,7 +3920,7 @@ void Panel::PinToSibling( const char *pszSibling, PinCorner_e pinOurCorner, PinC _pinCornerToSibling = pinOurCorner; _pinToSiblingCorner = pinSibling; - if ( _pinToSibling && pszSibling && !Q_strcmp( _pinToSibling, pszSibling ) ) + if ( m_pinSibling.Get() && _pinToSibling && pszSibling && !Q_strcmp( _pinToSibling, pszSibling ) ) return; if (_pinToSibling) @@ -4117,7 +4126,230 @@ void Panel::ApplyAutoResizeSettings(KeyValues *inResourceData) ConVar panel_test_title_safe( "panel_test_title_safe", "0", FCVAR_CHEAT, "Test vgui panel positioning with title safe indentation" ); +int Panel::ComputeWide( KeyValues *inResourceData, int nParentWide, int nParentTall, bool bComputingOther ) +{ + int wide = GetWide(); + const char *wstr = inResourceData->GetString( "wide", NULL ); + if ( wstr ) + { + if ( wstr[0] == 'f' || wstr[0] == 'F' ) + { + _buildModeFlags |= BUILDMODE_SAVE_WIDE_FULL; + wstr++; + } + else + { + if ( wstr[0] == 'o' || wstr[0] == 'O' ) + { + wstr++; + if ( bComputingOther ) + { + Warning( "Wide and Tall of panel %s are set to be each other!\n", GetName() ); + return 0; + } + + _buildModeFlags |= BUILDMODE_SAVE_WIDE_PROPORTIONAL_TALL; + wide = ComputeTall( inResourceData, nParentWide, nParentTall, true ); + + if ( IsProportional() ) + { + wide = scheme()->GetProportionalNormalizedValue( wide ); + } + } + else if ( wstr[0] == 'p' || wstr[0] == 'P' ) + { + _buildModeFlags |= BUILDMODE_SAVE_WIDE_PROPORTIONAL; + wstr++; + } + } + + float flWide = atof(wstr); + if ( !(_buildModeFlags & BUILDMODE_SAVE_WIDE_PROPORTIONAL_TALL) ) + { + wide = atoi(wstr); + } + + if ( _buildModeFlags & BUILDMODE_SAVE_WIDE_PROPORTIONAL_TALL ) + { + wide = scheme()->GetProportionalScaledValueEx(GetScheme(), wide); + wide *= flWide; + } + else if ( _buildModeFlags & BUILDMODE_SAVE_WIDE_PROPORTIONAL ) + { + wide = scheme()->GetProportionalScaledValueEx(GetScheme(), wide); + wide = nParentWide - wide; + wide *= flWide; + } + else + { + if ( IsProportional() ) + { + // scale the width up to our screen co-ords + wide = scheme()->GetProportionalScaledValueEx(GetScheme(), wide); + } + // now correct the alignment + if (_buildModeFlags & BUILDMODE_SAVE_WIDE_FULL) + { + wide = nParentWide - wide; + } + } + } + + return wide; +} + +int Panel::ComputeTall( KeyValues *inResourceData, int nParentWide, int nParentTall, bool bComputingOther ) +{ + int tall = GetTall(); + + // allow tall to be use the "fill" option, set to the height of the parent/screen + const char *tstr = inResourceData->GetString( "tall", NULL ); + if ( tstr ) + { + if (tstr[0] == 'f' || tstr[0] == 'F') + { + _buildModeFlags |= BUILDMODE_SAVE_TALL_FULL; + tstr++; + } + else + { + if ( tstr[0] == 'o' || tstr[0] == 'O' ) + { + tstr++; + if ( bComputingOther ) + { + Warning( "Wide and Tall of panel %s are set to be each other!\n", GetName() ); + return 0; + } + + _buildModeFlags |= BUILDMODE_SAVE_TALL_PROPORTIONAL_WIDE; + tall = ComputeWide( inResourceData, nParentWide, nParentTall, true ); + if ( IsProportional() ) + { + tall = scheme()->GetProportionalNormalizedValue( tall ); + } + } + else if ( tstr[0] == 'p' || tstr[0] == 'P' ) + { + _buildModeFlags |= BUILDMODE_SAVE_TALL_PROPORTIONAL; + tstr++; + } + } + + float flTall = atof(tstr); + if ( !( _buildModeFlags & BUILDMODE_SAVE_TALL_PROPORTIONAL_WIDE ) ) + { + tall = atoi(tstr); + } + + if ( _buildModeFlags & BUILDMODE_SAVE_TALL_PROPORTIONAL_WIDE ) + { + tall = scheme()->GetProportionalScaledValueEx(GetScheme(), tall); + tall *= flTall; + } + else if ( _buildModeFlags & BUILDMODE_SAVE_TALL_PROPORTIONAL ) + { + // scale the height up to our screen co-ords + tall = scheme()->GetProportionalScaledValueEx(GetScheme(), tall); + tall = nParentTall - tall; + tall *= flTall; + } + else + { + if ( IsProportional() ) + { + // scale the height up to our screen co-ords + tall = scheme()->GetProportionalScaledValueEx(GetScheme(), tall); + } + // now correct the alignment + if (_buildModeFlags & BUILDMODE_SAVE_TALL_FULL) + { + tall = nParentTall - tall; + } + } + } + + return tall; +} + +int Panel::ComputePos( const char *pszInput, int &nPos, const int& nSize, const int& nParentSize, const bool& bX ) +{ + const int nFlagRightAlign = bX ? BUILDMODE_SAVE_XPOS_RIGHTALIGNED : BUILDMODE_SAVE_YPOS_BOTTOMALIGNED; + const int nFlagCenterAlign = bX ? BUILDMODE_SAVE_XPOS_CENTERALIGNED : BUILDMODE_SAVE_YPOS_CENTERALIGNED; + const int nFlagProportionalSlef = bX ? BUILDMODE_SAVE_XPOS_PROPORTIONAL_SELF : BUILDMODE_SAVE_YPOS_PROPORTIONAL_SELF; + const int nFlagProportionalParent = bX ? BUILDMODE_SAVE_XPOS_PROPORTIONAL_PARENT : BUILDMODE_SAVE_YPOS_PROPORTIONAL_PARENT; + + int nFlags = 0; + if ( pszInput ) + { + // look for alignment flags + if (pszInput[0] == 'r' || pszInput[0] == 'R') + { + nFlags |= nFlagRightAlign; + pszInput++; + } + else if (pszInput[0] == 'c' || pszInput[0] == 'C') + { + nFlags |= nFlagCenterAlign; + pszInput++; + } + + if ( pszInput[0] == 's' || pszInput[0] == 'S' ) + { + nFlags |= nFlagProportionalSlef; + pszInput++; + } + else if ( pszInput[0] == 'p' || pszInput[0] == 'P' ) + { + nFlags |= nFlagProportionalParent; + pszInput++; + } + + // get the value + nPos = atoi( pszInput ); + float flPos = atof( pszInput ); + + float flProportion = 1.f; + // scale the x up to our screen co-ords + if ( IsProportional() ) + { + int nOldPos = nPos; + nPos = scheme()->GetProportionalScaledValueEx(GetScheme(), nPos); + flProportion = (float)nPos / (float)nOldPos; + } + + int nPosDelta = 0; + if ( nFlags & nFlagProportionalSlef ) + { + nPosDelta = nSize * flPos; + } + else if ( nFlags & nFlagProportionalParent ) + { + nPosDelta = nParentSize * flPos; + } + else + { + nPosDelta = nPos; + } + + // now correct the alignment + if ( nFlags & nFlagRightAlign ) + { + nPos = nParentSize - nPosDelta; + } + else if ( nFlags & nFlagCenterAlign ) + { + nPos = (nParentSize / 2) + nPosDelta; + } + else + { + nPos = nPosDelta; + } + } + + return nFlags; +} //----------------------------------------------------------------------------- // Purpose: Loads panel details from the resource info @@ -4135,7 +4367,19 @@ void Panel::ApplySettings(KeyValues *inResourceData) InternalApplySettings( GetAnimMap(), inResourceData ); // clear any alignment flags - _buildModeFlags &= ~(BUILDMODE_SAVE_XPOS_RIGHTALIGNED | BUILDMODE_SAVE_XPOS_CENTERALIGNED | BUILDMODE_SAVE_YPOS_BOTTOMALIGNED | BUILDMODE_SAVE_YPOS_CENTERALIGNED | BUILDMODE_SAVE_WIDE_FULL | BUILDMODE_SAVE_TALL_FULL | BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT); + _buildModeFlags &= ~( BUILDMODE_SAVE_XPOS_RIGHTALIGNED + | BUILDMODE_SAVE_XPOS_CENTERALIGNED + | BUILDMODE_SAVE_YPOS_BOTTOMALIGNED + | BUILDMODE_SAVE_YPOS_CENTERALIGNED + | BUILDMODE_SAVE_WIDE_FULL + | BUILDMODE_SAVE_TALL_FULL + | BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT + | BUILDMODE_SAVE_WIDE_PROPORTIONAL_TALL + | BUILDMODE_SAVE_TALL_PROPORTIONAL_WIDE + | BUILDMODE_SAVE_XPOS_PROPORTIONAL_PARENT + | BUILDMODE_SAVE_YPOS_PROPORTIONAL_PARENT + | BUILDMODE_SAVE_XPOS_PROPORTIONAL_SELF + | BUILDMODE_SAVE_YPOS_PROPORTIONAL_SELF ); // get the position int alignScreenWide, alignScreenTall; // screen dimensions used for pinning in splitscreen @@ -4169,72 +4413,17 @@ void Panel::ApplySettings(KeyValues *inResourceData) } } + // size + int wide = ComputeWide( inResourceData, alignScreenWide, alignScreenTall, false ); + int tall = ComputeTall( inResourceData, alignScreenWide, alignScreenTall, false ); + int x, y; GetPos(x, y); const char *xstr = inResourceData->GetString( "xpos", NULL ); const char *ystr = inResourceData->GetString( "ypos", NULL ); - - if (xstr) - { - // look for alignment flags - if (xstr[0] == 'r' || xstr[0] == 'R') - { - _buildModeFlags |= BUILDMODE_SAVE_XPOS_RIGHTALIGNED; - xstr++; - } - else if (xstr[0] == 'c' || xstr[0] == 'C') - { - _buildModeFlags |= BUILDMODE_SAVE_XPOS_CENTERALIGNED; - xstr++; - } - - // get the value - x = atoi(xstr); - // scale the x up to our screen co-ords - if ( IsProportional() ) - { - x = scheme()->GetProportionalScaledValueEx(GetScheme(), x); - } - // now correct the alignment - if (_buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED) - { - x = alignScreenWide - x; - } - else if (_buildModeFlags & BUILDMODE_SAVE_XPOS_CENTERALIGNED) - { - x = (alignScreenWide / 2) + x; - } - } - - if (ystr) - { - // look for alignment flags - if (ystr[0] == 'r' || ystr[0] == 'R') - { - _buildModeFlags |= BUILDMODE_SAVE_YPOS_BOTTOMALIGNED; - ystr++; - } - else if (ystr[0] == 'c' || ystr[0] == 'C') - { - _buildModeFlags |= BUILDMODE_SAVE_YPOS_CENTERALIGNED; - ystr++; - } - y = atoi(ystr); - if (IsProportional()) - { - // scale the y up to our screen co-ords - y = scheme()->GetProportionalScaledValueEx(GetScheme(), y); - } - // now correct the alignment - if (_buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED) - { - y = alignScreenTall - y; - } - else if (_buildModeFlags & BUILDMODE_SAVE_YPOS_CENTERALIGNED) - { - y = (alignScreenTall / 2) + y; - } - } + _buildModeFlags |= ComputePos( xstr, x, wide, alignScreenWide, true ); + _buildModeFlags |= ComputePos( ystr, y, tall, alignScreenTall, false ); + bool bUsesTitleSafeArea = false; int titleSafeWide = 0; @@ -4343,53 +4532,6 @@ void Panel::ApplySettings(KeyValues *inResourceData) SetZPos( inResourceData->GetInt( "zpos" ) ); } - // size - int wide, tall; - GetSize( wide, tall ); - - const char *wstr = inResourceData->GetString( "wide", NULL ); - if ( wstr ) - { - if (wstr[0] == 'f' || wstr[0] == 'F') - { - _buildModeFlags |= BUILDMODE_SAVE_WIDE_FULL; - wstr++; - } - wide = atoi(wstr); - if ( IsProportional() ) - { - // scale the width up to our screen co-ords - wide = scheme()->GetProportionalScaledValueEx(GetScheme(), wide); - } - // now correct the alignment - if (_buildModeFlags & BUILDMODE_SAVE_WIDE_FULL) - { - wide = alignScreenWide - wide; - } - } - - // allow tall to be use the "fill" option, set to the height of the parent/screen - wstr = inResourceData->GetString( "tall", NULL ); - if ( wstr ) - { - if (wstr[0] == 'f' || wstr[0] == 'F') - { - _buildModeFlags |= BUILDMODE_SAVE_TALL_FULL; - wstr++; - } - tall = atoi(wstr); - if ( IsProportional() ) - { - // scale the height up to our screen co-ords - tall = scheme()->GetProportionalScaledValueEx(GetScheme(), tall); - } - // now correct the alignment - if (_buildModeFlags & BUILDMODE_SAVE_TALL_FULL) - { - tall = alignScreenTall - tall; - } - } - if( bUsesTitleSafeArea ) { if ( _buildModeFlags & BUILDMODE_SAVE_WIDE_FULL ) diff --git a/vgui2/vgui_controls/PanelListPanel.cpp b/vgui2/vgui_controls/PanelListPanel.cpp index 5ef40966..9e4e6297 100644 --- a/vgui2/vgui_controls/PanelListPanel.cpp +++ b/vgui2/vgui_controls/PanelListPanel.cpp @@ -24,6 +24,8 @@ using namespace vgui; +DECLARE_BUILD_FACTORY( PanelListPanel ); + //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- @@ -135,7 +137,7 @@ Panel *PanelListPanel::GetCellRenderer( int row ) // data->GetName() is used to uniquely identify an item // data sub items are matched against column header name to be used in the table //----------------------------------------------------------------------------- -int PanelListPanel::AddItem( Panel *labelPanel, Panel *panel) +int PanelListPanel::AddItem( Panel *labelPanel, Panel *panel ) { Assert(panel); diff --git a/vgui2/vgui_controls/PerforceFileExplorer.cpp b/vgui2/vgui_controls/PerforceFileExplorer.cpp index de5cf9d1..94099e54 100644 --- a/vgui2/vgui_controls/PerforceFileExplorer.cpp +++ b/vgui2/vgui_controls/PerforceFileExplorer.cpp @@ -102,7 +102,7 @@ void PerforceFileExplorer::SetCurrentDirectory( const char *pFullPath ) m_CurrentDirectory = pFullPath; m_CurrentDirectory.StripTrailingSlash(); - Q_FixSlashes( m_CurrentDirectory.Get() ); + m_CurrentDirectory.FixSlashes(); PopulateFileList(); PopulateDriveList(); diff --git a/vgui2/vgui_controls/RadioButton.cpp b/vgui2/vgui_controls/RadioButton.cpp index f6f49034..70ed758a 100644 --- a/vgui2/vgui_controls/RadioButton.cpp +++ b/vgui2/vgui_controls/RadioButton.cpp @@ -115,7 +115,13 @@ void RadioButton::ApplySchemeSettings(IScheme *pScheme) SetContentAlignment(a_west); // reloading the scheme wipes out lists of images - _radioBoxImage->SetFont( pScheme->GetFont("Marlett", IsProportional()) ); + HFont hFont = pScheme->GetFont("MarlettSmall", IsProportional()); + if ( hFont == INVALID_FONT ) + { + // fallback to Marlett if MarlettSmall isn't found + hFont = pScheme->GetFont("Marlett", IsProportional()); + } + _radioBoxImage->SetFont( hFont ); _radioBoxImage->ResizeImageToContent(); SetImageAtIndex(0, _radioBoxImage, 0); diff --git a/vgui2/vgui_controls/RichText.cpp b/vgui2/vgui_controls/RichText.cpp index c4c76682..3d3ffe9e 100644 --- a/vgui2/vgui_controls/RichText.cpp +++ b/vgui2/vgui_controls/RichText.cpp @@ -748,9 +748,12 @@ void RichText::Paint() _currentTextClickable = m_CachedRenderState.textClickable; renderState.textClickable = _currentTextClickable; - renderState.textColor = m_FormatStream[renderState.formatStreamIndex].color; + + if ( m_FormatStream.IsValidIndex( renderState.formatStreamIndex ) ) + renderState.textColor = m_FormatStream[renderState.formatStreamIndex].color; + CalculateFade( renderState ); - + renderState.formatStreamIndex++; if ( _currentTextClickable ) diff --git a/vgui2/vgui_controls/TextEntry.cpp b/vgui2/vgui_controls/TextEntry.cpp index cecf3e04..fb67df8d 100644 --- a/vgui2/vgui_controls/TextEntry.cpp +++ b/vgui2/vgui_controls/TextEntry.cpp @@ -1637,7 +1637,7 @@ void TextEntry::OnKeyCodePressed(KeyCode code) // Pass on the joystick and mouse codes if ( IsMouseCode(code) || IsNovintButtonCode(code) || IsJoystickCode(code) || IsJoystickButtonCode(code) || - IsJoystickPOVCode(code) || IsJoystickPOVCode(code) || IsJoystickAxisCode(code) ) + IsJoystickPOVCode(code) || IsJoystickAxisCode(code) ) { Panel::OnKeyCodePressed( code ); return; diff --git a/vgui2/vgui_controls/vgui_controls.vpc b/vgui2/vgui_controls/vgui_controls.vpc index 2b90d073..6dea9311 100644 --- a/vgui2/vgui_controls/vgui_controls.vpc +++ b/vgui2/vgui_controls/vgui_controls.vpc @@ -99,7 +99,6 @@ $Project "vgui_controls" $File "URLLabel.cpp" $File "WizardPanel.cpp" $File "WizardSubPanel.cpp" - $File "$SRCDIR\public\html\htmlprotobuf.cpp" $File "$SRCDIR/vgui2/src/vgui_key_translation.cpp" } @@ -196,21 +195,4 @@ $Project "vgui_controls" $File "$SRCDIR\public\vgui_controls\WizardPanel.h" $File "$SRCDIR\public\vgui_controls\WizardSubPanel.h" } - - $Folder "Protobuf Files" - { - $File "$SRCDIR\vgui2\chromehtml\htmlmessages.proto" - $DynamicFile "$GENERATED_PROTO_DIR\htmlmessages.pb.h" - $DynamicFile "$GENERATED_PROTO_DIR\htmlmessages.pb.cc" - { - $Configuration - { - $Compiler - { - $Create/UsePrecompiledHeader "Not Using Precompiled Headers" [$WINDOWS] - } - } - } - } - } diff --git a/vpc_scripts/source_dll_base.vpc b/vpc_scripts/source_dll_base.vpc index c4b73b97..4a1f440f 100644 --- a/vpc_scripts/source_dll_base.vpc +++ b/vpc_scripts/source_dll_base.vpc @@ -10,7 +10,7 @@ $Include "$SRCDIR\vpc_scripts\source_video_base.vpc" $Configuration { - $General [$VS2010] + $General { $TargetExtension "$OUTDLLEXT" } @@ -20,6 +20,6 @@ $Configuration $PreprocessorDefinitions "$BASE;DEV_BUILD" [!$PUBLISH] $PreprocessorDefinitions "$BASE;_PROFILE" [$PROFILE && !$RETAIL] $PreprocessorDefinitions "$BASE;RETAIL_ASSERTS" [$RETAIL && $RETAILASSERTS] - $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" [$NOFPO || $VS2010] + $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" // This is now always true. } } diff --git a/vpc_scripts/source_dll_win32_base.vpc b/vpc_scripts/source_dll_win32_base.vpc index 8bee8137..40fa556a 100644 --- a/vpc_scripts/source_dll_win32_base.vpc +++ b/vpc_scripts/source_dll_win32_base.vpc @@ -24,7 +24,7 @@ $IgnoreRedundancyWarning "ON" // Common Configuration $Configuration { - $General [$VS2010] + $General { $TargetName "$OUTBINNAME" } @@ -50,6 +50,7 @@ $Configuration // Suppress this pointless warning using the undocumented /ignore linker switch // schemalib.lib(schemaclassinfo.obj) : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library $AdditionalOptions "$BASE /ignore:4221" + $AdditionalOptions "$BASE $SRCDIR\lib\public\ftol3.obj" [$VS2013 && $WIN32 && !$DISABLE_FTOL3_OVERRIDE && !$SOURCESDK] // Work around CRT bug https://connect.microsoft.com/VisualStudio/feedback/details/806362/vc12-pollutes-the-floating-point-stack-when-casting-infinity-nan-to-unsigned-long# } $PreBuildEvent @@ -105,8 +106,8 @@ $Project } // Implement __imp__EncodePointer and __imp__DecodePointer so that we can run on XP SP1 - // when building with VS 2010. - $File "$SRCDIR\public\tier0\pointeroverride.asm" [$WIN32 && $VS2010] + // when building with VS 2010 and higher. + $File "$SRCDIR\public\tier0\pointeroverride.asm" [$WIN32] { $Configuration { diff --git a/vpc_scripts/source_dll_win32_debug.vpc b/vpc_scripts/source_dll_win32_debug.vpc index 47e79b22..4b00b170 100644 --- a/vpc_scripts/source_dll_win32_debug.vpc +++ b/vpc_scripts/source_dll_win32_debug.vpc @@ -153,7 +153,7 @@ $Configuration "Debug" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmt" + $IgnoreSpecificLibrary "libc;libcd;libcmt;libcpmt;libcpmt1" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile @@ -166,7 +166,6 @@ $Configuration "Debug" $ManifestFile $AdditionalManifestDependencies $AllowIsolation - //$UACExecutionLevel [$VS2010] // Debugging $GenerateDebugInfo "Yes (/DEBUG)" diff --git a/vpc_scripts/source_dll_win32_release.vpc b/vpc_scripts/source_dll_win32_release.vpc index 82aa0d53..6f026bdb 100644 --- a/vpc_scripts/source_dll_win32_release.vpc +++ b/vpc_scripts/source_dll_win32_release.vpc @@ -82,7 +82,7 @@ $Configuration "Release" // Preprocessor $PreprocessorDefinitions "$BASE;WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions)" - $PreprocessorDefinitions "$BASE;RELEASE_ASSERTS" [$RELEASEASSERTS] + $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] $IgnoreStandardIncludePath $GeneratePreprocessedFile $KeepComments @@ -142,8 +142,11 @@ $Configuration "Release" $ErrorReporting "Prompt Immediately (/errorReport:prompt)" $AdditionalOptions "/Zm200" - // Enable extra debugging information. - $AdditionalOptions "$BASE /d2Zi+" [$VS2010] + // Enable extra debugging information. This switch requires VS 2013 Update 3. + // With VS 2013 make sure that Edit-And-Continue is disabled in the debugger settings so that + // the debugger uses the enhanced debug information. + // http://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ + $AdditionalOptions "$BASE /Zo" $AdditionalOptions "$BASE /Oy-" [$NOFPO] } @@ -165,7 +168,7 @@ $Configuration "Release" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmtd" + $IgnoreSpecificLibrary "libc;libcd;libcmtd;libcpmtd;libcpmtd0;libcpmtd1" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile diff --git a/vpc_scripts/source_exe_base.vpc b/vpc_scripts/source_exe_base.vpc index 24b94cb2..e1fec14e 100644 --- a/vpc_scripts/source_exe_base.vpc +++ b/vpc_scripts/source_exe_base.vpc @@ -15,6 +15,6 @@ $Configuration $PreprocessorDefinitions "$BASE;DEV_BUILD" [!$PUBLISH] $PreprocessorDefinitions "$BASE;_PROFILE" [$PROFILE && !$RETAIL] $PreprocessorDefinitions "$BASE;RETAIL_ASSERTS" [$RETAIL && $RETAILASSERTS] - $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" [$NOFPO || $VS2010] + $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" // This is now always true. } } \ No newline at end of file diff --git a/vpc_scripts/source_exe_con_base.vpc b/vpc_scripts/source_exe_con_base.vpc index 8edc0449..b38ef4a2 100644 --- a/vpc_scripts/source_exe_con_base.vpc +++ b/vpc_scripts/source_exe_con_base.vpc @@ -13,6 +13,6 @@ $Configuration $PreprocessorDefinitions "$BASE;DEV_BUILD" [!$PUBLISH] $PreprocessorDefinitions "$BASE;_PROFILE" [$PROFILE && !$RETAIL] $PreprocessorDefinitions "$BASE;RETAIL_ASSERTS" [$RETAIL && $RETAILASSERTS] - $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" [$NOFPO || $VS2010] + $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" // This is now always true. } } diff --git a/vpc_scripts/source_exe_con_win32_base.vpc b/vpc_scripts/source_exe_con_win32_base.vpc index e410cdf0..b734f297 100644 --- a/vpc_scripts/source_exe_con_win32_base.vpc +++ b/vpc_scripts/source_exe_con_win32_base.vpc @@ -14,7 +14,7 @@ $Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc" $Configuration { - $General [$VS2010] + $General { $TargetName "$OUTBINNAME" } diff --git a/vpc_scripts/source_exe_win_win32_base.vpc b/vpc_scripts/source_exe_win_win32_base.vpc index b0db090e..54478a33 100644 --- a/vpc_scripts/source_exe_win_win32_base.vpc +++ b/vpc_scripts/source_exe_win_win32_base.vpc @@ -24,7 +24,7 @@ $IgnoreRedundancyWarning "ON" // Common Configuration $Configuration { - $General [$VS2010] + $General { $TargetName "$OUTBINNAME" } @@ -53,6 +53,7 @@ $Configuration // Suppress this pointless warning using the undocumented /ignore linker switch // schemalib.lib(schemaclassinfo.obj) : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library $AdditionalOptions "$BASE /ignore:4221" + $AdditionalOptions "$BASE $SRCDIR\lib\public\ftol3.obj" [$VS2013 && $WIN32 && !$DISABLE_FTOL3_OVERRIDE && !$SOURCESDK] // Work around CRT bug https://connect.microsoft.com/VisualStudio/feedback/details/806362/vc12-pollutes-the-floating-point-stack-when-casting-infinity-nan-to-unsigned-long# } $PreBuildEvent @@ -100,8 +101,8 @@ $Project } // Implement __imp__EncodePointer and __imp__DecodePointer so that we can run on XP SP1 - // when building with VS 2010. - $File "$SRCDIR\public\tier0\pointeroverride.asm" [$WIN32 && $VS2010] + // when building with VS 2010 and higher. + $File "$SRCDIR\public\tier0\pointeroverride.asm" [$WIN32] { $Configuration { diff --git a/vpc_scripts/source_exe_win_win32_debug.vpc b/vpc_scripts/source_exe_win_win32_debug.vpc index 581b04d4..cbc85e45 100644 --- a/vpc_scripts/source_exe_win_win32_debug.vpc +++ b/vpc_scripts/source_exe_win_win32_debug.vpc @@ -158,7 +158,7 @@ $Configuration "Debug" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmt" + $IgnoreSpecificLibrary "libc;libcd;libcmt;libcpmt;libcpmt1" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile @@ -246,7 +246,7 @@ $Configuration "Debug" $UseFAT32WorkAround // Input And Output - $AdditionalManifestFiles "$SRCDIR\public\windows_default.manifest" [$VS2010 && !$SOURCESDK] + $AdditionalManifestFiles "$SRCDIR\public\windows_default.manifest" [!$SOURCESDK] $InputResourceManifests $EmbedManifest $OutputManifestFile diff --git a/vpc_scripts/source_exe_win_win32_release.vpc b/vpc_scripts/source_exe_win_win32_release.vpc index 5cb229ce..00c649ca 100644 --- a/vpc_scripts/source_exe_win_win32_release.vpc +++ b/vpc_scripts/source_exe_win_win32_release.vpc @@ -82,7 +82,7 @@ $Configuration "Release" // Preprocessor $PreprocessorDefinitions "$BASE;WIN32;_WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions)" - $PreprocessorDefinitions "$BASE;RELEASE_ASSERTS" [$RELEASEASSERTS] + $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] $IgnoreStandardIncludePath $GeneratePreprocessedFile $KeepComments @@ -141,8 +141,11 @@ $Configuration "Release" $OmitDefaultLibraryNames $ErrorReporting "Prompt Immediately (/errorReport:prompt)" - // Enable extra debugging information. - $AdditionalOptions "$BASE /d2Zi+" [$VS2010] + // Enable extra debugging information. This switch requires VS 2013 Update 3. + // With VS 2013 make sure that Edit-And-Continue is disabled in the debugger settings so that + // the debugger uses the enhanced debug information. + // http://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ + $AdditionalOptions "$BASE /Zo" // Command Line $AdditionalOptions "$BASE /Oy-" [$NOFPO] } @@ -165,7 +168,7 @@ $Configuration "Release" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmtd" + $IgnoreSpecificLibrary "libc;libcd;libcmtd;libcpmtd;libcpmtd0;libcpmtd1" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile @@ -264,7 +267,7 @@ $Configuration "Release" $UseFAT32WorkAround // Input And Output - $AdditionalManifestFiles "$SRCDIR\public\windows_default.manifest" [$VS2010 && !$SOURCESDK] + $AdditionalManifestFiles "$SRCDIR\public\windows_default.manifest" [!$SOURCESDK] $InputResourceManifests $EmbedManifest $OutputManifestFile diff --git a/vpc_scripts/source_lib_base.vpc b/vpc_scripts/source_lib_base.vpc index 9a07dbe7..47e9b97f 100644 --- a/vpc_scripts/source_lib_base.vpc +++ b/vpc_scripts/source_lib_base.vpc @@ -17,6 +17,6 @@ $Configuration $PreprocessorDefinitions "$BASE;DEV_BUILD" [!$PUBLISH] $PreprocessorDefinitions "$BASE;_PROFILE" [$PROFILE && !$RETAIL] $PreprocessorDefinitions "$BASE;RETAIL_ASSERTS" [$RETAIL && $RETAILASSERTS] - $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" [$NOFPO || $VS2010] + $PreprocessorDefinitions "$BASE;FRAME_POINTER_OMISSION_DISABLED" // This is now always true. } } diff --git a/vpc_scripts/source_lib_win32_base.vpc b/vpc_scripts/source_lib_win32_base.vpc index dbf2c701..ab8543b7 100644 --- a/vpc_scripts/source_lib_win32_base.vpc +++ b/vpc_scripts/source_lib_win32_base.vpc @@ -22,7 +22,7 @@ $IgnoreRedundancyWarning "ON" // Common Configuration $Configuration { - $General [$VS2010] + $General { $TargetName "$OUTLIBNAME" } diff --git a/vpc_scripts/source_lib_win32_debug.vpc b/vpc_scripts/source_lib_win32_debug.vpc index 75e27035..d34690ba 100644 --- a/vpc_scripts/source_lib_win32_debug.vpc +++ b/vpc_scripts/source_lib_win32_debug.vpc @@ -23,8 +23,7 @@ $Configuration "Debug" $General { // General - $OutputDirectory ".\Debug$_SUBDIRSUFFIX" [!$VS2010] - $OutputDirectory "$OUTLIBDIR" [$VS2010] + $OutputDirectory "$OUTLIBDIR" $IntermediateDirectory ".\Debug$_SUBDIRSUFFIX" $ExtensionsToDeleteOnClean $BuildLogFile diff --git a/vpc_scripts/source_lib_win32_release.vpc b/vpc_scripts/source_lib_win32_release.vpc index 9c1736d5..18613050 100644 --- a/vpc_scripts/source_lib_win32_release.vpc +++ b/vpc_scripts/source_lib_win32_release.vpc @@ -27,10 +27,7 @@ $Configuration "Release" $General { // General - $OutputDirectory ".\Release$_SUBDIRSUFFIX" [!$VS2010 && !$RETAIL && !$PROFILE] - $OutputDirectory ".\Retail$_SUBDIRSUFFIX" [!$VS2010 && $RETAIL] - $OutputDirectory ".\Profile$_SUBDIRSUFFIX" [!$VS2010 && !$RETAIL && $PROFILE] - $OutputDirectory "$OUTLIBDIR" [$VS2010] + $OutputDirectory "$OUTLIBDIR" $IntermediateDirectory ".\Release$_SUBDIRSUFFIX" [!$RETAIL && !$PROFILE] $IntermediateDirectory ".\Retail$_SUBDIRSUFFIX" [$RETAIL] $IntermediateDirectory ".\Profile$_SUBDIRSUFFIX" [!$RETAIL && $PROFILE] @@ -83,7 +80,7 @@ $Configuration "Release" // Preprocessor $PreprocessorDefinitions "$BASE;WIN32;_WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions)" - $PreprocessorDefinitions "$BASE;RELEASE_ASSERTS" [$RELEASEASSERTS] + $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] $IgnoreStandardIncludePath $GeneratePreprocessedFile $KeepComments @@ -142,8 +139,11 @@ $Configuration "Release" $OmitDefaultLibraryNames $ErrorReporting "Prompt Immediately (/errorReport:prompt)" - // Enable extra debugging information. - $AdditionalOptions "/d2Zi+" [$VS2010] + // Enable extra debugging information. This switch requires VS 2013 Update 3. + // With VS 2013 make sure that Edit-And-Continue is disabled in the debugger settings so that + // the debugger uses the enhanced debug information. + // http://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ + $AdditionalOptions "$BASE /Zo" $AdditionalOptions "$BASE /Oy-" [$NOFPO] } diff --git a/vpc_scripts/source_linux_base_project.vpc b/vpc_scripts/source_linux_base_project.vpc index f7fd40d5..c465da38 100644 --- a/vpc_scripts/source_linux_base_project.vpc +++ b/vpc_scripts/source_linux_base_project.vpc @@ -13,7 +13,8 @@ $Configuration "Debug" $Compiler { $PreprocessorDefinitions "DEBUG;_DEBUG" - $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" + $OptimizerLevel "-gdwarf-2 -g $(OptimizerLevel_CompilerSpecific)" [$OSXALL] + $OptimizerLevel "-gdwarf-4 -g $(OptimizerLevel_CompilerSpecific)" [$LINUX] } } @@ -22,8 +23,9 @@ $Configuration "Release" $Compiler { $PreprocessorDefinitions "NDEBUG" + $OptimizerLevel "-gdwarf-2 -g $(OptimizerLevel_CompilerSpecific)" [$OSXALL] + $OptimizerLevel "-gdwarf-4 -g $(OptimizerLevel_CompilerSpecific)" [$LINUX] $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] - $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" } } diff --git a/vpc_scripts/source_posix_base.vpc b/vpc_scripts/source_posix_base.vpc index 8e0fc436..a6f32a8e 100644 --- a/vpc_scripts/source_posix_base.vpc +++ b/vpc_scripts/source_posix_base.vpc @@ -12,7 +12,8 @@ $Configuration "Debug" $Compiler { $PreprocessorDefinitions "$BASE;DEBUG;_DEBUG" - $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" + $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" [$OSXALL] + $OptimizerLevel "-gdwarf-4 -g2 $(OptimizerLevel_CompilerSpecific)" [$LINUX] } } @@ -21,7 +22,9 @@ $Configuration "Release" $Compiler { $PreprocessorDefinitions "$BASE;NDEBUG" - $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" + $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" [$OSXALL] + $OptimizerLevel "-gdwarf-4 -g2 $(OptimizerLevel_CompilerSpecific)" [$LINUX] + $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] } } diff --git a/vpc_scripts/source_win32_base.vpc b/vpc_scripts/source_win32_base.vpc index 41b8cbfa..5e9cc6ce 100644 --- a/vpc_scripts/source_win32_base.vpc +++ b/vpc_scripts/source_win32_base.vpc @@ -1,8 +1,14 @@ +// Settings for /analyze are in a separate .vpc file so that they can be +// changed without triggering a full rebuild of non-analyze builds. On non-analyze +// builds the analyze.vpc file will not be listed as a dependency. +$Include "$SRCDIR\vpc_scripts\source_win32_analyze.vpc" [$ANALYZE] + $Configuration { $General { // Request a specific compiler toolset. + $PlatformToolset "v100" [$VS2010] $PlatformToolset "v110_xp" [$VS2012 && !$ANALYZE] // VS 2012 targeting Windows XP - http://msdn.microsoft.com/en-us/library/vstudio/jj851139.aspx $PlatformToolset "v110" [$VS2012 && $ANALYZE] // VS 2012 for /analyze $PlatformToolset "v120_xp" [$VS2013 && !$ANALYZE] // VS 2013 targeting Windows XP - http://msdn.microsoft.com/en-us/library/vstudio/jj851139.aspx @@ -27,45 +33,26 @@ $Configuration // warning C4316: object allocated on the heap may not be aligned 16 $DisableSpecificWarnings "$BASE;4316" [$VS2013] - // When using /analyze (triggered with /define:ANALYZE on the vpc command line) we want to forcibly disable lots - // of warnings (also disabled in platform.h but not everybody includes that). - // See platform.h for the list of warnings with explanations. - // warning C6318: Ill-defined __try/__except: use of the constant EXCEPTION_CONTINUE_SEARCH -- bogus - // warning C6322: Empty _except block - // Set the stack size threshold to 100,000 to avoid noisy warnings on functions with modest stack usage - // Note that /analyze for VS 2010 only works with the 32-bit compiler, but for VS 2012 it works on 64-bit - // as well. - $DisableSpecificWarnings "$BASE;6308;6255;6387;6309;6011;6211;6031;6326;6239;6285;6237;6235;6240;6323;6326;6335;6320;6250;6384;6318;6322" [$ANALYZE] - // See http://randomascii.wordpress.com/2011/10/04/analyzecommand-line-options/ for details on these options. - // /analyze:only may result in fewer warnings being reported, but the warnings it misses should show up in the regular build. - $AdditionalOptions "$BASE /analyze /analyze:only /analyze:stacksize100000" [$ANALYZE] - - // Specify /define:ALLOWSHADOWING to suppress variable shadowing warnings - $DisableSpecificWarnings "$BASE;6244;6246" [$ANALYZE && $ALLOWSHADOWING] - - // New warnings in VS 2012 that we want to ignore. - // warning C4005: 'DXGI_STATUS_OCCLUDED' : macro redefinition - // warning C6014: Leaking memory 'pThinkParams'. - // warning C28159: Consider using 'GetTickCount64' instead of 'GetTickCount'. Reason: GetTickCount overflows roughly every 49 days. - // warning C28182: Dereferencing NULL pointer. 'pPropMesh' contains the same NULL value as '(CMesh *)=(pPropMesh)' did. - // warning C28183: 'entropy->ac_count_ptrs[actbl]' could be '0', and is a copy of the value found in 'entropy->dc_count_ptrs[dctbl]': this does not adhere to the specification for the function 'memset'. - // warning C28197: Possibly leaking memory 'pInfo'. - // warning C28198: Possibly leaking memory 'kvFrame1' due to an exception. Is a local catch block needed to clean up memory? - // warning C28204: 'QueryInterface' : Only one of this overload and the one at c:\program files (x86)\windows kits\8.0\include\um\unknwnbase.h(114) are annotated for _Param_(2): both or neither must be annotated. - // warning C28247: Model file annotation for function '_vsnprintf': annotation on _Param_(1)/SAL_post, 'RequiresZeroTermination' duplicates header file annotation 'SAL_nullTerminated'. Remove the duplicated annotations from the model file. (Header: c:\program files (x86)\microsoft visual studio 11.0\vc\include\stdio.h(349).) - // warning C28251: Inconsistent annotation for 'WinMain': this instance has no annotations. See c:\program files (x86)\windows kits\8.0\include\um\winbase.h(2286). - // warning C28301: No annotations for first declaration of 'InitializeCriticalSection'. See d:\clients\tf3\staging\src\public\tier0\threadtools.h(1373). - // warning C28195: The function was declared as acquiring memory in 'return' and exited without doing so. - // warning C6340: Mismatch on sign: 'unsigned short' passed as parameter '6' when some signed type is required in call to 'V_snprintf'. - // This warning only applies to Windows XP in low-memory situations: - // warning C28125: The function 'InitializeCriticalSection' must be called from within a try\except block - // warning C28160: Error annotation: Calling VirtualFreeEx without the MEM_RELEASE flag frees memory but not address descriptors (VADs); results in address space leaks. - // warning C6248: Setting a SECURITY_DESCRIPTOR's DACL to NULL will result in an unprotected object. - // warning C6102: Using value from failed function call - $DisableSpecificWarnings "$BASE;6014;28159;28182;28183;28197;28198;28204;28247;28251;28301;28195;6340;28125;28160;6248;6102" [$ANALYZE && ($VS2012 || $VS2013)] + // Having lots of warnings makes it harder to notice new, and possibly + // important warnings, both on buildbot and in the output window. Lots + // of warnings also makes it harder to skip through errors in the output + // window since F8 stops on both warnings and errors. The only way to + // keep the warning count down is to have warnings-as-errors. + // We will not be warning free on 64-bit for a while... + $TreatWarningsAsErrors "Yes (/WX)" [!$ANALYZE && !$WIN64] // Defines to differentiate 32 from 64 bit builds $PreprocessorDefinitions "$BASE;PLATFORM_64BITS;WIN64;_WIN64;COMPILER_MSVC64" [$WIN64] $PreprocessorDefinitions "$BASE;COMPILER_MSVC32" [$WIN32] + + // /Gw is a VS 2013 option that puts global and static variables in individual sections so that the + // linker can discard unreferenced data. When building @client /dota with linker optimizations this + // reduces the client.dll size by about 1.14%. When linker optimizations are disabled this has no + // effect. This option does not show up in the IDE so we need to add it in $AdditionalOptions. + // http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx + $AdditionalOptions "$BASE /Gw" [$VS2013] + // Strip unreferenced inline functions from object files to shrink .obj files and .lib files, + // improve linker speed, and improve conformance. Requires VS 2013 Update 3 + $AdditionalOptions "$BASE /Zc:inline" [$VS2013] } }