diff --git a/sp/src/game/client/c_baseplayer.cpp b/sp/src/game/client/c_baseplayer.cpp index 0b2422fa..57a9c7eb 100644 --- a/sp/src/game/client/c_baseplayer.cpp +++ b/sp/src/game/client/c_baseplayer.cpp @@ -332,7 +332,10 @@ END_RECV_TABLE() RecvPropString( RECVINFO(m_szLastPlaceName) ), - RecvPropEHandle(RECVINFO(m_hPostProcessCtrl)), // Send to everybody - for spectating +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropEHandle( RECVINFO( m_hPostProcessCtrl ) ), // Send to everybody - for spectating + RecvPropEHandle( RECVINFO( m_hColorCorrectionCtrl ) ), // Send to everybody - for spectating +#endif #if defined USES_ECON_ITEMS RecvPropUtlVector( RECVINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, RecvPropEHandle(NULL, 0, 0) ), @@ -2918,6 +2921,7 @@ void C_BasePlayer::UpdateFogBlend( void ) } } +#ifdef MAPBASE // From Alien Swarm SDK //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- @@ -2926,6 +2930,15 @@ C_PostProcessController* C_BasePlayer::GetActivePostProcessController() const return m_hPostProcessCtrl.Get(); } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +C_ColorCorrection* C_BasePlayer::GetActiveColorCorrection() const +{ + return m_hColorCorrectionCtrl.Get(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/sp/src/game/client/c_baseplayer.h b/sp/src/game/client/c_baseplayer.h index 84ccffb5..5b569595 100644 --- a/sp/src/game/client/c_baseplayer.h +++ b/sp/src/game/client/c_baseplayer.h @@ -23,7 +23,10 @@ #include "hintsystem.h" #include "SoundEmitterSystem/isoundemittersystembase.h" #include "c_env_fog_controller.h" +#ifdef MAPBASE // From Alien Swarm SDK #include "c_postprocesscontroller.h" +#include "c_colorcorrection.h" +#endif #include "igameevents.h" #include "GameEventListener.h" @@ -381,7 +384,10 @@ public: void UpdateFogController( void ); void UpdateFogBlend( void ); +#ifdef MAPBASE // From Alien Swarm SDK C_PostProcessController* GetActivePostProcessController() const; + C_ColorCorrection* GetActiveColorCorrection() const; +#endif float GetFOVTime( void ){ return m_flFOVTime; } @@ -647,7 +653,10 @@ private: // One for left and one for right side of step StepSoundCache_t m_StepSoundCache[ 2 ]; - CNetworkHandle(C_PostProcessController, m_hPostProcessCtrl); // active postprocessing controller +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkHandle( C_PostProcessController, m_hPostProcessCtrl ); // active postprocessing controller + CNetworkHandle( C_ColorCorrection, m_hColorCorrectionCtrl ); // active FXVolume color correction +#endif public: diff --git a/sp/src/game/client/c_colorcorrection.cpp b/sp/src/game/client/c_colorcorrection.cpp index 6960031d..12e29768 100644 --- a/sp/src/game/client/c_colorcorrection.cpp +++ b/sp/src/game/client/c_colorcorrection.cpp @@ -6,6 +6,7 @@ //===========================================================================// #include "cbase.h" +#include "c_colorcorrection.h" #include "filesystem.h" #include "cdll_client_int.h" #include "colorcorrectionmgr.h" @@ -17,45 +18,27 @@ static ConVar mat_colcorrection_disableentities( "mat_colcorrection_disableentities", "0", FCVAR_NONE, "Disable map color-correction entities" ); - -//------------------------------------------------------------------------------ -// Purpose : Color correction entity with radial falloff -//------------------------------------------------------------------------------ -class C_ColorCorrection : public C_BaseEntity -{ -public: - DECLARE_CLASS( C_ColorCorrection, C_BaseEntity ); - - DECLARE_CLIENTCLASS(); - - C_ColorCorrection(); - virtual ~C_ColorCorrection(); - - void OnDataChanged(DataUpdateType_t updateType); - bool ShouldDraw(); - - void ClientThink(); - -private: - Vector m_vecOrigin; - - float m_minFalloff; - float m_maxFalloff; - float m_flCurWeight; - char m_netLookupFilename[MAX_PATH]; - - bool m_bEnabled; - - ClientCCHandle_t m_CCHandle; -}; +#ifdef MAPBASE // From Alien Swarm SDK +static ConVar mat_colcorrection_forceentitiesclientside( "mat_colcorrection_forceentitiesclientside", "0", FCVAR_CHEAT, "Forces color correction entities to be updated on the client" ); +#endif IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrection, DT_ColorCorrection, CColorCorrection) RecvPropVector( RECVINFO(m_vecOrigin) ), RecvPropFloat( RECVINFO(m_minFalloff) ), RecvPropFloat( RECVINFO(m_maxFalloff) ), RecvPropFloat( RECVINFO(m_flCurWeight) ), +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropFloat( RECVINFO(m_flMaxWeight) ), + RecvPropFloat( RECVINFO(m_flFadeInDuration) ), + RecvPropFloat( RECVINFO(m_flFadeOutDuration) ), +#endif RecvPropString( RECVINFO(m_netLookupFilename) ), RecvPropBool( RECVINFO(m_bEnabled) ), +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropBool( RECVINFO(m_bMaster) ), + RecvPropBool( RECVINFO(m_bClientSide) ), + RecvPropBool( RECVINFO(m_bExclusive) ) +#endif END_RECV_TABLE() @@ -65,14 +48,43 @@ END_RECV_TABLE() //------------------------------------------------------------------------------ C_ColorCorrection::C_ColorCorrection() { +#ifdef MAPBASE // From Alien Swarm SDK + m_minFalloff = -1.0f; + m_maxFalloff = -1.0f; + m_flFadeInDuration = 0.0f; + m_flFadeOutDuration = 0.0f; + m_flCurWeight = 0.0f; + m_flMaxWeight = 1.0f; + m_netLookupFilename[0] = '\0'; + m_bEnabled = false; + m_bMaster = false; + m_bExclusive = false; +#endif m_CCHandle = INVALID_CLIENT_CCHANDLE; + +#ifdef MAPBASE // From Alien Swarm SDK + m_bFadingIn = false; + m_flFadeStartWeight = 0.0f; + m_flFadeStartTime = 0.0f; + m_flFadeDuration = 0.0f; +#endif } C_ColorCorrection::~C_ColorCorrection() { +#ifdef MAPBASE // From Alien Swarm SDK + g_pColorCorrectionMgr->RemoveColorCorrectionEntity( this, m_CCHandle ); +#else g_pColorCorrectionMgr->RemoveColorCorrection( m_CCHandle ); +#endif } +#ifdef MAPBASE // From Alien Swarm SDK +bool C_ColorCorrection::IsClientSide() const +{ + return m_bClientSide || mat_colcorrection_forceentitiesclientside.GetBool(); +} +#endif //------------------------------------------------------------------------------ // Purpose : @@ -87,11 +99,21 @@ void C_ColorCorrection::OnDataChanged(DataUpdateType_t updateType) { if ( m_CCHandle == INVALID_CLIENT_CCHANDLE ) { +#ifdef MAPBASE // From Alien Swarm SDK + // forming a unique name without extension + char cleanName[MAX_PATH]; + V_StripExtension( m_netLookupFilename, cleanName, sizeof( cleanName ) ); + char name[MAX_PATH]; + Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() ); + + m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionEntity( this, name, m_netLookupFilename ); +#else char filename[MAX_PATH]; Q_strncpy( filename, m_netLookupFilename, MAX_PATH ); m_CCHandle = g_pColorCorrectionMgr->AddColorCorrection( filename ); SetNextClientThink( ( m_CCHandle != INVALID_CLIENT_CCHANDLE ) ? CLIENT_THINK_ALWAYS : CLIENT_THINK_NEVER ); +#endif } } } @@ -104,6 +126,129 @@ bool C_ColorCorrection::ShouldDraw() return false; } +#ifdef MAPBASE // From Alien Swarm SDK +void C_ColorCorrection::Update( C_BasePlayer *pPlayer, float ccScale ) +{ + Assert( m_CCHandle != INVALID_CLIENT_CCHANDLE ); + + if ( mat_colcorrection_disableentities.GetInt() ) + { + // Allow the colorcorrectionui panel (or user) to turn off color-correction entities + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive ); + return; + } + + // fade weight on client + if ( IsClientSide() ) + { + m_flCurWeight = Lerp( GetFadeRatio(), m_flFadeStartWeight, m_bFadingIn ? m_flMaxWeight : 0.0f ); + } + + if( !m_bEnabled && m_flCurWeight == 0.0f ) + { + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive ); + return; + } + + Vector playerOrigin = pPlayer->GetAbsOrigin(); + + float weight = 0; + if ( ( m_minFalloff != -1 ) && ( m_maxFalloff != -1 ) && m_minFalloff != m_maxFalloff ) + { + float dist = (playerOrigin - m_vecOrigin).Length(); + weight = (dist-m_minFalloff) / (m_maxFalloff-m_minFalloff); + if ( weight<0.0f ) weight = 0.0f; + if ( weight>1.0f ) weight = 1.0f; + } + + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_flCurWeight * ( 1.0 - weight ) * ccScale, m_bExclusive ); +} + +void C_ColorCorrection::EnableOnClient( bool bEnable, bool bSkipFade ) +{ + if ( !IsClientSide() ) + { + return; + } + + m_bFadingIn = bEnable; + + // initialize countdown timer + m_flFadeStartWeight = m_flCurWeight; + float flFadeTimeScale = 1.0f; + if ( m_flMaxWeight != 0.0f ) + { + flFadeTimeScale = m_flCurWeight / m_flMaxWeight; + } + + if ( m_bFadingIn ) + { + flFadeTimeScale = 1.0f - flFadeTimeScale; + } + + if ( bSkipFade ) + { + flFadeTimeScale = 0.0f; + } + + StartFade( flFadeTimeScale * ( m_bFadingIn ? m_flFadeInDuration : m_flFadeOutDuration ) ); + + // update the clientside weight once here, in case the fade duration is 0 + m_flCurWeight = Lerp( GetFadeRatio(), m_flFadeStartWeight, m_bFadingIn ? m_flMaxWeight : 0.0f ); +} + +Vector C_ColorCorrection::GetOrigin() +{ + return m_vecOrigin; +} + +float C_ColorCorrection::GetMinFalloff() +{ + return m_minFalloff; +} + +float C_ColorCorrection::GetMaxFalloff() +{ + return m_maxFalloff; +} + +void C_ColorCorrection::SetWeight( float fWeight ) +{ + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, fWeight, false ); +} + +void C_ColorCorrection::StartFade( float flDuration ) +{ + m_flFadeStartTime = gpGlobals->curtime; + m_flFadeDuration = MAX( flDuration, 0.0f ); +} + +float C_ColorCorrection::GetFadeRatio() const +{ + float flRatio = 1.0f; + + if ( m_flFadeDuration != 0.0f ) + { + flRatio = ( gpGlobals->curtime - m_flFadeStartTime ) / m_flFadeDuration; + flRatio = clamp( flRatio, 0.0f, 1.0f ); + } + return flRatio; +} + +bool C_ColorCorrection::IsFadeTimeElapsed() const +{ + return ( ( gpGlobals->curtime - m_flFadeStartTime ) > m_flFadeDuration ) || + ( ( gpGlobals->curtime - m_flFadeStartTime ) < 0.0f ); +} + +void UpdateColorCorrectionEntities( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrection **pList, int listCount ) +{ + for ( int i = 0; i < listCount; i++ ) + { + pList[i]->Update(pPlayer, ccScale); + } +} +#else void C_ColorCorrection::ClientThink() { if ( m_CCHandle == INVALID_CLIENT_CCHANDLE ) @@ -141,6 +286,7 @@ void C_ColorCorrection::ClientThink() BaseClass::ClientThink(); } +#endif diff --git a/sp/src/game/client/c_colorcorrection.h b/sp/src/game/client/c_colorcorrection.h new file mode 100644 index 00000000..63149a0a --- /dev/null +++ b/sp/src/game/client/c_colorcorrection.h @@ -0,0 +1,88 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Note that this header exists in the Alien Swarm SDK, but not in stock Source SDK 2013. +// Although technically a new Mapbase file, it only serves to move otherwise identical code, +// so most code and repo conventions will pretend it was always there. +// +// -------------------------------------------------------------------- +// +// Purpose: Color correction entity with simple radial falloff +// +//=============================================================================// + +#ifndef C_COLORCORRECTION_H +#define C_COLORCORRECTION_H +#ifdef _WIN32 +#pragma once +#endif + +#include "colorcorrectionmgr.h" + +//------------------------------------------------------------------------------ +// Purpose : Color correction entity with radial falloff +//------------------------------------------------------------------------------ +class C_ColorCorrection : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_ColorCorrection, C_BaseEntity ); + + DECLARE_CLIENTCLASS(); + + C_ColorCorrection(); + virtual ~C_ColorCorrection(); + + void OnDataChanged(DataUpdateType_t updateType); + bool ShouldDraw(); + +#ifdef MAPBASE // From Alien Swarm SDK + virtual void Update(C_BasePlayer *pPlayer, float ccScale); + + bool IsMaster() const { return m_bMaster; } + bool IsClientSide() const; + bool IsExclusive() const { return m_bExclusive; } + + void EnableOnClient( bool bEnable, bool bSkipFade = false ); + + Vector GetOrigin(); + float GetMinFalloff(); + float GetMaxFalloff(); + + void SetWeight( float fWeight ); + +protected: + void StartFade( float flDuration ); + float GetFadeRatio() const; + bool IsFadeTimeElapsed() const; +#else + void ClientThink(); + +private: +#endif + Vector m_vecOrigin; + + float m_minFalloff; + float m_maxFalloff; + float m_flCurWeight; + char m_netLookupFilename[MAX_PATH]; + + bool m_bEnabled; + +#ifdef MAPBASE // From Alien Swarm SDK + float m_flFadeInDuration; + float m_flFadeOutDuration; + float m_flMaxWeight; + + bool m_bMaster; + bool m_bClientSide; + bool m_bExclusive; + + bool m_bFadingIn; + float m_flFadeStartWeight; + float m_flFadeStartTime; + float m_flFadeDuration; +#endif + + ClientCCHandle_t m_CCHandle; +}; + +#endif diff --git a/sp/src/game/client/c_colorcorrectionvolume.cpp b/sp/src/game/client/c_colorcorrectionvolume.cpp index 4bbcea94..f7e33708 100644 --- a/sp/src/game/client/c_colorcorrectionvolume.cpp +++ b/sp/src/game/client/c_colorcorrectionvolume.cpp @@ -36,9 +36,26 @@ public: void OnDataChanged(DataUpdateType_t updateType); bool ShouldDraw(); +#ifdef MAPBASE // From Alien Swarm SDK + void Update( C_BasePlayer *pPlayer, float ccScale ); + + void StartTouch( C_BaseEntity *pOther ); + void EndTouch( C_BaseEntity *pOther ); +#else void ClientThink(); +#endif private: +#ifdef MAPBASE // From Alien Swarm SDK + float m_LastEnterWeight; + float m_LastEnterTime; + + float m_LastExitWeight; + float m_LastExitTime; + bool m_bEnabled; + float m_MaxWeight; + float m_FadeDuration; +#endif float m_Weight; char m_lookupFilename[MAX_PATH]; @@ -46,6 +63,11 @@ private: }; IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrectionVolume, DT_ColorCorrectionVolume, CColorCorrectionVolume) +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropBool( RECVINFO( m_bEnabled ) ), + RecvPropFloat( RECVINFO( m_MaxWeight ) ), + RecvPropFloat( RECVINFO( m_FadeDuration ) ), +#endif RecvPropFloat( RECVINFO(m_Weight) ), RecvPropString( RECVINFO(m_lookupFilename) ), END_RECV_TABLE() @@ -82,11 +104,21 @@ void C_ColorCorrectionVolume::OnDataChanged(DataUpdateType_t updateType) { if ( m_CCHandle == INVALID_CLIENT_CCHANDLE ) { +#ifdef MAPBASE // From Alien Swarm SDK + // forming a unique name without extension + char cleanName[MAX_PATH]; + V_StripExtension( m_lookupFilename, cleanName, sizeof( cleanName ) ); + char name[MAX_PATH]; + Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() ); + + m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionVolume( this, name, m_lookupFilename ); +#else char filename[MAX_PATH]; Q_strncpy( filename, m_lookupFilename, MAX_PATH ); m_CCHandle = g_pColorCorrectionMgr->AddColorCorrection( filename ); SetNextClientThink( ( m_CCHandle != INVALID_CLIENT_CCHANDLE ) ? CLIENT_THINK_ALWAYS : CLIENT_THINK_NEVER ); +#endif } } } @@ -99,11 +131,95 @@ bool C_ColorCorrectionVolume::ShouldDraw() return false; } +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +void C_ColorCorrectionVolume::StartTouch( CBaseEntity *pEntity ) +{ + m_LastEnterTime = gpGlobals->curtime; + m_LastEnterWeight = m_Weight; +} + + +//-------------------------------------------------------------------------------------------------------- +void C_ColorCorrectionVolume::EndTouch( CBaseEntity *pEntity ) +{ + m_LastExitTime = gpGlobals->curtime; + m_LastExitWeight = m_Weight; +} + + +void C_ColorCorrectionVolume::Update( C_BasePlayer *pPlayer, float ccScale ) +{ + if ( pPlayer ) + { + bool isTouching = CollisionProp()->IsPointInBounds( pPlayer->EyePosition() ); + bool wasTouching = m_LastEnterTime > m_LastExitTime; + + if ( isTouching && !wasTouching ) + { + StartTouch( pPlayer ); + } + else if ( !isTouching && wasTouching ) + { + EndTouch( pPlayer ); + } + } + + if( !m_bEnabled ) + { + m_Weight = 0.0f; + } + else + { + if( m_LastEnterTime > m_LastExitTime ) + { + // we most recently entered the volume + + if( m_Weight < 1.0f ) + { + float dt = gpGlobals->curtime - m_LastEnterTime; + float weight = m_LastEnterWeight + dt / ((1.0f-m_LastEnterWeight)*m_FadeDuration); + if( weight>1.0f ) + weight = 1.0f; + + m_Weight = weight; + } + } + else + { + // we most recently exitted the volume + + if( m_Weight > 0.0f ) + { + float dt = gpGlobals->curtime - m_LastExitTime; + float weight = (1.0f-m_LastExitWeight) + dt / (m_LastExitWeight*m_FadeDuration); + if( weight>1.0f ) + weight = 1.0f; + + m_Weight = 1.0f - weight; + } + } + } + + // Vector entityPosition = GetAbsOrigin(); + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_Weight * ccScale ); +} + + +void UpdateColorCorrectionVolumes( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrectionVolume **pList, int listCount ) +{ + for ( int i = 0; i < listCount; i++ ) + { + pList[i]->Update(pPlayer, ccScale); + } +} +#else void C_ColorCorrectionVolume::ClientThink() { Vector entityPosition = GetAbsOrigin(); g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_Weight ); } +#endif diff --git a/sp/src/game/client/clientmode_shared.cpp b/sp/src/game/client/clientmode_shared.cpp index 6f2aa4b8..f2e6e31d 100644 --- a/sp/src/game/client/clientmode_shared.cpp +++ b/sp/src/game/client/clientmode_shared.cpp @@ -292,8 +292,11 @@ ClientModeShared::ClientModeShared() m_pWeaponSelection = NULL; m_nRootSize[ 0 ] = m_nRootSize[ 1 ] = -1; +#ifdef MAPBASE // From Alien Swarm SDK m_pCurrentPostProcessController = NULL; m_PostProcessLerpTimer.Invalidate(); + m_pCurrentColorCorrection = NULL; +#endif #if defined( REPLAY_ENABLED ) m_pReplayReminderPanel = NULL; @@ -635,6 +638,43 @@ void ClientModeShared::Update() } } +#ifdef MAPBASE // From Alien Swarm SDK +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void ClientModeShared::OnColorCorrectionWeightsReset( void ) +{ + C_ColorCorrection *pNewColorCorrection = NULL; + C_ColorCorrection *pOldColorCorrection = m_pCurrentColorCorrection; + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( pPlayer ) + { + pNewColorCorrection = pPlayer->GetActiveColorCorrection(); + } + + if ( pNewColorCorrection != pOldColorCorrection ) + { + if ( pOldColorCorrection ) + { + pOldColorCorrection->EnableOnClient( false ); + } + if ( pNewColorCorrection ) + { + pNewColorCorrection->EnableOnClient( true, pOldColorCorrection == NULL ); + } + m_pCurrentColorCorrection = pNewColorCorrection; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +float ClientModeShared::GetColorCorrectionScale( void ) const +{ + return 1.0f; +} +#endif + //----------------------------------------------------------------------------- // This processes all input before SV Move messages are sent //----------------------------------------------------------------------------- diff --git a/sp/src/game/client/clientmode_shared.h b/sp/src/game/client/clientmode_shared.h index a1389f96..20288db8 100644 --- a/sp/src/game/client/clientmode_shared.h +++ b/sp/src/game/client/clientmode_shared.h @@ -91,6 +91,11 @@ public: virtual void ProcessInput(bool bActive); virtual bool CreateMove( float flInputSampleTime, CUserCmd *cmd ); virtual void Update(); +#ifdef MAPBASE // From Alien Swarm SDK + virtual void OnColorCorrectionWeightsReset( void ); + virtual float GetColorCorrectionScale( void ) const; + virtual void ClearCurrentColorCorrection() { m_pCurrentColorCorrection = NULL; } +#endif // Input virtual int KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ); @@ -165,12 +170,16 @@ private: CBaseHudWeaponSelection *m_pWeaponSelection; int m_nRootSize[2]; +#ifdef MAPBASE // From Alien Swarm SDK void UpdatePostProcessingEffects(); const C_PostProcessController* m_pCurrentPostProcessController; PostProcessParameters_t m_CurrentPostProcessParameters; PostProcessParameters_t m_LerpStartPostProcessParameters, m_LerpEndPostProcessParameters; CountdownTimer m_PostProcessLerpTimer; + + CHandle m_pCurrentColorCorrection; +#endif }; #endif // CLIENTMODE_NORMAL_H diff --git a/sp/src/game/client/colorcorrectionmgr.cpp b/sp/src/game/client/colorcorrectionmgr.cpp index 770354b0..cf1210ac 100644 --- a/sp/src/game/client/colorcorrectionmgr.cpp +++ b/sp/src/game/client/colorcorrectionmgr.cpp @@ -8,6 +8,12 @@ #include "cbase.h" #include "tier0/vprof.h" #include "colorcorrectionmgr.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "clientmode_shared.h" //"clientmode.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" +#endif //------------------------------------------------------------------------------ @@ -16,6 +22,13 @@ static CColorCorrectionMgr s_ColorCorrectionMgr; CColorCorrectionMgr *g_pColorCorrectionMgr = &s_ColorCorrectionMgr; +#ifdef MAPBASE // From Alien Swarm SDK +static ConVar mat_colcorrection_editor( "mat_colcorrection_editor", "0" ); + +static CUtlVector g_ColorCorrectionList; +static CUtlVector g_ColorCorrectionVolumeList; +#endif + //------------------------------------------------------------------------------ // Constructor @@ -62,10 +75,89 @@ void CColorCorrectionMgr::RemoveColorCorrection( ClientCCHandle_t h ) } } +#ifdef MAPBASE // From Alien Swarm SDK +ClientCCHandle_t CColorCorrectionMgr::AddColorCorrectionEntity( C_ColorCorrection *pEntity, const char *pName, const char *pFileName ) +{ + ClientCCHandle_t h = AddColorCorrection(pName, pFileName); + if ( h != INVALID_CLIENT_CCHANDLE ) + { + Assert(g_ColorCorrectionList.Find(pEntity) == -1); + g_ColorCorrectionList.AddToTail(pEntity); + } + return h; +} + +void CColorCorrectionMgr::RemoveColorCorrectionEntity( C_ColorCorrection *pEntity, ClientCCHandle_t h) +{ + RemoveColorCorrection(h); + g_ColorCorrectionList.FindAndFastRemove(pEntity); +} + +ClientCCHandle_t CColorCorrectionMgr::AddColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, const char *pName, const char *pFileName ) +{ + ClientCCHandle_t h = AddColorCorrection(pName, pFileName); + if ( h != INVALID_CLIENT_CCHANDLE ) + { + Assert(g_ColorCorrectionVolumeList.Find(pVolume) == -1); + g_ColorCorrectionVolumeList.AddToTail(pVolume); + } + return h; +} + +void CColorCorrectionMgr::RemoveColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, ClientCCHandle_t h) +{ + RemoveColorCorrection(h); + g_ColorCorrectionVolumeList.FindAndFastRemove(pVolume); +} +#endif //------------------------------------------------------------------------------ // Modify color correction weights //------------------------------------------------------------------------------ +#ifdef MAPBASE // From Alien Swarm SDK +void CColorCorrectionMgr::SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight, bool bExclusive ) +{ + if ( h != INVALID_CLIENT_CCHANDLE ) + { + SetWeightParams_t params = { h, flWeight, bExclusive }; + m_colorCorrectionWeights.AddToTail( params ); + if( bExclusive && m_bHaveExclusiveWeight && ( flWeight != 0.0f ) ) + { + DevWarning( "Found multiple active color_correction entities with exclusive setting enabled. This is invalid.\n" ); + } + if ( bExclusive ) + { + m_bHaveExclusiveWeight = true; + m_flExclusiveWeight = flWeight; + } + } +} + +void CColorCorrectionMgr::CommitColorCorrectionWeights() +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + + for ( int i = 0; i < m_colorCorrectionWeights.Count(); i++ ) + { + ColorCorrectionHandle_t ccHandle = reinterpret_cast( m_colorCorrectionWeights[i].handle ); + float flWeight = m_colorCorrectionWeights[i].flWeight; + if ( !m_colorCorrectionWeights[i].bExclusive ) + { + flWeight = (1.0f - m_flExclusiveWeight ) * m_colorCorrectionWeights[i].flWeight; + } + pRenderContext->SetLookupWeight( ccHandle, flWeight ); + + // FIXME: NOTE! This doesn't work if the same handle has + // its weight set twice with no intervening calls to ResetColorCorrectionWeights + // which, at the moment, is true + if ( flWeight != 0.0f ) + { + ++m_nActiveWeightCount; + } + } + m_colorCorrectionWeights.RemoveAll(); +} +#else void CColorCorrectionMgr::SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight ) { if ( h != INVALID_CLIENT_CCHANDLE ) @@ -83,6 +175,7 @@ void CColorCorrectionMgr::SetColorCorrectionWeight( ClientCCHandle_t h, float fl } } } +#endif void CColorCorrectionMgr::ResetColorCorrectionWeights() { @@ -93,6 +186,11 @@ void CColorCorrectionMgr::ResetColorCorrectionWeights() CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); pRenderContext->ResetLookupWeights(); m_nActiveWeightCount = 0; +#ifdef MAPBASE // From Alien Swarm SDK + m_bHaveExclusiveWeight = false; + m_flExclusiveWeight = 0.0f; + m_colorCorrectionWeights.RemoveAll(); +#endif } void CColorCorrectionMgr::SetResetable( ClientCCHandle_t h, bool bResetable ) @@ -113,7 +211,34 @@ void CColorCorrectionMgr::SetResetable( ClientCCHandle_t h, bool bResetable ) //------------------------------------------------------------------------------ // Is color correction active? //------------------------------------------------------------------------------ +#ifdef MAPBASE // From Alien Swarm SDK +bool CColorCorrectionMgr::HasNonZeroColorCorrectionWeights() const +{ + return ( m_nActiveWeightCount != 0 ) || mat_colcorrection_editor.GetBool(); +} + +void CColorCorrectionMgr::UpdateColorCorrection() +{ + ResetColorCorrectionWeights(); + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + IClientMode *pClientMode = GetClientModeNormal(); //GetClientMode(); + + Assert( pClientMode ); + if ( !pPlayer || !pClientMode ) + { + return; + } + + pClientMode->OnColorCorrectionWeightsReset(); + float ccScale = pClientMode->GetColorCorrectionScale(); + + UpdateColorCorrectionEntities( pPlayer, ccScale, g_ColorCorrectionList.Base(), g_ColorCorrectionList.Count() ); + UpdateColorCorrectionVolumes( pPlayer, ccScale, g_ColorCorrectionVolumeList.Base(), g_ColorCorrectionVolumeList.Count() ); + CommitColorCorrectionWeights(); +} +#else bool CColorCorrectionMgr::HasNonZeroColorCorrectionWeights() const { return ( m_nActiveWeightCount != 0 ); } +#endif diff --git a/sp/src/game/client/colorcorrectionmgr.h b/sp/src/game/client/colorcorrectionmgr.h index 3d5271db..3eba0f8c 100644 --- a/sp/src/game/client/colorcorrectionmgr.h +++ b/sp/src/game/client/colorcorrectionmgr.h @@ -14,6 +14,10 @@ #include "igamesystem.h" +#ifdef MAPBASE // From Alien Swarm SDK +class C_ColorCorrection; +class C_ColorCorrectionVolume; +#endif //------------------------------------------------------------------------------ // Purpose : Singleton manager for color correction on the client @@ -35,8 +39,21 @@ public: ClientCCHandle_t AddColorCorrection( const char *pName, const char *pFileName = NULL ); void RemoveColorCorrection( ClientCCHandle_t ); +#ifdef MAPBASE // From Alien Swarm SDK + ClientCCHandle_t AddColorCorrectionEntity( C_ColorCorrection *pEntity, const char *pName, const char *pFileName = NULL ); + void RemoveColorCorrectionEntity( C_ColorCorrection *pEntity, ClientCCHandle_t ); + + ClientCCHandle_t AddColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, const char *pName, const char *pFileName = NULL ); + void RemoveColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, ClientCCHandle_t ); +#endif + // Modify color correction weights +#ifdef MAPBASE // From Alien Swarm SDK + void SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight, bool bExclusive = false ); + void UpdateColorCorrection(); +#else void SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight ); +#endif void ResetColorCorrectionWeights(); void SetResetable( ClientCCHandle_t h, bool bResetable ); @@ -45,8 +62,27 @@ public: private: int m_nActiveWeightCount; +#ifdef MAPBASE // From Alien Swarm SDK + bool m_bHaveExclusiveWeight; + float m_flExclusiveWeight; + + struct SetWeightParams_t + { + ClientCCHandle_t handle; + float flWeight; + bool bExclusive; + }; + + CUtlVector< SetWeightParams_t > m_colorCorrectionWeights; + + void CommitColorCorrectionWeights(); +#endif }; +#ifdef MAPBASE // From Alien Swarm SDK +void UpdateColorCorrectionEntities( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrection **pList, int listCount ); +void UpdateColorCorrectionVolumes( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrectionVolume **pList, int listCount ); +#endif //------------------------------------------------------------------------------ // Singleton access diff --git a/sp/src/game/client/iclientmode.h b/sp/src/game/client/iclientmode.h index 2b74f625..38b60047 100644 --- a/sp/src/game/client/iclientmode.h +++ b/sp/src/game/client/iclientmode.h @@ -112,6 +112,11 @@ public: virtual bool CanRecordDemo( char *errorMsg, int length ) const = 0; +#ifdef MAPBASE // From Alien Swarm SDK + virtual void OnColorCorrectionWeightsReset( void ) = 0; + virtual float GetColorCorrectionScale( void ) const = 0; +#endif + virtual void ComputeVguiResConditions( KeyValues *pkvConditions ) = 0; //============================================================================= diff --git a/sp/src/game/client/viewrender.cpp b/sp/src/game/client/viewrender.cpp index e3889d74..c88858d5 100644 --- a/sp/src/game/client/viewrender.cpp +++ b/sp/src/game/client/viewrender.cpp @@ -76,6 +76,7 @@ #ifdef MAPBASE #include "mapbase/c_func_fake_worldportal.h" +#include "colorcorrectionmgr.h" #endif // Projective textures @@ -2133,6 +2134,10 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT // Must be first render->SceneBegin(); +#ifdef MAPBASE // From Alien Swarm SDK + g_pColorCorrectionMgr->UpdateColorCorrection(); +#endif + pRenderContext.GetFrom( materials ); pRenderContext->TurnOnToneMapping(); pRenderContext.SafeRelease(); diff --git a/sp/src/game/server/colorcorrection.cpp b/sp/src/game/server/colorcorrection.cpp index 16d01222..69e6db85 100644 --- a/sp/src/game/server/colorcorrection.cpp +++ b/sp/src/game/server/colorcorrection.cpp @@ -5,9 +5,8 @@ // $NoKeywords: $ //===========================================================================// -#include - #include "cbase.h" +#include "colorcorrection.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -16,64 +15,6 @@ static const char *s_pFadeInContextThink = "ColorCorrectionFadeInThink"; static const char *s_pFadeOutContextThink = "ColorCorrectionFadeOutThink"; - -//------------------------------------------------------------------------------ -// FIXME: This really should inherit from something more lightweight -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Purpose : Shadow control entity -//------------------------------------------------------------------------------ -class CColorCorrection : public CBaseEntity -{ - DECLARE_CLASS( CColorCorrection, CBaseEntity ); -public: - DECLARE_SERVERCLASS(); - DECLARE_DATADESC(); - - CColorCorrection(); - - void Spawn( void ); - int UpdateTransmitState(); - void Activate( void ); - - virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - // Inputs - void InputEnable( inputdata_t &inputdata ); - void InputDisable( inputdata_t &inputdata ); - void InputSetFadeInDuration ( inputdata_t &inputdata ); - void InputSetFadeOutDuration ( inputdata_t &inputdata ); - -private: - void FadeIn ( void ); - void FadeOut ( void ); - - void FadeInThink( void ); // Fades lookup weight from Cur->MaxWeight - void FadeOutThink( void ); // Fades lookup weight from CurWeight->0.0 - - - - float m_flFadeInDuration; // Duration for a full 0->MaxWeight transition - float m_flFadeOutDuration; // Duration for a full Max->0 transition - float m_flStartFadeInWeight; - float m_flStartFadeOutWeight; - float m_flTimeStartFadeIn; - float m_flTimeStartFadeOut; - - float m_flMaxWeight; - - bool m_bStartDisabled; - CNetworkVar( bool, m_bEnabled ); - - CNetworkVar( float, m_MinFalloff ); - CNetworkVar( float, m_MaxFalloff ); - CNetworkVar( float, m_flCurWeight ); - CNetworkString( m_netlookupFilename, MAX_PATH ); - - string_t m_lookupFilename; -}; LINK_ENTITY_TO_CLASS(color_correction, CColorCorrection); @@ -97,12 +38,19 @@ BEGIN_DATADESC( CColorCorrection ) DEFINE_KEYFIELD( m_bEnabled, FIELD_BOOLEAN, "enabled" ), DEFINE_KEYFIELD( m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled" ), +#ifdef MAPBASE // From Alien Swarm SDK + DEFINE_KEYFIELD( m_bExclusive, FIELD_BOOLEAN, "exclusive" ), +#endif // DEFINE_ARRAY( m_netlookupFilename, FIELD_CHARACTER, MAX_PATH ), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeInDuration", InputSetFadeInDuration ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeOutDuration", InputSetFadeOutDuration ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMinFalloff", InputSetMinFalloff ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxFalloff", InputSetMaxFalloff ), +#endif END_DATADESC() @@ -112,8 +60,18 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE(CColorCorrection, DT_ColorCorrection) SendPropFloat( SENDINFO(m_MinFalloff) ), SendPropFloat( SENDINFO(m_MaxFalloff) ), SendPropFloat( SENDINFO(m_flCurWeight) ), +#ifdef MAPBASE // From Alien Swarm SDK + SendPropFloat( SENDINFO(m_flMaxWeight) ), + SendPropFloat( SENDINFO(m_flFadeInDuration) ), + SendPropFloat( SENDINFO(m_flFadeOutDuration) ), +#endif SendPropString( SENDINFO(m_netlookupFilename) ), SendPropBool( SENDINFO(m_bEnabled) ), +#ifdef MAPBASE // From Alien Swarm SDK + SendPropBool( SENDINFO(m_bMaster) ), + SendPropBool( SENDINFO(m_bClientSide) ), + SendPropBool( SENDINFO(m_bExclusive) ), +#endif END_SEND_TABLE() @@ -132,6 +90,11 @@ CColorCorrection::CColorCorrection() : BaseClass() m_flTimeStartFadeOut = 0.0f; m_netlookupFilename.GetForModify()[0] = 0; m_lookupFilename = NULL_STRING; +#ifdef MAPBASE // From Alien Swarm SDK + m_bMaster = false; + m_bClientSide = false; + m_bExclusive = false; +#endif } @@ -175,6 +138,11 @@ void CColorCorrection::Activate( void ) { BaseClass::Activate(); +#ifdef MAPBASE // From Alien Swarm SDK (moved to Activate() for save/restore support) + m_bMaster = IsMaster(); + m_bClientSide = IsClientSide(); +#endif + Q_strncpy( m_netlookupFilename.GetForModify(), STRING( m_lookupFilename ), MAX_PATH ); } @@ -183,6 +151,11 @@ void CColorCorrection::Activate( void ) //----------------------------------------------------------------------------- void CColorCorrection::FadeIn ( void ) { +#ifdef MAPBASE // From Alien Swarm SDK + if ( m_bClientSide || ( m_bEnabled && m_flCurWeight >= m_flMaxWeight ) ) + return; +#endif + m_bEnabled = true; m_flTimeStartFadeIn = gpGlobals->curtime; m_flStartFadeInWeight = m_flCurWeight; @@ -194,6 +167,11 @@ void CColorCorrection::FadeIn ( void ) //----------------------------------------------------------------------------- void CColorCorrection::FadeOut ( void ) { +#ifdef MAPBASE // From Alien Swarm SDK + if ( m_bClientSide || ( !m_bEnabled && m_flCurWeight <= 0.0f ) ) + return; +#endif + m_bEnabled = false; m_flTimeStartFadeOut = gpGlobals->curtime; m_flStartFadeOutWeight = m_flCurWeight; @@ -230,7 +208,11 @@ void CColorCorrection::FadeInThink( void ) flFadeRatio = clamp ( flFadeRatio, 0.0f, 1.0f ); m_flStartFadeInWeight = clamp ( m_flStartFadeInWeight, 0.0f, 1.0f ); +#ifdef MAPBASE + m_flCurWeight = Lerp( flFadeRatio, m_flStartFadeInWeight, m_flMaxWeight.Get() ); +#else m_flCurWeight = Lerp( flFadeRatio, m_flStartFadeInWeight, m_flMaxWeight ); +#endif SetNextThink( gpGlobals->curtime + COLOR_CORRECTION_ENT_THINK_RATE, s_pFadeInContextThink ); } @@ -312,3 +294,94 @@ void CColorCorrection::InputSetFadeOutDuration( inputdata_t& inputdata ) { m_flFadeOutDuration = inputdata.value.Float(); } + +#ifdef MAPBASE +void CColorCorrection::InputSetMinFalloff( inputdata_t& inputdata ) +{ + m_MinFalloff = inputdata.value.Float(); +} + +void CColorCorrection::InputSetMaxFalloff( inputdata_t& inputdata ) +{ + m_MaxFalloff = inputdata.value.Float(); +} +#endif + +#ifdef MAPBASE // From Alien Swarm SDK +CColorCorrectionSystem s_ColorCorrectionSystem( "ColorCorrectionSystem" ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CColorCorrectionSystem *ColorCorrectionSystem( void ) +{ + return &s_ColorCorrectionSystem; +} + + +//----------------------------------------------------------------------------- +// Purpose: Clear out the fog controller. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::LevelInitPreEntity( void ) +{ + m_hMasterController = NULL; + ListenForGameEvent( "round_start" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Find the master controller. If no controller is +// set as Master, use the first controller found. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::InitMasterController( void ) +{ + CColorCorrection *pColorCorrection = NULL; + do + { + pColorCorrection = static_cast( gEntList.FindEntityByClassname( pColorCorrection, "color_correction" ) ); + if ( pColorCorrection ) + { + if ( m_hMasterController.Get() == NULL ) + { + m_hMasterController = pColorCorrection; + } + else + { + if ( pColorCorrection->IsMaster() ) + { + m_hMasterController = pColorCorrection; + } + } + } + } while ( pColorCorrection ); +} + +//----------------------------------------------------------------------------- +// Purpose: On a multiplayer map restart, re-find the master controller. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::FireGameEvent( IGameEvent *pEvent ) +{ + InitMasterController(); +} + +//----------------------------------------------------------------------------- +// Purpose: On level load find the master fog controller. If no controller is +// set as Master, use the first fog controller found. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::LevelInitPostEntity( void ) +{ + InitMasterController(); + + // HACK: Singleplayer games don't get a call to CBasePlayer::Spawn on level transitions. + // CBasePlayer::Activate is called before this is called so that's too soon to set up the fog controller. + // We don't have a hook similar to Activate that happens after LevelInitPostEntity + // is called, or we could just do this in the player itself. + if ( gpGlobals->maxClients == 1 ) + { + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer && ( pPlayer->m_hColorCorrectionCtrl.Get() == NULL ) ) + { + pPlayer->InitColorCorrectionController(); + } + } +} +#endif diff --git a/sp/src/game/server/colorcorrection.h b/sp/src/game/server/colorcorrection.h new file mode 100644 index 00000000..2e96eb7c --- /dev/null +++ b/sp/src/game/server/colorcorrection.h @@ -0,0 +1,147 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Note that this header exists in the Alien Swarm SDK, but not in stock Source SDK 2013. +// Although technically a new Mapbase file, it only serves to move otherwise identical code, +// so most code and repo conventions will pretend it was always there. +// +// -------------------------------------------------------------------- +// +// Purpose: Color correction entity. +// +//=============================================================================// + +#ifndef COLOR_CORRECTION_H +#define COLOR_CORRECTION_H +#ifdef _WIN32 +#pragma once +#endif + +#include +#include "cbase.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "GameEventListener.h" + +// Spawn Flags +#define SF_COLORCORRECTION_MASTER 0x0001 +#define SF_COLORCORRECTION_CLIENTSIDE 0x0002 +#endif + +//------------------------------------------------------------------------------ +// FIXME: This really should inherit from something more lightweight +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Purpose : Shadow control entity +//------------------------------------------------------------------------------ +class CColorCorrection : public CBaseEntity +{ + DECLARE_CLASS( CColorCorrection, CBaseEntity ); +public: + DECLARE_SERVERCLASS(); + DECLARE_DATADESC(); + + CColorCorrection(); + + void Spawn( void ); + int UpdateTransmitState(); + void Activate( void ); + + virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } + +#ifdef MAPBASE // From Alien Swarm SDK + bool IsMaster( void ) const { return HasSpawnFlags( SF_COLORCORRECTION_MASTER ); } + + bool IsClientSide( void ) const { return HasSpawnFlags( SF_COLORCORRECTION_CLIENTSIDE ); } + + bool IsExclusive( void ) const { return m_bExclusive; } +#endif + + // Inputs + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputSetFadeInDuration ( inputdata_t &inputdata ); + void InputSetFadeOutDuration ( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetMinFalloff( inputdata_t &inputdata ); + void InputSetMaxFalloff( inputdata_t &inputdata ); +#endif + +private: + void FadeIn ( void ); + void FadeOut ( void ); + + void FadeInThink( void ); // Fades lookup weight from Cur->MaxWeight + void FadeOutThink( void ); // Fades lookup weight from CurWeight->0.0 + + + +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( float, m_flFadeInDuration ); // Duration for a full 0->MaxWeight transition + CNetworkVar( float, m_flFadeOutDuration ); // Duration for a full Max->0 transition +#else + float m_flFadeInDuration; // Duration for a full 0->MaxWeight transition + float m_flFadeOutDuration; // Duration for a full Max->0 transition +#endif + float m_flStartFadeInWeight; + float m_flStartFadeOutWeight; + float m_flTimeStartFadeIn; + float m_flTimeStartFadeOut; + +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( float, m_flMaxWeight ); +#else + float m_flMaxWeight; +#endif + + bool m_bStartDisabled; + CNetworkVar( bool, m_bEnabled ); +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( bool, m_bMaster ); + CNetworkVar( bool, m_bClientSide ); + CNetworkVar( bool, m_bExclusive ); +#endif + + CNetworkVar( float, m_MinFalloff ); + CNetworkVar( float, m_MaxFalloff ); + CNetworkVar( float, m_flCurWeight ); + CNetworkString( m_netlookupFilename, MAX_PATH ); + + string_t m_lookupFilename; +}; + +#ifdef MAPBASE // From Alien Swarm SDK +//============================================================================= +// +// ColorCorrection Controller System. Just a place to store a master controller +// +class CColorCorrectionSystem : public CAutoGameSystem, public CGameEventListener +{ +public: + + // Creation/Init. + CColorCorrectionSystem( char const *name ) : CAutoGameSystem( name ) + { + m_hMasterController = NULL; + } + + ~CColorCorrectionSystem() + { + m_hMasterController = NULL; + } + + virtual void LevelInitPreEntity(); + virtual void LevelInitPostEntity(); + virtual void FireGameEvent( IGameEvent *pEvent ); + CColorCorrection *GetMasterColorCorrection( void ) { return m_hMasterController; } + +private: + + void InitMasterController( void ); + CHandle< CColorCorrection > m_hMasterController; +}; + +CColorCorrectionSystem *ColorCorrectionSystem( void ); +#endif + +#endif // COLOR_CORRECTION_H diff --git a/sp/src/game/server/colorcorrectionvolume.cpp b/sp/src/game/server/colorcorrectionvolume.cpp index a56cd533..abc55d75 100644 --- a/sp/src/game/server/colorcorrectionvolume.cpp +++ b/sp/src/game/server/colorcorrectionvolume.cpp @@ -48,7 +48,11 @@ public: private: +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( bool, m_bEnabled ); +#else bool m_bEnabled; +#endif bool m_bStartDisabled; CNetworkVar( float, m_Weight ); @@ -61,7 +65,11 @@ private: float m_LastExitWeight; float m_LastExitTime; +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( float, m_FadeDuration ); +#else float m_FadeDuration; +#endif }; LINK_ENTITY_TO_CLASS(color_correction_volume, CColorCorrectionVolume); @@ -90,6 +98,11 @@ END_DATADESC() IMPLEMENT_SERVERCLASS_ST_NOBASE(CColorCorrectionVolume, DT_ColorCorrectionVolume) +#ifdef MAPBASE // From Alien Swarm SDK + SendPropBool( SENDINFO(m_bEnabled) ), + SendPropFloat( SENDINFO(m_MaxWeight) ), + SendPropFloat( SENDINFO(m_FadeDuration) ), +#endif SendPropFloat( SENDINFO(m_Weight) ), SendPropString( SENDINFO(m_lookupFilename) ), END_SEND_TABLE() diff --git a/sp/src/game/server/env_tonemap_controller.cpp b/sp/src/game/server/env_tonemap_controller.cpp index bfd4f5a2..492b2046 100644 --- a/sp/src/game/server/env_tonemap_controller.cpp +++ b/sp/src/game/server/env_tonemap_controller.cpp @@ -5,6 +5,7 @@ //============================================================================= #include "cbase.h" +#include "env_tonemap_controller.h" #include "baseentity.h" #include "entityoutput.h" #include "convar.h" @@ -16,50 +17,6 @@ ConVar mat_hdr_tonemapscale( "mat_hdr_tonemapscale", "1.0", FCVAR_CHEAT, "The HDR tonemap scale. 1 = Use autoexposure, 0 = eyes fully closed, 16 = eyes wide open." ); -// 0 - eyes fully closed / fully black -// 1 - nominal -// 16 - eyes wide open / fully white - -//----------------------------------------------------------------------------- -// Purpose: Entity that controls player's tonemap -//----------------------------------------------------------------------------- -class CEnvTonemapController : public CPointEntity -{ - DECLARE_CLASS( CEnvTonemapController, CPointEntity ); -public: - DECLARE_DATADESC(); - DECLARE_SERVERCLASS(); - - void Spawn( void ); - int UpdateTransmitState( void ); - void UpdateTonemapScaleBlend( void ); - - // Inputs - void InputSetTonemapScale( inputdata_t &inputdata ); - void InputBlendTonemapScale( inputdata_t &inputdata ); - void InputSetTonemapRate( inputdata_t &inputdata ); - void InputSetAutoExposureMin( inputdata_t &inputdata ); - void InputSetAutoExposureMax( inputdata_t &inputdata ); - void InputUseDefaultAutoExposure( inputdata_t &inputdata ); - void InputSetBloomScale( inputdata_t &inputdata ); - void InputUseDefaultBloomScale( inputdata_t &inputdata ); - void InputSetBloomScaleRange( inputdata_t &inputdata ); - -private: - float m_flBlendTonemapStart; // HDR Tonemap at the start of the blend - float m_flBlendTonemapEnd; // Target HDR Tonemap at the end of the blend - float m_flBlendEndTime; // Time at which the blend ends - float m_flBlendStartTime; // Time at which the blend started - - CNetworkVar( bool, m_bUseCustomAutoExposureMin ); - CNetworkVar( bool, m_bUseCustomAutoExposureMax ); - CNetworkVar( bool, m_bUseCustomBloomScale ); - CNetworkVar( float, m_flCustomAutoExposureMin ); - CNetworkVar( float, m_flCustomAutoExposureMax ); - CNetworkVar( float, m_flCustomBloomScale); - CNetworkVar( float, m_flCustomBloomScaleMinimum); -}; - LINK_ENTITY_TO_CLASS( env_tonemap_controller, CEnvTonemapController ); BEGIN_DATADESC( CEnvTonemapController ) @@ -120,27 +77,72 @@ int CEnvTonemapController::UpdateTransmitState() return SetTransmitState( FL_EDICT_ALWAYS ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CEnvTonemapController::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "TonemapScale" ) ) + { + float flTonemapScale = atof( szValue ); + if (flTonemapScale != -1.0f) + { + mat_hdr_tonemapscale.SetValue( flTonemapScale ); + } + } + else if (FStrEq( szKeyName, "TonemapRate" )) + { + float flTonemapRate = atof( szValue ); + if (flTonemapRate != -1.0f) + { + ConVarRef mat_hdr_manual_tonemap_rate( "mat_hdr_manual_tonemap_rate" ); + if ( mat_hdr_manual_tonemap_rate.IsValid() ) + { + mat_hdr_manual_tonemap_rate.SetValue( flTonemapRate ); + } + } + } + else if (FStrEq( szKeyName, "AutoExposureMin" )) + { + float flAutoExposureMin = atof( szValue ); + if (flAutoExposureMin != 1.0f) + { + m_flCustomAutoExposureMin = flAutoExposureMin; + m_bUseCustomAutoExposureMin = true; + } + } + else if (FStrEq( szKeyName, "AutoExposureMax" )) + { + float flAutoExposureMax = atof( szValue ); + if (flAutoExposureMax != 1.0f) + { + m_flCustomAutoExposureMax = flAutoExposureMax; + m_bUseCustomAutoExposureMax = true; + } + } + else if (FStrEq( szKeyName, "BloomScale" )) + { + float flBloomScale = atof( szValue ); + if (flBloomScale != 1.0f) + { + m_flCustomBloomScale = flBloomScale; + m_flCustomBloomScaleMinimum = flBloomScale; + m_bUseCustomBloomScale = true; + } + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Set the tonemap scale to the specified value //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetTonemapScale( inputdata_t &inputdata ) { - //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. - //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. - if ( ( gpGlobals->maxClients > 1 ) ) - { - if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) - { -// DevMsg("activator is a player: InputSetTonemapScale\n"); - CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); - if (pPlayer) - { - pPlayer->InputSetTonemapScale( inputdata ); - return; - } - } - } - float flRemapped = inputdata.value.Float(); mat_hdr_tonemapscale.SetValue( flRemapped ); } @@ -150,10 +152,6 @@ void CEnvTonemapController::InputSetTonemapScale( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputBlendTonemapScale( inputdata_t &inputdata ) { - //Tony; TODO!!! -- tonemap scale blending does _not_ work properly in multiplayer.. - if ( ( gpGlobals->maxClients > 1 ) ) - return; - char parseString[255]; Q_strncpy(parseString, inputdata.value.String(), sizeof(parseString)); @@ -207,22 +205,6 @@ void CEnvTonemapController::InputSetBloomScaleRange( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetTonemapRate( inputdata_t &inputdata ) { - //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. - //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. - if ( ( gpGlobals->maxClients > 1 ) ) - { - if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) - { -// DevMsg("activator is a player: InputSetTonemapRate\n"); - CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); - if (pPlayer) - { - pPlayer->InputSetTonemapRate( inputdata ); - return; - } - } - } - // TODO: There should be a better way to do this. ConVarRef mat_hdr_manual_tonemap_rate( "mat_hdr_manual_tonemap_rate" ); if ( mat_hdr_manual_tonemap_rate.IsValid() ) @@ -254,22 +236,6 @@ void CEnvTonemapController::UpdateTonemapScaleBlend( void ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetAutoExposureMin( inputdata_t &inputdata ) { - //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. - //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. - if ( ( gpGlobals->maxClients > 1 ) ) - { - if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) - { -// DevMsg("activator is a player: InputSetAutoExposureMin\n"); - CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); - if (pPlayer) - { - pPlayer->InputSetAutoExposureMin( inputdata ); - return; - } - } - } - m_flCustomAutoExposureMin = inputdata.value.Float(); m_bUseCustomAutoExposureMin = true; } @@ -279,22 +245,6 @@ void CEnvTonemapController::InputSetAutoExposureMin( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetAutoExposureMax( inputdata_t &inputdata ) { - //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. - //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. - if ( ( gpGlobals->maxClients > 1 ) ) - { - if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) - { -// DevMsg("activator is a player: InputSetAutoExposureMax\n"); - CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); - if (pPlayer) - { - pPlayer->InputSetAutoExposureMax( inputdata ); - return; - } - } - } - m_flCustomAutoExposureMax = inputdata.value.Float(); m_bUseCustomAutoExposureMax = true; } @@ -304,22 +254,6 @@ void CEnvTonemapController::InputSetAutoExposureMax( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputUseDefaultAutoExposure( inputdata_t &inputdata ) { - //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. - //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. - if ( ( gpGlobals->maxClients > 1 ) ) - { - if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) - { -// DevMsg("activator is a player: InputUseDefaultAutoExposure\n"); - CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); - if (pPlayer) - { - pPlayer->InputUseDefaultAutoExposure( inputdata ); - return; - } - } - } - m_bUseCustomAutoExposureMin = false; m_bUseCustomAutoExposureMax = false; } @@ -329,22 +263,6 @@ void CEnvTonemapController::InputUseDefaultAutoExposure( inputdata_t &inputdata //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetBloomScale( inputdata_t &inputdata ) { - //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. - //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. - if ( ( gpGlobals->maxClients > 1 ) ) - { - if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) - { -// DevMsg("activator is a player: InputSetBloomScale\n"); - CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); - if (pPlayer) - { - pPlayer->InputSetBloomScale( inputdata ); - return; - } - } - } - m_flCustomBloomScale = inputdata.value.Float(); m_flCustomBloomScaleMinimum = m_flCustomBloomScale; m_bUseCustomBloomScale = true; @@ -355,21 +273,111 @@ void CEnvTonemapController::InputSetBloomScale( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputUseDefaultBloomScale( inputdata_t &inputdata ) { - //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. - //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. - if ( ( gpGlobals->maxClients > 1 ) ) - { - if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) - { -// DevMsg("activator is a player: InputUseDefaultBloomScale\n"); - CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); - if (pPlayer) - { - pPlayer->InputUseDefaultBloomScale( inputdata ); - return; - } - } - } - m_bUseCustomBloomScale = false; } + +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +LINK_ENTITY_TO_CLASS( trigger_tonemap, CTonemapTrigger ); + +BEGIN_DATADESC( CTonemapTrigger ) + DEFINE_KEYFIELD( m_tonemapControllerName, FIELD_STRING, "TonemapName" ), +END_DATADESC() + + +//-------------------------------------------------------------------------------------------------------- +void CTonemapTrigger::Spawn( void ) +{ + AddSpawnFlags( SF_TRIGGER_ALLOW_CLIENTS ); + + BaseClass::Spawn(); + InitTrigger(); + + m_hTonemapController = gEntList.FindEntityByName( NULL, m_tonemapControllerName ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CTonemapTrigger::StartTouch( CBaseEntity *other ) +{ + if ( !PassesTriggerFilters( other ) ) + return; + + BaseClass::StartTouch( other ); + + CBasePlayer *player = ToBasePlayer( other ); + if ( !player ) + return; + + player->OnTonemapTriggerStartTouch( this ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CTonemapTrigger::EndTouch( CBaseEntity *other ) +{ + if ( !PassesTriggerFilters( other ) ) + return; + + BaseClass::EndTouch( other ); + + CBasePlayer *player = ToBasePlayer( other ); + if ( !player ) + return; + + player->OnTonemapTriggerEndTouch( this ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Clear out the tonemap controller. +//----------------------------------------------------------------------------- +void CTonemapSystem::LevelInitPreEntity( void ) +{ + m_hMasterController = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: On level load find the master fog controller. If no controller is +// set as Master, use the first fog controller found. +//----------------------------------------------------------------------------- +void CTonemapSystem::LevelInitPostEntity( void ) +{ + // Overall master controller + CEnvTonemapController *pTonemapController = NULL; + do + { + pTonemapController = static_cast( gEntList.FindEntityByClassname( pTonemapController, "env_tonemap_controller" ) ); + if ( pTonemapController ) + { + if ( m_hMasterController == NULL ) + { + m_hMasterController = pTonemapController; + } + else + { + if ( pTonemapController->IsMaster() ) + { + m_hMasterController = pTonemapController; + } + } + } + } while ( pTonemapController ); + + +} + + +//-------------------------------------------------------------------------------------------------------- +CTonemapSystem s_TonemapSystem( "TonemapSystem" ); + + +//-------------------------------------------------------------------------------------------------------- +CTonemapSystem *TheTonemapSystem( void ) +{ + return &s_TonemapSystem; +} + + +//-------------------------------------------------------------------------------------------------------- +#endif diff --git a/sp/src/game/server/env_tonemap_controller.h b/sp/src/game/server/env_tonemap_controller.h new file mode 100644 index 00000000..94e3e0f4 --- /dev/null +++ b/sp/src/game/server/env_tonemap_controller.h @@ -0,0 +1,140 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Note that this header exists in the Alien Swarm SDK, but not in stock Source SDK 2013. +// Although technically a new Mapbase file, it only serves to move otherwise identical code, +// so most code and repo conventions will pretend it was always there. +// +// -------------------------------------------------------------------- +// +// Purpose: +// +//=============================================================================// + +#ifndef ENV_TONEMAP_CONTROLLER_H +#define ENV_TONEMAP_CONTROLLER_H + +#include "triggers.h" + +// 0 - eyes fully closed / fully black +// 1 - nominal +// 16 - eyes wide open / fully white + +#ifdef MAPBASE // From Alien Swarm SDK +// Spawn Flags +#define SF_TONEMAP_MASTER 0x0001 +#endif + +//----------------------------------------------------------------------------- +// Purpose: Entity that controls player's tonemap +//----------------------------------------------------------------------------- +class CEnvTonemapController : public CPointEntity +{ + DECLARE_CLASS( CEnvTonemapController, CPointEntity ); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + void Spawn( void ); + int UpdateTransmitState( void ); + void UpdateTonemapScaleBlend( void ); + +#ifdef MAPBASE + bool IsMaster( void ) const { return HasSpawnFlags( SF_TONEMAP_MASTER ); } // From Alien Swarm SDK + + bool KeyValue( const char *szKeyName, const char *szValue ); +#endif + + // Inputs + void InputSetTonemapScale( inputdata_t &inputdata ); + void InputBlendTonemapScale( inputdata_t &inputdata ); + void InputSetTonemapRate( inputdata_t &inputdata ); + void InputSetAutoExposureMin( inputdata_t &inputdata ); + void InputSetAutoExposureMax( inputdata_t &inputdata ); + void InputUseDefaultAutoExposure( inputdata_t &inputdata ); + void InputSetBloomScale( inputdata_t &inputdata ); + void InputUseDefaultBloomScale( inputdata_t &inputdata ); + void InputSetBloomScaleRange( inputdata_t &inputdata ); + +private: + float m_flBlendTonemapStart; // HDR Tonemap at the start of the blend + float m_flBlendTonemapEnd; // Target HDR Tonemap at the end of the blend + float m_flBlendEndTime; // Time at which the blend ends + float m_flBlendStartTime; // Time at which the blend started + +#ifdef MAPBASE // From Alien Swarm SDK +public: +#endif + CNetworkVar( bool, m_bUseCustomAutoExposureMin ); + CNetworkVar( bool, m_bUseCustomAutoExposureMax ); + CNetworkVar( bool, m_bUseCustomBloomScale ); + CNetworkVar( float, m_flCustomAutoExposureMin ); + CNetworkVar( float, m_flCustomAutoExposureMax ); + CNetworkVar( float, m_flCustomBloomScale); + CNetworkVar( float, m_flCustomBloomScaleMinimum); +}; + +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +class CTonemapTrigger : public CBaseTrigger +{ +public: + DECLARE_CLASS( CTonemapTrigger, CBaseTrigger ); + DECLARE_DATADESC(); + + virtual void Spawn( void ); + virtual void StartTouch( CBaseEntity *other ); + virtual void EndTouch( CBaseEntity *other ); + + CBaseEntity *GetTonemapController( void ) const; + +private: + string_t m_tonemapControllerName; + EHANDLE m_hTonemapController; +}; + + +//-------------------------------------------------------------------------------------------------------- +inline CBaseEntity *CTonemapTrigger::GetTonemapController( void ) const +{ + return m_hTonemapController.Get(); +} + + +//-------------------------------------------------------------------------------------------------------- +// Tonemap Controller System. +class CTonemapSystem : public CAutoGameSystem +{ +public: + + // Creation/Init. + CTonemapSystem( char const *name ) : CAutoGameSystem( name ) + { + m_hMasterController = NULL; + } + + ~CTonemapSystem() + { + m_hMasterController = NULL; + } + + virtual void LevelInitPreEntity(); + virtual void LevelInitPostEntity(); + CBaseEntity *GetMasterTonemapController( void ) const; + +private: + + EHANDLE m_hMasterController; +}; + + +//-------------------------------------------------------------------------------------------------------- +inline CBaseEntity *CTonemapSystem::GetMasterTonemapController( void ) const +{ + return m_hMasterController.Get(); +} + +//-------------------------------------------------------------------------------------------------------- +CTonemapSystem *TheTonemapSystem( void ); +#endif + +#endif //ENV_TONEMAP_CONTROLLER_H \ No newline at end of file diff --git a/sp/src/game/server/fogvolume.cpp b/sp/src/game/server/fogvolume.cpp new file mode 100644 index 00000000..f2f9a718 --- /dev/null +++ b/sp/src/game/server/fogvolume.cpp @@ -0,0 +1,153 @@ +//-------------------------------------------------------------------------------------------------------- +// Copyright (c) 2007 Turtle Rock Studios, Inc. - All Rights Reserved + +#include "cbase.h" +#include "fogvolume.h" +#include "collisionutils.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +CUtlVector< CFogVolume * > TheFogVolumes; + +ConVar fog_volume_debug( "fog_volume_debug", "0", 0, "If enabled, prints diagnostic information about the current fog volume" ); + +//-------------------------------------------------------------------------------------------------------- +LINK_ENTITY_TO_CLASS(fog_volume, CFogVolume); + +BEGIN_DATADESC( CFogVolume ) + + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + + DEFINE_KEYFIELD( m_fogName, FIELD_STRING, "FogName" ), + DEFINE_KEYFIELD( m_postProcessName, FIELD_STRING, "PostProcessName" ), + DEFINE_KEYFIELD( m_colorCorrectionName, FIELD_STRING, "ColorCorrectionName" ), + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + DEFINE_FIELD( m_hFogController, FIELD_EHANDLE ), + DEFINE_FIELD( m_hPostProcessController, FIELD_EHANDLE ), + DEFINE_FIELD( m_hColorCorrectionController, FIELD_EHANDLE ), + +END_DATADESC() + + +//-------------------------------------------------------------------------------------------------------- +CFogVolume *CFogVolume::FindFogVolumeForPosition( const Vector &position ) +{ + CFogVolume *fogVolume = NULL; + for ( int i=0; iCollisionProp()->WorldToCollisionSpace( position, &vecRelativeCenter ); + if ( IsBoxIntersectingSphere( fogVolume->CollisionProp()->OBBMins(), fogVolume->CollisionProp()->OBBMaxs(), vecRelativeCenter, 1.0f ) ) + { + break; + } + fogVolume = NULL; + } + + // This doesn't work well if there are multiple players or multiple fog volume queries per frame; might want to relocate this if that's the case + if ( fog_volume_debug.GetBool() ) + { + if ( fogVolume ) + { + char fogVolumeName[256]; + fogVolume->GetKeyValue( "targetname", fogVolumeName, 256 ); + engine->Con_NPrintf( 0, "Fog Volume ""%s"" found at position (%f %f %f)", fogVolumeName, position.x, position.y, position.z ); + engine->Con_NPrintf( 1, "Fog: %s, post process: %s, color correct: %s", fogVolume->m_fogName, fogVolume->m_postProcessName, fogVolume->m_colorCorrectionName ); + } + else + { + engine->Con_NPrintf( 0, "No Fog Volume found at given position (%f %f %f)", position.x, position.y, position.z ); + } + } + + return fogVolume; +} + + +//-------------------------------------------------------------------------------------------------------- +CFogVolume::CFogVolume() : + BaseClass(), + m_bDisabled( false ), + m_bInFogVolumesList( false ) +{ +} + + +//-------------------------------------------------------------------------------------------------------- +CFogVolume::~CFogVolume() +{ + RemoveFromGlobalList(); +} + + +//-------------------------------------------------------------------------------------------------------- +void CFogVolume::Spawn( void ) +{ + BaseClass::Spawn(); + + SetSolid( SOLID_BSP ); + SetSolidFlags( FSOLID_NOT_SOLID ); + SetModel( STRING( GetModelName() ) ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CFogVolume::AddToGlobalList() +{ + if ( !m_bInFogVolumesList ) + { + TheFogVolumes.AddToTail( this ); + m_bInFogVolumesList = true; + } +} + + +//-------------------------------------------------------------------------------------------------------- +void CFogVolume::RemoveFromGlobalList() +{ + if ( m_bInFogVolumesList ) + { + TheFogVolumes.FindAndRemove( this ); + m_bInFogVolumesList = false; + } +} + + +//---------------------------------------------------------------------------- +void CFogVolume::InputEnable( inputdata_t &data ) +{ + m_bDisabled = false; + AddToGlobalList(); +} + + +//---------------------------------------------------------------------------- +void CFogVolume::InputDisable( inputdata_t &data ) +{ + m_bDisabled = true; + RemoveFromGlobalList(); +} + + +//---------------------------------------------------------------------------- +// Called when the level loads or is restored +//---------------------------------------------------------------------------- +void CFogVolume::Activate() +{ + BaseClass::Activate(); + + m_hFogController = dynamic_cast< CFogController* >( gEntList.FindEntityByName( NULL, m_fogName ) ); + m_hPostProcessController = dynamic_cast< CPostProcessController* >( gEntList.FindEntityByName( NULL, m_postProcessName ) ); + m_hColorCorrectionController = dynamic_cast< CColorCorrection* >( gEntList.FindEntityByName( NULL, m_colorCorrectionName ) ); + + if ( !m_bDisabled ) + { + AddToGlobalList(); + } +} diff --git a/sp/src/game/server/fogvolume.h b/sp/src/game/server/fogvolume.h new file mode 100644 index 00000000..6bd5880a --- /dev/null +++ b/sp/src/game/server/fogvolume.h @@ -0,0 +1,74 @@ +//-------------------------------------------------------------------------------------------------------- +// Copyright (c) 2007 Turtle Rock Studios, Inc. - All Rights Reserved + +#ifndef FOG_VOLUME_H +#define FOG_VOLUME_H + +#ifdef _WIN32 +#pragma once +#endif + + +class CFogController; +class CPostProcessController; +class CColorCorrection; + + +//-------------------------------------------------------------------------------------------------------- +// Fog volume entity +class CFogVolume : public CServerOnlyEntity +{ + DECLARE_CLASS( CFogVolume, CServerOnlyEntity ); + DECLARE_DATADESC(); + +public: + CFogVolume(); + virtual ~CFogVolume(); + virtual void Spawn( void ); + virtual void Activate(); + + static CFogVolume *FindFogVolumeForPosition( const Vector &position ); + + const char *GetFogControllerName() const + { + return STRING( m_fogName ); + } + + CFogController* GetFogController( ) const + { + return m_hFogController.Get(); + } + + CPostProcessController* GetPostProcessController( ) const + { + return m_hPostProcessController.Get(); + } + + CColorCorrection* GetColorCorrectionController( ) const + { + return m_hColorCorrectionController.Get(); + } + + void InputEnable( inputdata_t &data ); + void InputDisable( inputdata_t &data ); + +private: + string_t m_fogName; + string_t m_postProcessName; + string_t m_colorCorrectionName; + + CHandle< CFogController > m_hFogController; + CHandle< CPostProcessController > m_hPostProcessController; + CHandle< CColorCorrection > m_hColorCorrectionController; + + bool m_bDisabled; + bool m_bInFogVolumesList; + + void AddToGlobalList(); + void RemoveFromGlobalList(); +}; + +extern CUtlVector< CFogVolume * > TheFogVolumes; + + +#endif // FOG_VOLUME_H \ No newline at end of file diff --git a/sp/src/game/server/player.cpp b/sp/src/game/server/player.cpp index 5280b60a..524b1e75 100644 --- a/sp/src/game/server/player.cpp +++ b/sp/src/game/server/player.cpp @@ -59,6 +59,10 @@ #include "env_zoom.h" #include "rumble_shared.h" #include "gamestats.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "env_tonemap_controller.h" +#include "fogvolume.h" +#endif #include "npcevent.h" #include "datacache/imdlcache.h" #include "hintsystem.h" @@ -459,8 +463,13 @@ BEGIN_DATADESC( CBasePlayer ) // Inputs DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetHUDVisibility", InputSetHUDVisibility ), - DEFINE_INPUTFUNC( FIELD_STRING, "SetFogController", InputSetFogController ), +#ifdef MAPBASE // From Alien Swarm SDK (kind of) + DEFINE_INPUTFUNC( FIELD_INPUT, "SetFogController", InputSetFogController ), DEFINE_INPUTFUNC( FIELD_INPUT, "SetPostProcessController", InputSetPostProcessController ), + DEFINE_INPUTFUNC( FIELD_INPUT, "SetColorCorrectionController", InputSetColorCorrectionController ), +#else + DEFINE_INPUTFUNC( FIELD_STRING, "SetFogController", InputSetFogController ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "HandleMapEvent", InputHandleMapEvent ), #ifdef MAPBASE DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetSuppressAttacks", InputSetSuppressAttacks ), @@ -474,9 +483,10 @@ BEGIN_DATADESC( CBasePlayer ) DEFINE_FIELD( m_nNumCrateHudHints, FIELD_INTEGER ), +#ifdef MAPBASE // From Alien Swarm SDK DEFINE_FIELD( m_hPostProcessCtrl, FIELD_EHANDLE ), - - + DEFINE_FIELD( m_hColorCorrectionCtrl, FIELD_EHANDLE ), +#endif // DEFINE_FIELD( m_nBodyPitchPoseParam, FIELD_INTEGER ), // DEFINE_ARRAY( m_StepSoundCache, StepSoundCache_t, 2 ), @@ -4668,6 +4678,55 @@ void CBasePlayer::ForceOrigin( const Vector &vecOrigin ) m_vForcedOrigin = vecOrigin; } +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::OnTonemapTriggerStartTouch( CTonemapTrigger *pTonemapTrigger ) +{ + m_hTriggerTonemapList.FindAndRemove( pTonemapTrigger ); + m_hTriggerTonemapList.AddToTail( pTonemapTrigger ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::OnTonemapTriggerEndTouch( CTonemapTrigger *pTonemapTrigger ) +{ + m_hTriggerTonemapList.FindAndRemove( pTonemapTrigger ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::UpdateTonemapController( void ) +{ + // For now, Mapbase uses Tony Sergi's Source 2007 tonemap fixes. + // Alien Swarm SDK tonemap controller code copies the parameters instead. + + CEnvTonemapController *pController = NULL; + + if (m_hTriggerTonemapList.Count() > 0) + { + pController = static_cast(m_hTriggerTonemapList.Tail()->GetTonemapController()); + } + else if (TheTonemapSystem()->GetMasterTonemapController()) + { + pController = static_cast(TheTonemapSystem()->GetMasterTonemapController()); + } + + if (pController) + { + //m_hTonemapController = TheTonemapSystem()->GetMasterTonemapController(); + + if (pController->m_bUseCustomAutoExposureMax) + m_Local.m_TonemapParams.m_flAutoExposureMax = pController->m_flCustomAutoExposureMax; + + if (pController->m_bUseCustomAutoExposureMin) + m_Local.m_TonemapParams.m_flAutoExposureMin = pController->m_flCustomAutoExposureMin; + + if (pController->m_bUseCustomBloomScale) + m_Local.m_TonemapParams.m_flBloomScale = pController->m_flCustomBloomScale; + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -4675,6 +4734,11 @@ void CBasePlayer::PostThink() { m_vecSmoothedVelocity = m_vecSmoothedVelocity * SMOOTHING_FACTOR + GetAbsVelocity() * ( 1 - SMOOTHING_FACTOR ); +#ifdef MAPBASE // From Alien Swarm SDK + UpdateTonemapController(); + UpdateFXVolume(); +#endif + if ( !g_fGameOver && !m_iPlayerLocked ) { if ( IsAlive() ) @@ -5151,7 +5215,9 @@ void CBasePlayer::Spawn( void ) // Initialize the fog and postprocess controllers. InitFogController(); +#ifdef MAPBASE // From Alien Swarm SDK InitPostProcessController(); +#endif m_DmgTake = 0; m_DmgSave = 0; @@ -8716,8 +8782,11 @@ void SendProxy_ShiftPlayerSpawnflags( const SendProp *pProp, const void *pStruct SendPropArray ( SendPropEHandle( SENDINFO_ARRAY( m_hViewModel ) ), m_hViewModel ), SendPropString (SENDINFO(m_szLastPlaceName) ), +#ifdef MAPBASE // From Alien Swarm SDK // Postprocess data - SendPropEHandle( SENDINFO( m_hPostProcessCtrl ) ), + SendPropEHandle ( SENDINFO(m_hPostProcessCtrl) ), + SendPropEHandle ( SENDINFO(m_hColorCorrectionCtrl) ), +#endif #if defined USES_ECON_ITEMS SendPropUtlVector( SENDINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, SendPropEHandle( NULL, 0 ) ), @@ -9433,7 +9502,19 @@ void CBasePlayer::InputSetSuppressAttacks( inputdata_t &inputdata ) void CBasePlayer::InputSetFogController( inputdata_t &inputdata ) { // Find the fog controller with the given name. +#ifdef MAPBASE // From Alien Swarm SDK + CFogController *pFogController = NULL; + if ( inputdata.value.FieldType() == FIELD_EHANDLE ) + { + pFogController = dynamic_cast( inputdata.value.Entity().Get() ); + } + else + { + pFogController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); + } +#else CFogController *pFogController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); +#endif if ( pFogController ) { m_Local.m_PlayerFog.m_hCtrl.Set( pFogController ); @@ -9449,6 +9530,7 @@ void CBasePlayer::InitFogController( void ) m_Local.m_PlayerFog.m_hCtrl = FogSystem()->GetMasterFogController(); } +#ifdef MAPBASE // From Alien Swarm SDK //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- @@ -9461,25 +9543,57 @@ void CBasePlayer::InitPostProcessController( void ) //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- -void CBasePlayer::InputSetPostProcessController( inputdata_t& inputdata ) +void CBasePlayer::InitColorCorrectionController( void ) { - // Find the postprocess controller with the given name. - CPostProcessController* pController = NULL; - if (inputdata.value.FieldType() == FIELD_EHANDLE) + m_hColorCorrectionCtrl = ColorCorrectionSystem()->GetMasterColorCorrection(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InputSetPostProcessController( inputdata_t &inputdata ) +{ + // Find the fog controller with the given name. + CPostProcessController *pController = NULL; + if ( inputdata.value.FieldType() == FIELD_EHANDLE ) { - pController = dynamic_cast(inputdata.value.Entity().Get()); + pController = dynamic_cast( inputdata.value.Entity().Get() ); } else { - pController = dynamic_cast(gEntList.FindEntityByName( NULL, inputdata.value.String() )); + pController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); } - if (pController) + if ( pController ) { m_hPostProcessCtrl.Set( pController ); } } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InputSetColorCorrectionController( inputdata_t &inputdata ) +{ + // Find the fog controller with the given name. + CColorCorrection *pController = NULL; + if ( inputdata.value.FieldType() == FIELD_EHANDLE ) + { + pController = dynamic_cast( inputdata.value.Entity().Get() ); + } + else + { + pController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); + } + + if ( pController ) + { + m_hColorCorrectionCtrl.Set( pController ); + } + +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - @@ -10150,4 +10264,71 @@ uint64 CBasePlayer::GetSteamIDAsUInt64( void ) return steamIDForPlayer.ConvertToUint64(); return 0; } -#endif // NO_STEAM \ No newline at end of file +#endif // NO_STEAM + +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::UpdateFXVolume( void ) +{ + CFogController *pFogController = NULL; + CPostProcessController *pPostProcessController = NULL; + CColorCorrection* pColorCorrectionEnt = NULL; + + Vector eyePos; + CBaseEntity *pViewEntity = GetViewEntity(); + if ( pViewEntity ) + { + eyePos = pViewEntity->GetAbsOrigin(); + } + else + { + eyePos = EyePosition(); + } + + CFogVolume *pFogVolume = CFogVolume::FindFogVolumeForPosition( eyePos ); + if ( pFogVolume ) + { + pFogController = pFogVolume->GetFogController(); + pPostProcessController = pFogVolume->GetPostProcessController(); + pColorCorrectionEnt = pFogVolume->GetColorCorrectionController(); + + if ( !pFogController ) + { + pFogController = FogSystem()->GetMasterFogController(); + } + + if ( !pPostProcessController ) + { + pPostProcessController = PostProcessSystem()->GetMasterPostProcessController(); + } + + if ( !pColorCorrectionEnt ) + { + pColorCorrectionEnt = ColorCorrectionSystem()->GetMasterColorCorrection(); + } + } + else if ( TheFogVolumes.Count() > 0 ) + { + // If we're not in a fog volume, clear our fog volume, if the map has any. + // This will get us back to using the master fog controller. + pFogController = FogSystem()->GetMasterFogController(); + pPostProcessController = PostProcessSystem()->GetMasterPostProcessController(); + pColorCorrectionEnt = ColorCorrectionSystem()->GetMasterColorCorrection(); + } + + if ( pFogController && m_Local.m_PlayerFog.m_hCtrl.Get() != pFogController ) + { + m_Local.m_PlayerFog.m_hCtrl.Set( pFogController ); + } + + if ( pPostProcessController ) + { + m_hPostProcessCtrl.Set( pPostProcessController ); + } + + if ( pColorCorrectionEnt ) + { + m_hColorCorrectionCtrl.Set( pColorCorrectionEnt ); + } +} +#endif diff --git a/sp/src/game/server/player.h b/sp/src/game/server/player.h index bda4a5fe..05bf335b 100644 --- a/sp/src/game/server/player.h +++ b/sp/src/game/server/player.h @@ -88,6 +88,10 @@ class CNavArea; class CHintSystem; class CAI_Expresser; +#ifdef MAPBASE // From Alien Swarm SDK +class CTonemapTrigger; +#endif + #if defined USES_ECON_ITEMS class CEconWearable; #endif // USES_ECON_ITEMS @@ -658,6 +662,8 @@ public: #ifdef MAPBASE bool ShouldUseVisibilityCache( CBaseEntity *pEntity ); + + void UpdateFXVolume( void ); // From Alien Swarm SDK #endif public: @@ -884,9 +890,18 @@ public: void InitFogController( void ); void InputSetFogController( inputdata_t &inputdata ); +#ifdef MAPBASE // From Alien Swarm SDK + void OnTonemapTriggerStartTouch( CTonemapTrigger *pTonemapTrigger ); + void OnTonemapTriggerEndTouch( CTonemapTrigger *pTonemapTrigger ); + CUtlVector< CHandle< CTonemapTrigger > > m_hTriggerTonemapList; + CNetworkHandle( CPostProcessController, m_hPostProcessCtrl ); // active postprocessing controller + CNetworkHandle( CColorCorrection, m_hColorCorrectionCtrl ); // active FXVolume color correction void InitPostProcessController( void ); - void InputSetPostProcessController( inputdata_t& inputdata ); + void InputSetPostProcessController( inputdata_t &inputdata ); + void InitColorCorrectionController( void ); + void InputSetColorCorrectionController( inputdata_t &inputdata ); +#endif // Used by env_soundscape_triggerable to manage when the player is touching multiple // soundscape triggers simultaneously. @@ -1031,6 +1046,13 @@ protected: float m_fReplayEnd; // time to stop replay mode int m_iReplayEntity; // follow this entity in replay +#ifdef MAPBASE // From Alien Swarm SDK + // For now, Mapbase uses Tony Sergi's Source 2007 tonemap fixes. + // Alien Swarm SDK tonemap controller code copies the parameters instead. + virtual void UpdateTonemapController( void ); + //CNetworkHandle( CBaseEntity, m_hTonemapController ); +#endif + private: void HandleFuncTrain(); diff --git a/sp/src/game/server/playerlocaldata.h b/sp/src/game/server/playerlocaldata.h index 587dbd1a..f9ceef70 100644 --- a/sp/src/game/server/playerlocaldata.h +++ b/sp/src/game/server/playerlocaldata.h @@ -15,7 +15,10 @@ #include "playernet_vars.h" #include "networkvar.h" #include "fogcontroller.h" +#ifdef MAPBASE // From Alien Swarm SDK #include "postprocesscontroller.h" +#include "colorcorrection.h" +#endif //----------------------------------------------------------------------------- // Purpose: Player specific data ( sent only to local player, too ) diff --git a/sp/src/game/server/server_mapbase.vpc b/sp/src/game/server/server_mapbase.vpc index 523ba827..80ece7cf 100644 --- a/sp/src/game/server/server_mapbase.vpc +++ b/sp/src/game/server/server_mapbase.vpc @@ -30,6 +30,8 @@ $Project $File "env_dof_controller.h" $File "logic_playmovie.cpp" $File "movie_display.cpp" + $File "fogvolume.cpp" + $File "fogvolume.h" $File "ai_expresserfollowup.cpp" [$NEW_RESPONSE_SYSTEM] $File "ai_speechqueue.cpp" [$NEW_RESPONSE_SYSTEM] $File "ai_speechqueue.h" [$NEW_RESPONSE_SYSTEM]