From 87cd9b24bb78e2044480a59ff0ee9d6754fa70c6 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Thu, 17 Dec 2020 03:38:23 +0000 Subject: [PATCH] Mapbase v6.1 - Added postprocess_controller entity from later versions of Source - Added env_dof_controller entity from later versions of Source - Added SDK_Engine_Post and DepthOfField shaders from the Momentum repo/Alien Swarm SDK - Fixed auto-breaking game_text/choreo text not null terminating - Fixed console groups showing up at the wrong developer levels - Added more mesages to console groups, including a new "NPC AI" console group - Fixed typos and added elaboration in various cvars, console messages, etc. - Fixed npc_metropolice not using frag grenades correctly when allowed to use them - Fixed npc_metropolice not registering stitching squad slots in AI - Fixed SetModel input late precache warning - Fixed env_global_light angles resetting upon loading a save - Fixed an issue with ScriptKeyValuesRead using the wrong name and having a memory leak - Allowed VScript functions which return null strings to actually return null instead of empty strings - Added VScript member variable documentation - Fixed VScript documentation lines sometimes mixing together - Fixed VScript singletons having a ! at the beginning of descriptions - Added Color struct to VScript and allowed color-related inputs to use it - Added more VScript functions for weapons, ammo, ragdolling, and response contexts - Added GameRules singleton for VScript - Exposed AI interaction system to VScript - Recovered some lost documentation from older revisions of the Mapbase wiki - Added a way to get the current game's load type in VScript - Fixed Precache/SpawnEntityFromTable not accounting for a few important field types - Added VScript functions for getting a player's eye vectors - Fixed a crash caused by removing the active weapon of a Combine soldier while it's firing - Changed the way metrocops deploy their manhacks so they could use their manhack death response properly - Fixed "Use Server" keyvalue on game_convar_mod not working - Adjusted CAI_Expresser in VScript --- README | 1 + sp/src/game/client/c_baseplayer.cpp | 10 + sp/src/game/client/c_baseplayer.h | 6 + sp/src/game/client/c_effects.cpp | 2 +- sp/src/game/client/c_env_dof_controller.cpp | 88 +++ .../game/client/c_postprocesscontroller.cpp | 63 ++ sp/src/game/client/c_postprocesscontroller.h | 33 + sp/src/game/client/client_mapbase.vpc | 3 + sp/src/game/client/clientmode_shared.cpp | 80 +++ sp/src/game/client/clientmode_shared.h | 7 + sp/src/game/client/message.cpp | 5 +- sp/src/game/client/viewpostprocess.cpp | 589 +++++++++++++--- sp/src/game/client/viewpostprocess.h | 14 +- sp/src/game/client/viewrender.cpp | 16 +- sp/src/game/server/ai_basenpc.cpp | 35 +- sp/src/game/server/ai_basenpc.h | 10 + sp/src/game/server/ai_basenpc_schedule.cpp | 38 +- sp/src/game/server/ai_speech.cpp | 15 +- sp/src/game/server/ai_speech.h | 3 +- sp/src/game/server/ai_squad.cpp | 10 +- sp/src/game/server/baseanimating.cpp | 10 +- sp/src/game/server/basecombatcharacter.cpp | 40 +- sp/src/game/server/basecombatcharacter.h | 8 + sp/src/game/server/baseentity.cpp | 153 ++++- sp/src/game/server/baseentity.h | 14 +- sp/src/game/server/env_dof_controller.cpp | 186 +++++ sp/src/game/server/env_dof_controller.h | 56 ++ sp/src/game/server/env_global_light.cpp | 23 +- sp/src/game/server/hl2/item_itemcrate.cpp | 69 ++ sp/src/game/server/hl2/npc_attackchopper.cpp | 23 + sp/src/game/server/hl2/npc_combine.cpp | 9 + sp/src/game/server/hl2/npc_metropolice.cpp | 25 +- .../game/server/mapbase/SystemConvarMod.cpp | 22 +- sp/src/game/server/player.cpp | 44 ++ sp/src/game/server/player.h | 8 + sp/src/game/server/playerlocaldata.h | 1 + sp/src/game/server/postprocesscontroller.cpp | 207 ++++++ sp/src/game/server/postprocesscontroller.h | 80 +++ sp/src/game/server/server_mapbase.vpc | 4 + sp/src/game/server/variant_t.cpp | 21 +- sp/src/game/server/vscript_server.cpp | 8 + sp/src/game/shared/ammodef.cpp | 2 + sp/src/game/shared/ammodef.h | 5 + .../game/shared/basecombatweapon_shared.cpp | 2 + sp/src/game/shared/gamerules.cpp | 61 ++ sp/src/game/shared/mapbase/mapbase_shared.cpp | 2 +- .../shared/mapbase/vscript_consts_shared.cpp | 79 ++- .../game/shared/mapbase/vscript_funcs_hl2.cpp | 7 +- .../shared/mapbase/vscript_funcs_shared.cpp | 73 +- .../shared/mapbase/vscript_funcs_shared.h | 2 +- .../shared/mapbase/vscript_singletons.cpp | 4 +- sp/src/game/shared/postprocess_shared.h | 54 ++ sp/src/game/shared/util_shared.h | 16 + .../stdshaders/blurgaussian_3x3_ps2x.fxc | 22 + .../stdshaders/depth_of_field_ps20b.fxc | 137 ++++ .../stdshaders/depth_of_field_vs20.fxc | 29 + .../stdshaders/depthoffield_dx9.cpp | 280 ++++++++ .../stdshaders/engine_post_dx9.cpp | 636 ++++++++++++++++++ .../fxctmp9/blurgaussian_3x3_ps20.inc | 33 + .../fxctmp9/blurgaussian_3x3_ps20b.inc | 33 + .../fxctmp9/depth_of_field_ps20b.inc | 60 ++ .../fxctmp9/depth_of_field_vs20.inc | 33 + .../stdshaders/fxctmp9/engine_post_ps20b.inc | 362 ++++++++++ .../fxctmp9_tmp/blurgaussian_3x3_ps20.inc | 33 + .../fxctmp9_tmp/blurgaussian_3x3_ps20b.inc | 33 + .../fxctmp9_tmp/depth_of_field_ps20b.inc | 60 ++ .../fxctmp9_tmp/depth_of_field_vs20.inc | 33 + .../fxctmp9_tmp/engine_post_ps20b.inc | 362 ++++++++++ .../stdshaders/game_shader_dx9_mapbase.vpc | 3 + .../lightmappedgeneric_dx9_helper.cpp | 2 +- .../stdshaders/stdshader_dx9_20b.txt | 7 + sp/src/public/tier1/mapbase_con_groups.h | 1 + sp/src/public/vphysics_interface.h | 14 + sp/src/public/vscript/ivscript.h | 24 + sp/src/tier1/mapbase_con_groups.cpp | 8 +- sp/src/utils/vbsp/map.cpp | 4 +- sp/src/vscript/vscript_bindings_base.cpp | 105 ++- sp/src/vscript/vscript_bindings_base.h | 13 + sp/src/vscript/vscript_bindings_math.cpp | 5 + sp/src/vscript/vscript_squirrel.cpp | 68 +- sp/src/vscript/vscript_squirrel.nut | 183 ++--- thirdpartylegalnotices.txt | 4 +- 82 files changed, 4596 insertions(+), 337 deletions(-) create mode 100644 sp/src/game/client/c_env_dof_controller.cpp create mode 100644 sp/src/game/client/c_postprocesscontroller.cpp create mode 100644 sp/src/game/client/c_postprocesscontroller.h create mode 100644 sp/src/game/server/env_dof_controller.cpp create mode 100644 sp/src/game/server/env_dof_controller.h create mode 100644 sp/src/game/server/postprocesscontroller.cpp create mode 100644 sp/src/game/server/postprocesscontroller.h create mode 100644 sp/src/game/shared/postprocess_shared.h create mode 100644 sp/src/materialsystem/stdshaders/blurgaussian_3x3_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/depth_of_field_ps20b.fxc create mode 100644 sp/src/materialsystem/stdshaders/depth_of_field_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/depthoffield_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/engine_post_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20b.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_ps20b.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_vs20.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9/engine_post_ps20b.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20b.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_ps20b.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_vs20.inc create mode 100644 sp/src/materialsystem/stdshaders/fxctmp9_tmp/engine_post_ps20b.inc diff --git a/README b/README index 923f02bb..9d4193dc 100644 --- a/README +++ b/README @@ -53,6 +53,7 @@ Here's a list of Mapbase's other known external code sources: - https://github.com/KyleGospo/City-17-Episode-One-Source (Brush phong and projected texture changes, included indirectly via Insolence repo) - https://github.com/DownFall-Team/DownFall (Multiple skybox code and fix for ent_fire delay not using floats; Also used as a guide to port certain Alien Swarm SDK changes to Source 2013, including radial fog, rope code, and treesway) +- https://github.com/momentum-mod/game (Used as a guide to port postprocess_controller and env_dof_controller to Source 2013) - https://github.com/DeathByNukes/source-sdk-2013 (VBSP manifest fixes) - https://github.com/entropy-zero/source-sdk-2013 (skill_changed game event) diff --git a/sp/src/game/client/c_baseplayer.cpp b/sp/src/game/client/c_baseplayer.cpp index b7382f4e..c12e25f8 100644 --- a/sp/src/game/client/c_baseplayer.cpp +++ b/sp/src/game/client/c_baseplayer.cpp @@ -331,6 +331,8 @@ END_RECV_TABLE() RecvPropString( RECVINFO(m_szLastPlaceName) ), + RecvPropEHandle(RECVINFO(m_hPostProcessCtrl)), // Send to everybody - for spectating + #if defined USES_ECON_ITEMS RecvPropUtlVector( RECVINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, RecvPropEHandle(NULL, 0, 0) ), #endif @@ -2907,6 +2909,14 @@ void C_BasePlayer::UpdateFogBlend( void ) } } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +C_PostProcessController* C_BasePlayer::GetActivePostProcessController() const +{ + return m_hPostProcessCtrl.Get(); +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/sp/src/game/client/c_baseplayer.h b/sp/src/game/client/c_baseplayer.h index 3e746311..fac6c0dd 100644 --- a/sp/src/game/client/c_baseplayer.h +++ b/sp/src/game/client/c_baseplayer.h @@ -23,6 +23,7 @@ #include "hintsystem.h" #include "SoundEmitterSystem/isoundemittersystembase.h" #include "c_env_fog_controller.h" +#include "c_postprocesscontroller.h" #include "igameevents.h" #include "GameEventListener.h" @@ -37,6 +38,7 @@ class C_BaseViewModel; class C_FuncLadder; class CFlashlightEffect; class C_EconWearable; +class C_PostProcessController; extern int g_nKillCamMode; extern int g_nKillCamTarget1; @@ -379,6 +381,8 @@ public: void UpdateFogController( void ); void UpdateFogBlend( void ); + C_PostProcessController* GetActivePostProcessController() const; + float GetFOVTime( void ){ return m_flFOVTime; } virtual void OnAchievementAchieved( int iAchievement ) {} @@ -641,6 +645,8 @@ private: // One for left and one for right side of step StepSoundCache_t m_StepSoundCache[ 2 ]; + CNetworkHandle(C_PostProcessController, m_hPostProcessCtrl); // active postprocessing controller + public: const char *GetLastKnownPlaceName( void ) const { return m_szLastPlaceName; } // return the last nav place name the player occupied diff --git a/sp/src/game/client/c_effects.cpp b/sp/src/game/client/c_effects.cpp index 8035bfc4..afd5bcf9 100644 --- a/sp/src/game/client/c_effects.cpp +++ b/sp/src/game/client/c_effects.cpp @@ -40,7 +40,7 @@ ConVar r_RainSplashPercentage( "r_RainSplashPercentage", "20", FCVAR_CHEAT ); // ConVar r_RainParticleDensity( "r_RainParticleDensity", "1", FCVAR_NONE, "Density of Particle Rain 0-1" ); #ifdef MAPBASE -ConVar r_RainParticleClampOffset( "r_RainParticleClampOffset", "112", FCVAR_NONE, "How far inward or outward to extrude clamped precipitation particle systemss" ); +ConVar r_RainParticleClampOffset( "r_RainParticleClampOffset", "112", FCVAR_NONE, "How far inward or outward to extrude clamped precipitation particle systems" ); ConVar r_RainParticleClampDebug( "r_RainParticleClampDebug", "0", FCVAR_NONE, "Enables debug code for precipitation particle system clamping" ); #endif diff --git a/sp/src/game/client/c_env_dof_controller.cpp b/sp/src/game/client/c_env_dof_controller.cpp new file mode 100644 index 00000000..274820e7 --- /dev/null +++ b/sp/src/game/client/c_env_dof_controller.cpp @@ -0,0 +1,88 @@ +//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: Depth of field controller entity +// +//============================================================================= + +#include "cbase.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +extern bool g_bDOFEnabled; +extern float g_flDOFNearBlurDepth; +extern float g_flDOFNearFocusDepth; +extern float g_flDOFFarFocusDepth; +extern float g_flDOFFarBlurDepth; +extern float g_flDOFNearBlurRadius; +extern float g_flDOFFarBlurRadius; + +EHANDLE g_hDOFControllerInUse = NULL; + +class C_EnvDOFController : public C_BaseEntity +{ + DECLARE_CLASS( C_EnvDOFController, C_BaseEntity ); +public: + DECLARE_CLIENTCLASS(); + + C_EnvDOFController(); + ~C_EnvDOFController(); + virtual void OnDataChanged( DataUpdateType_t updateType ); + +private: + bool m_bDOFEnabled; + float m_flNearBlurDepth; + float m_flNearFocusDepth; + float m_flFarFocusDepth; + float m_flFarBlurDepth; + float m_flNearBlurRadius; + float m_flFarBlurRadius; + +private: + C_EnvDOFController( const C_EnvDOFController & ); +}; + +IMPLEMENT_CLIENTCLASS_DT( C_EnvDOFController, DT_EnvDOFController, CEnvDOFController ) + RecvPropInt( RECVINFO(m_bDOFEnabled) ), + RecvPropFloat( RECVINFO(m_flNearBlurDepth) ), + RecvPropFloat( RECVINFO(m_flNearFocusDepth) ), + RecvPropFloat( RECVINFO(m_flFarFocusDepth) ), + RecvPropFloat( RECVINFO(m_flFarBlurDepth) ), + RecvPropFloat( RECVINFO(m_flNearBlurRadius) ), + RecvPropFloat( RECVINFO(m_flFarBlurRadius) ) +END_RECV_TABLE() + +C_EnvDOFController::C_EnvDOFController() +: m_bDOFEnabled( true ), + m_flNearBlurDepth( 20.0f ), + m_flNearFocusDepth( 100.0f ), + m_flFarFocusDepth( 250.0f ), + m_flFarBlurDepth( 1000.0f ), + m_flNearBlurRadius( 0.0f ), // no near blur by default + m_flFarBlurRadius( 5.0f ) +{ +} + +C_EnvDOFController::~C_EnvDOFController() +{ + if ( g_hDOFControllerInUse == this ) + { + g_bDOFEnabled = false; + } +} + +void C_EnvDOFController::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + g_bDOFEnabled = m_bDOFEnabled && ( ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ) ); + g_flDOFNearBlurDepth = m_flNearBlurDepth; + g_flDOFNearFocusDepth = m_flNearFocusDepth; + g_flDOFFarFocusDepth = m_flFarFocusDepth; + g_flDOFFarBlurDepth = m_flFarBlurDepth; + g_flDOFNearBlurRadius = m_flNearBlurRadius; + g_flDOFFarBlurRadius = m_flFarBlurRadius; + + g_hDOFControllerInUse = this; +} diff --git a/sp/src/game/client/c_postprocesscontroller.cpp b/sp/src/game/client/c_postprocesscontroller.cpp new file mode 100644 index 00000000..91a2d1df --- /dev/null +++ b/sp/src/game/client/c_postprocesscontroller.cpp @@ -0,0 +1,63 @@ +//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. ======= +// +// Purpose: stores map postprocess params +// +//============================================================================= +#include "cbase.h" +#include "c_postprocesscontroller.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +IMPLEMENT_CLIENTCLASS_DT( C_PostProcessController, DT_PostProcessController, CPostProcessController ) + RecvPropArray3( RECVINFO_NAME( m_PostProcessParameters.m_flParameters[0], m_flPostProcessParameters ), POST_PROCESS_PARAMETER_COUNT, RecvPropFloat( RECVINFO_NAME( m_PostProcessParameters.m_flParameters[0], m_flPostProcessParameters[0] ) ) ), + RecvPropBool( RECVINFO(m_bMaster) ) +END_RECV_TABLE() + +C_PostProcessController* C_PostProcessController::ms_pMasterController = nullptr; + +//----------------------------------------------------------------------------- +C_PostProcessController::C_PostProcessController() +: m_bMaster( false ) +{ + if ( ms_pMasterController == nullptr) + { + ms_pMasterController = this; + } +} + +//----------------------------------------------------------------------------- +C_PostProcessController::~C_PostProcessController() +{ + if ( ms_pMasterController == this ) + { + ms_pMasterController = nullptr; + } +} + +void C_PostProcessController::PostDataUpdate( DataUpdateType_t updateType ) +{ + BaseClass::PostDataUpdate( updateType ); + + if ( m_bMaster ) + { + ms_pMasterController = this; + } +} + +#ifdef MAPBASE +// Prevents parameters from fading after a save/restore +bool g_bPostProcessNeedsRestore = false; + +void C_PostProcessController::OnRestore() +{ + BaseClass::OnRestore(); + + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( pPlayer && pPlayer->GetActivePostProcessController() == this ) + { + // Tell clientmode this is part of a save/restore + g_bPostProcessNeedsRestore = true; + } +} +#endif diff --git a/sp/src/game/client/c_postprocesscontroller.h b/sp/src/game/client/c_postprocesscontroller.h new file mode 100644 index 00000000..c07673f7 --- /dev/null +++ b/sp/src/game/client/c_postprocesscontroller.h @@ -0,0 +1,33 @@ +#pragma once + +#include "postprocess_shared.h" + +//============================================================================= +// +// Class Postprocess Controller: +// +class C_PostProcessController : public C_BaseEntity +{ + DECLARE_CLASS( C_PostProcessController, C_BaseEntity ); +public: + DECLARE_CLIENTCLASS(); + + C_PostProcessController(); + virtual ~C_PostProcessController(); + + virtual void PostDataUpdate( DataUpdateType_t updateType ); + + static C_PostProcessController* GetMasterController() { return ms_pMasterController; } + + PostProcessParameters_t m_PostProcessParameters; + +#ifdef MAPBASE + // Prevents fade time from being used in save/restore + virtual void OnRestore(); +#endif + +private: + bool m_bMaster; + + static C_PostProcessController* ms_pMasterController; +}; diff --git a/sp/src/game/client/client_mapbase.vpc b/sp/src/game/client/client_mapbase.vpc index 4b9b879f..3c2eb00f 100644 --- a/sp/src/game/client/client_mapbase.vpc +++ b/sp/src/game/client/client_mapbase.vpc @@ -28,6 +28,9 @@ $Project $File "c_gameinstructor.h" $File "hud_locator_target.cpp" $File "hud_locator_target.h" + $File "c_postprocesscontroller.cpp" + $File "c_postprocesscontroller.h" + $File "c_env_dof_controller.cpp" $Folder "Mapbase" { diff --git a/sp/src/game/client/clientmode_shared.cpp b/sp/src/game/client/clientmode_shared.cpp index 7f818ed0..f68531bb 100644 --- a/sp/src/game/client/clientmode_shared.cpp +++ b/sp/src/game/client/clientmode_shared.cpp @@ -36,6 +36,7 @@ #include #include "hud_vote.h" #include "ienginevgui.h" +#include "viewpostprocess.h" #include "sourcevr/isourcevirtualreality.h" #if defined( _X360 ) #include "xbox/xbox_console.h" @@ -291,6 +292,9 @@ ClientModeShared::ClientModeShared() m_pWeaponSelection = NULL; m_nRootSize[ 0 ] = m_nRootSize[ 1 ] = -1; + m_pCurrentPostProcessController = NULL; + m_PostProcessLerpTimer.Invalidate(); + #if defined( REPLAY_ENABLED ) m_pReplayReminderPanel = NULL; m_flReplayStartRecordTime = 0.0f; @@ -604,6 +608,8 @@ void ClientModeShared::Update() m_pViewport->SetVisible( cl_drawhud.GetBool() ); } + UpdatePostProcessingEffects(); + UpdateRumbleEffects(); if ( cl_show_num_particle_systems.GetBool() ) @@ -914,6 +920,17 @@ void ClientModeShared::LevelShutdown( void ) s_hVGuiContext = DEFAULT_VGUI_CONTEXT; } +#ifdef MAPBASE + // Always reset post-processing on level unload + //if (m_pCurrentPostProcessController) + { + m_CurrentPostProcessParameters = PostProcessParameters_t(); + m_LerpEndPostProcessParameters = PostProcessParameters_t(); + m_pCurrentPostProcessController = NULL; + SetPostProcessParams( &m_CurrentPostProcessParameters ); + } +#endif + // Reset any player explosion/shock effects CLocalPlayerFilter filter; enginesound->SetPlayerDSP( filter, 0, true ); @@ -988,6 +1005,69 @@ float ClientModeShared::GetViewModelFOV( void ) return v_viewmodel_fov.GetFloat(); } +#ifdef MAPBASE +extern bool g_bPostProcessNeedsRestore; +#endif + +void ClientModeShared::UpdatePostProcessingEffects() +{ + C_PostProcessController* pNewPostProcessController = NULL; + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + + if (pPlayer) + pNewPostProcessController = pPlayer->GetActivePostProcessController(); + + if (!pNewPostProcessController) + { + m_CurrentPostProcessParameters = PostProcessParameters_t(); + m_pCurrentPostProcessController = NULL; + SetPostProcessParams( &m_CurrentPostProcessParameters ); + return; + } + + if (pNewPostProcessController != m_pCurrentPostProcessController) + m_pCurrentPostProcessController = pNewPostProcessController; + + // Start a lerp timer if the parameters changed, regardless of whether the controller changed + if (m_LerpEndPostProcessParameters != pNewPostProcessController->m_PostProcessParameters) + { + m_LerpStartPostProcessParameters = m_CurrentPostProcessParameters; + m_LerpEndPostProcessParameters = pNewPostProcessController ? pNewPostProcessController->m_PostProcessParameters : m_CurrentPostProcessParameters; + + float flFadeTime = pNewPostProcessController ? pNewPostProcessController->m_PostProcessParameters.m_flParameters[PPPN_FADE_TIME] : 0.0f; + if (flFadeTime <= 0.0f) + { + flFadeTime = 0.001f; + } + + m_PostProcessLerpTimer.Start( flFadeTime ); + } +#ifdef MAPBASE + // HACKHACK: Needs to be checked here because OnRestore() doesn't seem to run before a lerp begins + else if (g_bPostProcessNeedsRestore) + { + // The player just loaded a saved game. + // Don't fade parameters from 0; instead, take what's already there and assume they were already active. + // (we have no way of knowing if they were in the middle of a lerp) + m_PostProcessLerpTimer.Invalidate(); + g_bPostProcessNeedsRestore = false; + } +#endif + + // Lerp between old and new parameters + float flLerpFactor = 1.0f - m_PostProcessLerpTimer.GetRemainingRatio(); + for (int nParameter = 0; nParameter < POST_PROCESS_PARAMETER_COUNT; ++nParameter) + { + m_CurrentPostProcessParameters.m_flParameters[nParameter] = + Lerp( + flLerpFactor, + m_LerpStartPostProcessParameters.m_flParameters[nParameter], + m_LerpEndPostProcessParameters.m_flParameters[nParameter] ); + } + + SetPostProcessParams( &m_CurrentPostProcessParameters ); +} + class CHudChat; bool PlayerNameNotSetYet( const char *pszName ) diff --git a/sp/src/game/client/clientmode_shared.h b/sp/src/game/client/clientmode_shared.h index e7b92c35..a1389f96 100644 --- a/sp/src/game/client/clientmode_shared.h +++ b/sp/src/game/client/clientmode_shared.h @@ -164,6 +164,13 @@ private: vgui::HCursor m_CursorNone; CBaseHudWeaponSelection *m_pWeaponSelection; int m_nRootSize[2]; + + void UpdatePostProcessingEffects(); + + const C_PostProcessController* m_pCurrentPostProcessController; + PostProcessParameters_t m_CurrentPostProcessParameters; + PostProcessParameters_t m_LerpStartPostProcessParameters, m_LerpEndPostProcessParameters; + CountdownTimer m_PostProcessLerpTimer; }; #endif // CLIENTMODE_NORMAL_H diff --git a/sp/src/game/client/message.cpp b/sp/src/game/client/message.cpp index 1a5c4ae4..dc41bb00 100644 --- a/sp/src/game/client/message.cpp +++ b/sp/src/game/client/message.cpp @@ -892,7 +892,7 @@ void CHudMessage::MsgFunc_HudMsg(bf_read &msg) int lineMinBreak = lineMax * 0.9; - DevMsg( "Line max is %i from an aspect ratio of %.3f (strlen %i)\n", lineMax, engine->GetScreenAspectRatio(), len ); + CGMsg( 2, CON_GROUP_CHOREO, "Line max is %i from an aspect ratio of %.3f (strlen %i)\n", lineMax, engine->GetScreenAspectRatio(), len ); char *curMessage = (char*)pNetMessage->pMessage; char newMessage[512]; @@ -934,6 +934,9 @@ void CHudMessage::MsgFunc_HudMsg(bf_read &msg) i2++; } + // Null terminate + newMessage[i2] = '\0'; + Q_strncpy( (char*)pNetMessage->pMessage, newMessage, 512 ); } #endif diff --git a/sp/src/game/client/viewpostprocess.cpp b/sp/src/game/client/viewpostprocess.cpp index 2ad1b0d9..e1845d8d 100644 --- a/sp/src/game/client/viewpostprocess.cpp +++ b/sp/src/game/client/viewpostprocess.cpp @@ -13,6 +13,7 @@ #include "materialsystem/materialsystem_config.h" #include "tier1/callqueue.h" #include "colorcorrectionmgr.h" +#include "postprocess_shared.h" #include "view_scene.h" #include "c_world.h" @@ -38,6 +39,15 @@ float g_flCustomAutoExposureMax = 0; float g_flCustomBloomScale = 0.0f; float g_flCustomBloomScaleMinimum = 0.0f; +// mapmaker controlled depth of field +bool g_bDOFEnabled = false; +float g_flDOFNearBlurDepth = 20.0f; +float g_flDOFNearFocusDepth = 100.0f; +float g_flDOFFarFocusDepth = 250.0f; +float g_flDOFFarBlurDepth = 1000.0f; +float g_flDOFNearBlurRadius = 0.0f; +float g_flDOFFarBlurRadius = 10.0f; + bool g_bFlashlightIsOn = false; // hdr parameters @@ -293,9 +303,9 @@ void ApplyPostProcessingPasses(PostProcessingPass *pass_list, // table of effect pRenderContext->SetRenderTarget(NULL); int row=pcount/4; int col=pcount %4; - int dest_width,dest_height; - pRenderContext->GetRenderTargetDimensions( dest_width, dest_height ); - pRenderContext->Viewport( 0, 0, dest_width, dest_height ); + int destwidth,destheight; + pRenderContext->GetRenderTargetDimensions( destwidth, destheight ); + pRenderContext->Viewport( 0, 0, destwidth, destheight ); DrawClippedScreenSpaceRectangle(src_mat,10+col*220,10+row*220, 200,200, 0,0,1,1,1,1,cb); @@ -336,7 +346,7 @@ PostProcessingPass HDRSimulate_NonHDR[] = PPP_END }; -static void SetRenderTargetAndViewPort(ITexture *rt) +void SetRenderTargetAndViewPort(ITexture *rt) { tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); @@ -1145,6 +1155,32 @@ void CLuminanceHistogramSystem::DisplayHistogram( void ) pRenderContext->PopRenderTargetAndViewport(); } +// Local contrast setting +PostProcessParameters_t s_LocalPostProcessParameters; + +// view fade param settings +static Vector4D s_viewFadeColor; +static bool s_bViewFadeModulate; + +static bool s_bOverridePostProcessParams = false; + +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters ) +{ + if (!s_bOverridePostProcessParams) + s_LocalPostProcessParameters = *pPostProcessParameters; +} + +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters, bool bOverride ) +{ + s_bOverridePostProcessParams = bOverride; + s_LocalPostProcessParameters = *pPostProcessParameters; +} + +void SetViewFadeParams( byte r, byte g, byte b, byte a, bool bModulate ) +{ + s_viewFadeColor.Init( float( r ) / 255.0f, float( g ) / 255.0f, float( b ) / 255.0f, float( a ) / 255.0f ); + s_bViewFadeModulate = bModulate; +} static CLuminanceHistogramSystem g_HDR_HistogramSystem; @@ -1240,15 +1276,32 @@ private: IMaterialVar *m_pMaterialParam_AAValues; IMaterialVar *m_pMaterialParam_AAValues2; IMaterialVar *m_pMaterialParam_BloomEnable; + IMaterialVar *m_pMaterialParam_BloomAmount; IMaterialVar *m_pMaterialParam_BloomUVTransform; IMaterialVar *m_pMaterialParam_ColCorrectEnable; IMaterialVar *m_pMaterialParam_ColCorrectNumLookups; IMaterialVar *m_pMaterialParam_ColCorrectDefaultWeight; IMaterialVar *m_pMaterialParam_ColCorrectLookupWeights; + IMaterialVar *m_pMaterialParam_LocalContrastStrength; + IMaterialVar *m_pMaterialParam_LocalContrastEdgeStrength; + IMaterialVar *m_pMaterialParam_VignetteStart; + IMaterialVar *m_pMaterialParam_VignetteEnd; + IMaterialVar *m_pMaterialParam_VignetteBlurEnable; + IMaterialVar *m_pMaterialParam_VignetteBlurStrength; + IMaterialVar *m_pMaterialParam_FadeToBlackStrength; + IMaterialVar *m_pMaterialParam_DepthBlurFocalDistance; + IMaterialVar *m_pMaterialParam_DepthBlurStrength; + IMaterialVar *m_pMaterialParam_ScreenBlurStrength; + IMaterialVar *m_pMaterialParam_FilmGrainStrength; + IMaterialVar *m_pMaterialParam_VomitEnable; + IMaterialVar *m_pMaterialParam_VomitColor1; + IMaterialVar *m_pMaterialParam_VomitColor2; + IMaterialVar *m_pMaterialParam_FadeColor; + IMaterialVar *m_pMaterialParam_FadeType; public: static IMaterial * SetupEnginePostMaterial( const Vector4D & fullViewportBloomUVs, const Vector4D & fullViewportFBUVs, const Vector2D & destTexSize, - bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength ); + bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength, float flBloomAmount ); static void SetupEnginePostMaterialAA( bool bPerformSoftwareAA, float flAAStrength ); static void SetupEnginePostMaterialTextureTransform( const Vector4D & fullViewportBloomUVs, const Vector4D & fullViewportFBUVs, Vector2D destTexSize ); @@ -1257,12 +1310,14 @@ private: static float s_vBloomAAValues2[4]; static float s_vBloomUVTransform[4]; static int s_PostBloomEnable; + static float s_PostBloomAmount; }; float CEnginePostMaterialProxy::s_vBloomAAValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float CEnginePostMaterialProxy::s_vBloomAAValues2[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float CEnginePostMaterialProxy::s_vBloomUVTransform[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; int CEnginePostMaterialProxy::s_PostBloomEnable = 1; +float CEnginePostMaterialProxy::s_PostBloomAmount = 1.0f; CEnginePostMaterialProxy::CEnginePostMaterialProxy() { @@ -1270,10 +1325,22 @@ CEnginePostMaterialProxy::CEnginePostMaterialProxy() m_pMaterialParam_AAValues2 = NULL; m_pMaterialParam_BloomUVTransform = NULL; m_pMaterialParam_BloomEnable = NULL; + m_pMaterialParam_BloomAmount = NULL; m_pMaterialParam_ColCorrectEnable = NULL; m_pMaterialParam_ColCorrectNumLookups = NULL; m_pMaterialParam_ColCorrectDefaultWeight = NULL; m_pMaterialParam_ColCorrectLookupWeights = NULL; + m_pMaterialParam_LocalContrastStrength = NULL; + m_pMaterialParam_LocalContrastEdgeStrength = NULL; + m_pMaterialParam_VignetteStart = NULL; + m_pMaterialParam_VignetteEnd = NULL; + m_pMaterialParam_VignetteBlurEnable = NULL; + m_pMaterialParam_VignetteBlurStrength = NULL; + m_pMaterialParam_FadeToBlackStrength = NULL; + m_pMaterialParam_DepthBlurFocalDistance = NULL; + m_pMaterialParam_DepthBlurStrength = NULL; + m_pMaterialParam_ScreenBlurStrength = NULL; + m_pMaterialParam_FilmGrainStrength = NULL; } CEnginePostMaterialProxy::~CEnginePostMaterialProxy() @@ -1284,15 +1351,32 @@ CEnginePostMaterialProxy::~CEnginePostMaterialProxy() bool CEnginePostMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { bool bFoundVar = false; - + m_pMaterialParam_AAValues = pMaterial->FindVar( "$AAInternal1", &bFoundVar, false ); m_pMaterialParam_AAValues2 = pMaterial->FindVar( "$AAInternal3", &bFoundVar, false ); m_pMaterialParam_BloomUVTransform = pMaterial->FindVar( "$AAInternal2", &bFoundVar, false ); m_pMaterialParam_BloomEnable = pMaterial->FindVar( "$bloomEnable", &bFoundVar, false ); + m_pMaterialParam_BloomAmount = pMaterial->FindVar( "$bloomAmount", &bFoundVar, false ); m_pMaterialParam_ColCorrectEnable = pMaterial->FindVar( "$colCorrectEnable", &bFoundVar, false ); m_pMaterialParam_ColCorrectNumLookups = pMaterial->FindVar( "$colCorrect_NumLookups", &bFoundVar, false ); m_pMaterialParam_ColCorrectDefaultWeight = pMaterial->FindVar( "$colCorrect_DefaultWeight", &bFoundVar, false ); m_pMaterialParam_ColCorrectLookupWeights = pMaterial->FindVar( "$colCorrect_LookupWeights", &bFoundVar, false ); + m_pMaterialParam_LocalContrastStrength = pMaterial->FindVar( "$localContrastScale", &bFoundVar, false ); + m_pMaterialParam_LocalContrastEdgeStrength = pMaterial->FindVar( "$localContrastEdgeScale", &bFoundVar, false ); + m_pMaterialParam_VignetteStart = pMaterial->FindVar( "$localContrastVignetteStart", &bFoundVar, false ); + m_pMaterialParam_VignetteEnd = pMaterial->FindVar( "$localContrastVignetteEnd", &bFoundVar, false ); + m_pMaterialParam_VignetteBlurEnable = pMaterial->FindVar( "$blurredVignetteEnable", &bFoundVar, false ); + m_pMaterialParam_VignetteBlurStrength = pMaterial->FindVar( "$blurredVignetteScale", &bFoundVar, false ); + m_pMaterialParam_FadeToBlackStrength = pMaterial->FindVar( "$fadeToBlackScale", &bFoundVar, false ); + m_pMaterialParam_DepthBlurFocalDistance = pMaterial->FindVar( "$depthBlurFocalDistance", &bFoundVar, false ); + m_pMaterialParam_DepthBlurStrength = pMaterial->FindVar( "$depthBlurStrength", &bFoundVar, false ); + m_pMaterialParam_ScreenBlurStrength = pMaterial->FindVar( "$screenBlurStrength", &bFoundVar, false ); + m_pMaterialParam_FilmGrainStrength = pMaterial->FindVar( "$noiseScale", &bFoundVar, false ); + m_pMaterialParam_VomitEnable = pMaterial->FindVar( "$vomitEnable", &bFoundVar, false ); + m_pMaterialParam_VomitColor1 = pMaterial->FindVar( "$vomitColor1", &bFoundVar, false ); + m_pMaterialParam_VomitColor2 = pMaterial->FindVar( "$vomitColor2", &bFoundVar, false ); + m_pMaterialParam_FadeColor = pMaterial->FindVar( "$fadeColor", &bFoundVar, false ); + m_pMaterialParam_FadeType = pMaterial->FindVar( "$fade", &bFoundVar, false ); return true; } @@ -1310,6 +1394,56 @@ void CEnginePostMaterialProxy::OnBind( C_BaseEntity *pEnt ) if ( m_pMaterialParam_BloomEnable ) m_pMaterialParam_BloomEnable->SetIntValue( s_PostBloomEnable ); + + if ( m_pMaterialParam_BloomAmount ) + m_pMaterialParam_BloomAmount->SetFloatValue( s_PostBloomAmount ); + + if ( m_pMaterialParam_LocalContrastStrength ) + m_pMaterialParam_LocalContrastStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_LOCAL_CONTRAST_STRENGTH ] ); + + if ( m_pMaterialParam_LocalContrastEdgeStrength ) + m_pMaterialParam_LocalContrastEdgeStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_LOCAL_CONTRAST_EDGE_STRENGTH ] ); + + if ( m_pMaterialParam_VignetteStart ) + m_pMaterialParam_VignetteStart->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_START ] ); + + if ( m_pMaterialParam_VignetteEnd ) + m_pMaterialParam_VignetteEnd->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_END ] ); + + if ( m_pMaterialParam_VignetteBlurEnable ) + m_pMaterialParam_VignetteBlurEnable->SetIntValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_BLUR_STRENGTH ] > 0.0f ? 1 : 0 ); + + if ( m_pMaterialParam_VignetteBlurStrength ) + m_pMaterialParam_VignetteBlurStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_BLUR_STRENGTH ] ); + + if ( m_pMaterialParam_FadeToBlackStrength ) + m_pMaterialParam_FadeToBlackStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_FADE_TO_BLACK_STRENGTH ] ); + + if ( m_pMaterialParam_DepthBlurFocalDistance ) + m_pMaterialParam_DepthBlurFocalDistance->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_DEPTH_BLUR_FOCAL_DISTANCE ] ); + + if ( m_pMaterialParam_DepthBlurStrength ) + m_pMaterialParam_DepthBlurStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_DEPTH_BLUR_STRENGTH ] ); + + if ( m_pMaterialParam_ScreenBlurStrength ) + m_pMaterialParam_ScreenBlurStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_SCREEN_BLUR_STRENGTH ] ); + + if ( m_pMaterialParam_FilmGrainStrength ) + m_pMaterialParam_FilmGrainStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_FILM_GRAIN_STRENGTH ] ); + + + + if ( m_pMaterialParam_FadeType ) + { + int nFadeType = ( s_bViewFadeModulate ) ? 2 : 1; + nFadeType = ( s_viewFadeColor[3] > 0.0f ) ? nFadeType : 0; + m_pMaterialParam_FadeType->SetIntValue( nFadeType ); + } + + if ( m_pMaterialParam_FadeColor ) + { + m_pMaterialParam_FadeColor->SetVecValue( s_viewFadeColor.Base(), 4 ); + } } IMaterial *CEnginePostMaterialProxy::GetMaterial() @@ -1382,26 +1516,29 @@ void CEnginePostMaterialProxy::SetupEnginePostMaterialTextureTransform( const Ve } IMaterial * CEnginePostMaterialProxy::SetupEnginePostMaterial( const Vector4D & fullViewportBloomUVs, const Vector4D & fullViewportFBUVs, const Vector2D & destTexSize, - bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength ) + bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength, float flBloomAmount ) { // Shouldn't get here if none of the effects are enabled Assert( bPerformSoftwareAA || bPerformBloom || bPerformColCorrect ); - s_PostBloomEnable = bPerformBloom ? 1 : 0; + s_PostBloomEnable = bPerformBloom ? 1 : 0; + s_PostBloomAmount = flBloomAmount; SetupEnginePostMaterialAA( bPerformSoftwareAA, flAAStrength ); - if ( bPerformSoftwareAA || bPerformColCorrect ) + //if ( bPerformSoftwareAA || bPerformColCorrect ) { SetupEnginePostMaterialTextureTransform( fullViewportBloomUVs, fullViewportFBUVs, destTexSize ); return materials->FindMaterial( "dev/engine_post", TEXTURE_GROUP_OTHER, true); } + /* else { // Just use the old bloomadd material (which uses additive blending, unlike engine_post) // NOTE: this path is what gets used for DX8 (which cannot enable AA or col-correction) return materials->FindMaterial( "dev/bloomadd", TEXTURE_GROUP_OTHER, true); } + */ } EXPOSE_INTERFACE( CEnginePostMaterialProxy, IMaterialProxy, "engine_post" IMATERIAL_PROXY_INTERFACE_VERSION ); @@ -1552,6 +1689,28 @@ void DumpTGAofRenderTarget( const int width, const int height, const char *pFile static bool s_bScreenEffectTextureIsUpdated = false; +// WARNING: This function sets rendertarget and viewport. Save and restore is left to the caller. +static void DownsampleFBQuarterSize( IMatRenderContext *pRenderContext, int nSrcWidth, int nSrcHeight, ITexture* pDest, + bool bFloatHDR = false ) +{ + Assert( pRenderContext ); + Assert( pDest ); + + IMaterial *downsample_mat = materials->FindMaterial( bFloatHDR ? "dev/downsample" : "dev/downsample_non_hdr", TEXTURE_GROUP_OTHER, true ); + + // *Everything* in here relies on the small RTs being exactly 1/4 the full FB res + Assert( pDest->GetActualWidth() == nSrcWidth / 4 ); + Assert( pDest->GetActualHeight() == nSrcHeight / 4 ); + + // downsample fb to rt0 + SetRenderTargetAndViewPort( pDest ); + // note the -2's below. Thats because we are downsampling on each axis and the shader + // accesses pixels on both sides of the source coord + pRenderContext->DrawScreenSpaceRectangle( downsample_mat, 0, 0, nSrcWidth/4, nSrcHeight/4, + 0, 0, nSrcWidth-2, nSrcHeight-2, + nSrcWidth, nSrcHeight ); +} + static void Generate8BitBloomTexture( IMatRenderContext *pRenderContext, float flBloomScale, int x, int y, int w, int h ) { @@ -1614,7 +1773,7 @@ static void Generate8BitBloomTexture( IMatRenderContext *pRenderContext, float f // Gaussian blur y rt1 to rt0 SetRenderTargetAndViewPort( dest_rt0 ); IMaterialVar *pBloomAmountVar = yblur_mat->FindVar( "$bloomamount", NULL ); - pBloomAmountVar->SetFloatValue( flBloomScale ); + pBloomAmountVar->SetFloatValue( 1.0f ); // the bloom amount is now applied in engine_post or bloomadd materials pRenderContext->DrawScreenSpaceRectangle( yblur_mat, 0, 0, nSrcWidth / 4, nSrcHeight / 4, 0, 0, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1, nSrcWidth / 4, nSrcHeight / 4 ); @@ -2357,7 +2516,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b // bloom, software-AA and colour-correction (applied in 1 pass, after generation of the bloom texture) bool bPerformSoftwareAA = IsX360() && ( engine->GetDXSupportLevel() >= 90 ) && ( flAAStrength != 0.0f ); - bool bPerformBloom = !bPostVGui && ( flBloomScale > 0.0f ) && ( engine->GetDXSupportLevel() >= 90 ); + bool bPerformBloom = true; //!bPostVGui && ( flBloomScale > 0.0f ) && ( engine->GetDXSupportLevel() >= 90 ); bool bPerformColCorrect = !bPostVGui && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 90) && ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_FLOAT ) && @@ -2417,9 +2576,9 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b partialViewportPostDestRect.height -= 0.50f*fullViewportPostDestRect.height; // This math interprets texel coords as being at corner pixel centers (*not* at corner vertices): - Vector2D uvScale( 1.0f - ( (w / 2) / (float)(w - 1) ), + Vector2D uvScaleCorner( 1.0f - ( (w / 2) / (float)(w - 1) ), 1.0f - ( (h / 2) / (float)(h - 1) ) ); - CenterScaleQuadUVs( partialViewportPostSrcCorners, uvScale ); + CenterScaleQuadUVs( partialViewportPostSrcCorners, uvScaleCorner ); } // Temporary hack... Color correction was crashing on the first frame @@ -2435,7 +2594,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b { // Perform post-processing in one combined pass - IMaterial *post_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, bPerformBloom, bPerformColCorrect, flAAStrength ); + IMaterial *post_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, bPerformBloom, bPerformColCorrect, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2463,7 +2622,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b // Perform post-processing in three separate passes if ( bPerformSoftwareAA ) { - IMaterial *aa_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, false, false, flAAStrength ); + IMaterial *aa_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, false, false, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2488,7 +2647,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b if ( bPerformBloom ) { - IMaterial *bloom_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, bPerformBloom, false, flAAStrength ); + IMaterial *bloom_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, bPerformBloom, false, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2519,7 +2678,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b UpdateScreenEffectTexture( 0, x, y, w, h, false, &actualRect ); } - IMaterial *colcorrect_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, false, bPerformColCorrect, flAAStrength ); + IMaterial *colcorrect_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, false, bPerformColCorrect, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2667,6 +2826,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b // Motion Blur Material Proxy ========================================================================================= static float g_vMotionBlurValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static float g_vMotionBlurViewportValues[4] = { 0.0f, 0.0f, 1.0f, 1.0f }; class CMotionBlurMaterialProxy : public CEntityMaterialProxy { public: @@ -2678,6 +2838,7 @@ public: private: IMaterialVar *m_pMaterialParam; + IMaterialVar *m_pMaterialParamViewport; }; CMotionBlurMaterialProxy::CMotionBlurMaterialProxy() @@ -2698,6 +2859,10 @@ bool CMotionBlurMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues if ( bFoundVar == false) return false; + m_pMaterialParamViewport = pMaterial->FindVar( "$MotionBlurViewportInternal", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + return true; } @@ -2707,6 +2872,11 @@ void CMotionBlurMaterialProxy::OnBind( C_BaseEntity *pEnt ) { m_pMaterialParam->SetVecValue( g_vMotionBlurValues, 4 ); } + + if ( m_pMaterialParamViewport != NULL ) + { + m_pMaterialParamViewport->SetVecValue( g_vMotionBlurViewportValues, 4 ); + } } IMaterial *CMotionBlurMaterialProxy::GetMaterial() @@ -2723,24 +2893,49 @@ EXPOSE_INTERFACE( CMotionBlurMaterialProxy, IMaterialProxy, "MotionBlur" IMATERI // Image-space Motion Blur ============================================================================================ //===================================================================================================================== ConVar mat_motion_blur_enabled( "mat_motion_blur_enabled", "1", FCVAR_ARCHIVE ); + ConVar mat_motion_blur_forward_enabled( "mat_motion_blur_forward_enabled", "0" ); ConVar mat_motion_blur_falling_min( "mat_motion_blur_falling_min", "10.0" ); + ConVar mat_motion_blur_falling_max( "mat_motion_blur_falling_max", "20.0" ); ConVar mat_motion_blur_falling_intensity( "mat_motion_blur_falling_intensity", "1.0" ); //ConVar mat_motion_blur_roll_intensity( "mat_motion_blur_roll_intensity", "1.0" ); ConVar mat_motion_blur_rotation_intensity( "mat_motion_blur_rotation_intensity", "1.0" ); ConVar mat_motion_blur_strength( "mat_motion_blur_strength", "1.0" ); -void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h ) +struct MotionBlurHistory_t { -#ifdef CSS_PERF_TEST - return; -#endif - if ( ( !mat_motion_blur_enabled.GetInt() ) || ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 90 ) ) + MotionBlurHistory_t() + { + m_flLastTimeUpdate = 0.0f; + m_flPreviousPitch = 0.0f; + m_flPreviousYaw = 0.0f; + m_vPreviousPositon.Init( 0.0f, 0.0f, 0.0f ); + m_mPreviousFrameBasisVectors; + m_flNoRotationalMotionBlurUntil = 0.0f; + SetIdentityMatrix( m_mPreviousFrameBasisVectors ); + } + + float m_flLastTimeUpdate; + float m_flPreviousPitch; + float m_flPreviousYaw; + Vector m_vPreviousPositon; + matrix3x4_t m_mPreviousFrameBasisVectors; + float m_flNoRotationalMotionBlurUntil; +}; + +void DoImageSpaceMotionBlur( const CViewSetup &viewSetup ) +{ + if ( !mat_motion_blur_enabled.GetInt() ) { return; } + int x = viewSetup.x; + int y = viewSetup.y; + int w = viewSetup.width; + int h = viewSetup.height; + //======================================================================================================// // Get these convars here to make it easier to remove them later and to default each client differently // //======================================================================================================// @@ -2759,22 +2954,19 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //=====================// // Previous frame data // //=====================// - static float s_flLastTimeUpdate = 0.0f; - static float s_flPreviousPitch = 0.0f; - static float s_flPreviousYaw = 0.0f; - static float s_vPreviousPositon[3] = { 0.0f, 0.0f, 0.0f }; - static matrix3x4_t s_mPreviousFrameBasisVectors; - static float s_flNoRotationalMotionBlurUntil = 0.0f; + static MotionBlurHistory_t history; + //float vPreviousSideVec[3] = { s_mPreviousFrameBasisVectors[0][1], s_mPreviousFrameBasisVectors[1][1], s_mPreviousFrameBasisVectors[2][1] }; //float vPreviousForwardVec[3] = { s_mPreviousFrameBasisVectors[0][0], s_mPreviousFrameBasisVectors[1][0], s_mPreviousFrameBasisVectors[2][0] }; //float vPreviousUpVec[3] = { s_mPreviousFrameBasisVectors[0][2], s_mPreviousFrameBasisVectors[1][2], s_mPreviousFrameBasisVectors[2][2] }; - float flTimeElapsed = gpGlobals->realtime - s_flLastTimeUpdate; + float flTimeElapsed = gpGlobals->realtime - history.m_flLastTimeUpdate; + //===================================// // Get current pitch & wrap to +-180 // //===================================// - float flCurrentPitch = view.angles[PITCH]; + float flCurrentPitch = viewSetup.angles[PITCH]; while ( flCurrentPitch > 180.0f ) flCurrentPitch -= 360.0f; while ( flCurrentPitch < -180.0f ) @@ -2783,35 +2975,39 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //=================================// // Get current yaw & wrap to +-180 // //=================================// - float flCurrentYaw = view.angles[YAW]; + float flCurrentYaw = viewSetup.angles[YAW]; while ( flCurrentYaw > 180.0f ) flCurrentYaw -= 360.0f; while ( flCurrentYaw < -180.0f ) flCurrentYaw += 360.0f; - //engine->Con_NPrintf( 0, "Blur Pitch: %6.2f Yaw: %6.2f", flCurrentPitch, flCurrentYaw ); - //engine->Con_NPrintf( 1, "Blur FOV: %6.2f Aspect: %6.2f Ortho: %s", view.fov, view.m_flAspectRatio, view.m_bOrtho ? "Yes" : "No" ); + + + /*engine->Con_NPrintf( 0, "Blur Pitch: %6.2f Yaw: %6.2f", flCurrentPitch, flCurrentYaw ); + engine->Con_NPrintf( 1, "Blur FOV: %6.2f Aspect: %6.2f Ortho: %s", view.fov, view.m_flAspectRatio, view.m_bOrtho ? "Yes" : "No" ); + engine->Con_NPrintf( 2, "View Angles: %6.2f %6.2f %6.2f", XYZ(view.angles) );*/ //===========================// // Get current basis vectors // //===========================// matrix3x4_t mCurrentBasisVectors; - AngleMatrix( view.angles, mCurrentBasisVectors ); + AngleMatrix( viewSetup.angles, mCurrentBasisVectors ); - float vCurrentSideVec[3] = { mCurrentBasisVectors[0][1], mCurrentBasisVectors[1][1], mCurrentBasisVectors[2][1] }; - float vCurrentForwardVec[3] = { mCurrentBasisVectors[0][0], mCurrentBasisVectors[1][0], mCurrentBasisVectors[2][0] }; - //float vCurrentUpVec[3] = { mCurrentBasisVectors[0][2], mCurrentBasisVectors[1][2], mCurrentBasisVectors[2][2] }; + + Vector vCurrentSideVec( mCurrentBasisVectors[0][1], mCurrentBasisVectors[1][1], mCurrentBasisVectors[2][1] ); + Vector vCurrentForwardVec( mCurrentBasisVectors[0][0], mCurrentBasisVectors[1][0], mCurrentBasisVectors[2][0] ); + //Vector vCurrentUpVec( mCurrentBasisVectors[0][2], mCurrentBasisVectors[1][2], mCurrentBasisVectors[2][2] ); //======================// // Get current position // //======================// - float vCurrentPosition[3] = { view.origin.x, view.origin.y, view.origin.z }; + Vector vCurrentPosition = viewSetup.origin; //===============================================================// // Evaluate change in position to determine if we need to update // //===============================================================// - float vPositionChange[3] = { 0.0f, 0.0f, 0.0f }; - VectorSubtract( s_vPreviousPositon, vCurrentPosition, vPositionChange ); + Vector vPositionChange( 0.0f, 0.0f, 0.0f ); + VectorSubtract( history.m_vPreviousPositon, vCurrentPosition, vPositionChange ); if ( ( VectorLength( vPositionChange ) > 30.0f ) && ( flTimeElapsed >= 0.5f ) ) { //=======================================================// @@ -2825,7 +3021,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h g_vMotionBlurValues[2] = 0.0f; g_vMotionBlurValues[3] = 0.0f; } - else if ( flTimeElapsed > ( 1.0f / 15.0f ) ) + else if ( ( flTimeElapsed > ( 1.0f / 15.0f ) ) ) { //==========================================// // If slower than 15 fps, don't motion blur // @@ -2835,7 +3031,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h g_vMotionBlurValues[2] = 0.0f; g_vMotionBlurValues[3] = 0.0f; } - else if ( VectorLength( vPositionChange ) > 50.0f ) + else if ( ( VectorLength( vPositionChange ) > 50.0f ) ) { //================================================================================// // We moved a far distance in a frame, use the same motion blur as last frame // @@ -2843,7 +3039,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //================================================================================// //engine->Con_NPrintf( 8, " Position changed %f units @ %.2f time ", VectorLength( vPositionChange ), gpGlobals->realtime ); - s_flNoRotationalMotionBlurUntil = gpGlobals->realtime + 1.0f; // Wait a second until the portal craziness calms down + history.m_flNoRotationalMotionBlurUntil = gpGlobals->realtime + 1.0f; // Wait a second until the portal craziness calms down } else { @@ -2851,8 +3047,8 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h // Normal update path // //====================// // Compute horizontal and vertical fov - float flHorizontalFov = view.fov; - float flVerticalFov = ( view.m_flAspectRatio <= 0.0f ) ? ( view.fov ) : ( view.fov / view.m_flAspectRatio ); + float flHorizontalFov = viewSetup.fov; + float flVerticalFov = ( viewSetup.m_flAspectRatio <= 0.0f ) ? ( viewSetup.fov ) : ( viewSetup.fov / viewSetup.m_flAspectRatio ); //engine->Con_NPrintf( 2, "Horizontal Fov: %6.2f Vertical Fov: %6.2f", flHorizontalFov, flVerticalFov ); //=====================// @@ -2868,10 +3064,10 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h // Yaw (Compensate for circle strafe) // //====================================// float flSideDotMotion = DotProduct( vCurrentSideVec, vPositionChange ); - float flYawDiffOriginal = s_flPreviousYaw - flCurrentYaw; - if ( ( ( s_flPreviousYaw - flCurrentYaw > 180.0f ) || ( s_flPreviousYaw - flCurrentYaw < -180.0f ) ) && - ( ( s_flPreviousYaw + flCurrentYaw > -180.0f ) && ( s_flPreviousYaw + flCurrentYaw < 180.0f ) ) ) - flYawDiffOriginal = s_flPreviousYaw + flCurrentYaw; + float flYawDiffOriginal = history.m_flPreviousYaw - flCurrentYaw; + if ( ( ( history.m_flPreviousYaw - flCurrentYaw > 180.0f ) || ( history.m_flPreviousYaw - flCurrentYaw < -180.0f ) ) && + ( ( history.m_flPreviousYaw + flCurrentYaw > -180.0f ) && ( history.m_flPreviousYaw + flCurrentYaw < 180.0f ) ) ) + flYawDiffOriginal = history.m_flPreviousYaw + flCurrentYaw; float flYawDiffAdjusted = flYawDiffOriginal + ( flSideDotMotion / 3.0f ); // Yes, 3.0 is a magic number, sue me @@ -2891,7 +3087,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h // Pitch (Compensate for forward motion) // //=======================================// float flPitchCompensateMask = 1.0f - ( ( 1.0f - fabs( vCurrentForwardVec[2] ) ) * ( 1.0f - fabs( vCurrentForwardVec[2] ) ) ); - float flPitchDiffOriginal = s_flPreviousPitch - flCurrentPitch; + float flPitchDiffOriginal = history.m_flPreviousPitch - flCurrentPitch; float flPitchDiffAdjusted = flPitchDiffOriginal; if ( flCurrentPitch > 0.0f ) @@ -2941,24 +3137,21 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //===============================================================// // Dampen motion blur from 100%-0% as fps drops from 50fps-30fps // //===============================================================// - if ( !IsX360() ) // I'm not doing this on the 360 yet since I can't test it - { - float flSlowFps = 30.0f; - float flFastFps = 50.0f; - float flCurrentFps = ( flTimeElapsed > 0.0f ) ? ( 1.0f / flTimeElapsed ) : 0.0f; - float flDampenFactor = clamp( ( ( flCurrentFps - flSlowFps ) / ( flFastFps - flSlowFps ) ), 0.0f, 1.0f ); + float flSlowFps = 30.0f; + float flFastFps = 50.0f; + float flCurrentFps = ( flTimeElapsed > 0.0f ) ? ( 1.0f / flTimeElapsed ) : 0.0f; + float flDampenFactor = clamp( ( ( flCurrentFps - flSlowFps ) / ( flFastFps - flSlowFps ) ), 0.0f, 1.0f ); - //engine->Con_NPrintf( 4, "gpGlobals->realtime %.2f gpGlobals->curtime %.2f", gpGlobals->realtime, gpGlobals->curtime ); - //engine->Con_NPrintf( 5, "flCurrentFps %.2f", flCurrentFps ); - //engine->Con_NPrintf( 7, "flTimeElapsed %.2f", flTimeElapsed ); + //engine->Con_NPrintf( 4, "gpGlobals->realtime %.2f gpGlobals->curtime %.2f", gpGlobals->realtime, gpGlobals->curtime ); + //engine->Con_NPrintf( 5, "flCurrentFps %.2f", flCurrentFps ); + //engine->Con_NPrintf( 7, "flTimeElapsed %.2f", flTimeElapsed ); - g_vMotionBlurValues[0] *= flDampenFactor; - g_vMotionBlurValues[1] *= flDampenFactor; - g_vMotionBlurValues[2] *= flDampenFactor; - g_vMotionBlurValues[3] *= flDampenFactor; + g_vMotionBlurValues[0] *= flDampenFactor; + g_vMotionBlurValues[1] *= flDampenFactor; + g_vMotionBlurValues[2] *= flDampenFactor; + g_vMotionBlurValues[3] *= flDampenFactor; - //engine->Con_NPrintf( 6, "Dampen: %.2f", flDampenFactor ); - } + //engine->Con_NPrintf( 6, "Dampen: %.2f", flDampenFactor ); //engine->Con_NPrintf( 6, "Final values: { %6.2f%%, %6.2f%%, %6.2f%%, %6.2f%% }", g_vMotionBlurValues[0]*100.0f, g_vMotionBlurValues[1]*100.0f, g_vMotionBlurValues[2]*100.0f, g_vMotionBlurValues[3]*100.0f ); } @@ -2966,7 +3159,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //============================================// // Zero out blur if still in that time window // //============================================// - if ( gpGlobals->realtime < s_flNoRotationalMotionBlurUntil ) + if ( gpGlobals->realtime < history.m_flNoRotationalMotionBlurUntil ) { //engine->Con_NPrintf( 9, " No Rotation @ %f ", gpGlobals->realtime ); @@ -2977,17 +3170,60 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h } else { - s_flNoRotationalMotionBlurUntil = 0.0f; + history.m_flNoRotationalMotionBlurUntil = 0.0f; } //====================================// // Store current frame for next frame // //====================================// - VectorCopy( vCurrentPosition, s_vPreviousPositon ); - s_mPreviousFrameBasisVectors = mCurrentBasisVectors; - s_flPreviousPitch = flCurrentPitch; - s_flPreviousYaw = flCurrentYaw; - s_flLastTimeUpdate = gpGlobals->realtime; + VectorCopy( vCurrentPosition, history.m_vPreviousPositon ); + history.m_mPreviousFrameBasisVectors = mCurrentBasisVectors; + history.m_flPreviousPitch = flCurrentPitch; + history.m_flPreviousYaw = flCurrentYaw; + history.m_flLastTimeUpdate = gpGlobals->realtime; + } + + //engine->Con_NPrintf( 6, "Final values: { %6.2f%%, %6.2f%%, %6.2f%%, %6.2f%% }", g_vMotionBlurValues[0]*100.0f, g_vMotionBlurValues[1]*100.0f, g_vMotionBlurValues[2]*100.0f, g_vMotionBlurValues[3]*100.0f ); + + //==========================================// + // Set global g_vMotionBlurViewportValues[] // + //==========================================// + if ( true ) + { + ITexture *pSrc = materials->FindTexture( "_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET ); + float flSrcWidth = ( float )pSrc->GetActualWidth(); + float flSrcHeight = ( float )pSrc->GetActualHeight(); + + // NOTE #1: float4 stored as ( minx, miny, maxy, maxx )...z&w have been swapped to save pixel shader instructions + // NOTE #2: This code should definitely work for 2 players (horizontal or vertical), or 4 players (4 corners), but + // it might have to be modified if we ever want to support other split screen configurations + + int nOffset; // Offset by one pixel to land in the correct half + + // Left + nOffset = ( x > 0 ) ? 1 : 0; + g_vMotionBlurViewportValues[0] = ( float )( x + nOffset ) / ( flSrcWidth - 1 ); + + // Right + nOffset = ( x < ( flSrcWidth - 1 ) ) ? -1 : 0; + g_vMotionBlurViewportValues[3] = ( float )( x + w + nOffset ) / ( flSrcWidth - 1 ); + + // Top + nOffset = ( y > 0 ) ? 1 : 0; // Offset by one pixel to land in the correct half + g_vMotionBlurViewportValues[1] = ( float )( y + nOffset ) / ( flSrcHeight - 1 ); + + // Bottom + nOffset = ( y < ( flSrcHeight - 1 ) ) ? -1 : 0; + g_vMotionBlurViewportValues[2] = ( float )( y + h + nOffset ) / ( flSrcHeight - 1 ); + + // Only allow clamping to happen in the middle of the screen, so nudge the clamp values out if they're on the border of the screen + for ( int i = 0; i < 4; i++ ) + { + if ( g_vMotionBlurViewportValues[i] <= 0.0f ) + g_vMotionBlurViewportValues[i] = -1.0f; + else if ( g_vMotionBlurViewportValues[i] >= 1.0f ) + g_vMotionBlurViewportValues[i] = 2.0f; + } } //=============================================================================================// @@ -3000,13 +3236,10 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h ITexture *pSrc = materials->FindTexture( "_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET ); int nSrcWidth = pSrc->GetActualWidth(); int nSrcHeight = pSrc->GetActualHeight(); - int dest_width, dest_height, nDummy; - pRenderContext->GetViewport( nDummy, nDummy, dest_width, dest_height ); + int nViewportWidth, nViewportHeight, nDummy; + pRenderContext->GetViewport( nDummy, nDummy, nViewportWidth, nViewportHeight ); - if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_FLOAT ) - { - UpdateScreenEffectTexture( 0, x, y, w, h, true ); // Do we need to check if we already did this? - } + UpdateScreenEffectTexture( 0, x, y, w, h, false ); // Get material pointer IMaterial *pMatMotionBlur = materials->FindMaterial( "dev/motion_blur", TEXTURE_GROUP_OTHER, true ); @@ -3018,14 +3251,200 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h { pRenderContext->DrawScreenSpaceRectangle( pMatMotionBlur, - 0, 0, dest_width, dest_height, - 0, 0, nSrcWidth-1, nSrcHeight-1, + 0, 0, nViewportWidth, nViewportHeight, + x, y, x + w-1, y + h-1, nSrcWidth, nSrcHeight, GetClientWorldEntity()->GetClientRenderable() ); - - if ( g_bDumpRenderTargets ) - { - DumpTGAofRenderTarget( dest_width, dest_height, "MotionBlur" ); - } } } } + +//===================================================================================================================== +// Depth of field ===================================================================================================== +//===================================================================================================================== +ConVar mat_dof_enabled( "mat_dof_enabled", "1" ); +ConVar mat_dof_override( "mat_dof_override", "0" ); +ConVar mat_dof_near_blur_depth( "mat_dof_near_blur_depth", "20.0" ); +ConVar mat_dof_near_focus_depth( "mat_dof_near_focus_depth", "100.0" ); +ConVar mat_dof_far_focus_depth( "mat_dof_far_focus_depth", "250.0" ); +ConVar mat_dof_far_blur_depth( "mat_dof_far_blur_depth", "1000.0" ); +ConVar mat_dof_near_blur_radius( "mat_dof_near_blur_radius", "0.0" ); +ConVar mat_dof_far_blur_radius( "mat_dof_far_blur_radius", "10.0" ); +ConVar mat_dof_quality( "mat_dof_quality", "3" ); + +static float GetNearBlurDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_near_blur_depth.GetFloat() : g_flDOFNearBlurDepth; +} + +static float GetNearFocusDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_near_focus_depth.GetFloat() : g_flDOFNearFocusDepth; +} + +static float GetFarFocusDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_far_focus_depth.GetFloat() : g_flDOFFarFocusDepth; +} + +static float GetFarBlurDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_far_blur_depth.GetFloat() : g_flDOFFarBlurDepth; +} + +static float GetNearBlurRadius() +{ + return mat_dof_override.GetBool() ? mat_dof_near_blur_radius.GetFloat() : g_flDOFNearBlurRadius; +} + +static float GetFarBlurRadius() +{ + return mat_dof_override.GetBool() ? mat_dof_far_blur_radius.GetFloat() : g_flDOFFarBlurRadius; +} + +bool IsDepthOfFieldEnabled() +{ + const CViewSetup *pViewSetup = view->GetViewSetup(); + if ( !pViewSetup ) + return false; + + if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 92 ) + return false; + + if ( !mat_dof_enabled.GetBool() ) + return false; + + if ( mat_dof_override.GetBool() == true ) + { + return mat_dof_enabled.GetBool(); + } + else + { + return g_bDOFEnabled; + } +} + +static inline bool SetMaterialVarFloat( IMaterial* pMat, const char* pVarName, float flValue ) +{ + Assert( pMat != NULL ); + Assert( pVarName != NULL ); + if ( pMat == NULL || pVarName == NULL ) + { + return false; + } + + bool bFound = false; + IMaterialVar* pVar = pMat->FindVar( pVarName, &bFound ); + if ( bFound ) + { + pVar->SetFloatValue( flValue ); + } + + return bFound; +} + +static inline bool SetMaterialVarInt( IMaterial* pMat, const char* pVarName, int nValue ) +{ + Assert( pMat != NULL ); + Assert( pVarName != NULL ); + if ( pMat == NULL || pVarName == NULL ) + { + return false; + } + + bool bFound = false; + IMaterialVar* pVar = pMat->FindVar( pVarName, &bFound ); + if ( bFound ) + { + pVar->SetIntValue( nValue ); + } + + return bFound; +} + +void DoDepthOfField( const CViewSetup &viewSetup ) +{ + if ( !IsDepthOfFieldEnabled() ) + { + return; + } + + // Copy from backbuffer to _rt_FullFrameFB + UpdateScreenEffectTexture( 0, viewSetup.x, viewSetup.y, viewSetup.width, viewSetup.height, false ); // Do we need to check if we already did this? + + CMatRenderContextPtr pRenderContext( materials ); + + ITexture *pSrc = materials->FindTexture( "_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET ); + int nSrcWidth = pSrc->GetActualWidth(); + int nSrcHeight = pSrc->GetActualHeight(); + + int nViewportWidth = 0; + int nViewportHeight = 0; + int nDummy = 0; + pRenderContext->GetViewport( nDummy, nDummy, nViewportWidth, nViewportHeight ); + + if ( mat_dof_quality.GetInt() < 2 ) + { + ///////////////////////////////////// + // Downsample backbuffer to 1/4 size + ///////////////////////////////////// + + // Update downsampled framebuffer. TODO: Don't do this again for the bloom if we already did it here... + pRenderContext->PushRenderTargetAndViewport(); + ITexture *dest_rt0 = materials->FindTexture( "_rt_SmallFB0", TEXTURE_GROUP_RENDER_TARGET ); + + // *Everything* in here relies on the small RTs being exactly 1/4 the full FB res + Assert( dest_rt0->GetActualWidth() == pSrc->GetActualWidth() / 4 ); + Assert( dest_rt0->GetActualHeight() == pSrc->GetActualHeight() / 4 ); + + // Downsample fb to rt0 + DownsampleFBQuarterSize( pRenderContext, nSrcWidth, nSrcHeight, dest_rt0, true ); + + ////////////////////////////////////// + // Additional blur using 3x3 gaussian + ////////////////////////////////////// + + IMaterial *pMat = materials->FindMaterial( "dev/blurgaussian_3x3", TEXTURE_GROUP_OTHER, true ); + + if ( pMat == NULL ) + return; + + SetMaterialVarFloat( pMat, "$c0_x", 0.5f / (float)dest_rt0->GetActualWidth() ); + SetMaterialVarFloat( pMat, "$c0_y", 0.5f / (float)dest_rt0->GetActualHeight() ); + SetMaterialVarFloat( pMat, "$c1_x", -0.5f / (float)dest_rt0->GetActualWidth() ); + SetMaterialVarFloat( pMat, "$c1_y", 0.5f / (float)dest_rt0->GetActualHeight() ); + + ITexture *dest_rt1 = materials->FindTexture( "_rt_SmallFB1", TEXTURE_GROUP_RENDER_TARGET ); + SetRenderTargetAndViewPort( dest_rt1 ); + + pRenderContext->DrawScreenSpaceRectangle( + pMat, 0, 0, nSrcWidth/4, nSrcHeight/4, + 0, 0, dest_rt0->GetActualWidth()-1, dest_rt0->GetActualHeight()-1, + dest_rt0->GetActualWidth(), dest_rt0->GetActualHeight() ); + + pRenderContext->PopRenderTargetAndViewport(); + } + + // Render depth-of-field quad + IMaterial *pMatDOF = materials->FindMaterial( "dev/depth_of_field", TEXTURE_GROUP_OTHER, true ); + + if ( pMatDOF == NULL ) + return; + + SetMaterialVarFloat( pMatDOF, "$nearPlane", viewSetup.zNear ); + SetMaterialVarFloat( pMatDOF, "$farPlane", viewSetup.zFar ); + + // pull from convars/globals + SetMaterialVarFloat( pMatDOF, "$nearBlurDepth", GetNearBlurDepth() ); + SetMaterialVarFloat( pMatDOF, "$nearFocusDepth", GetNearFocusDepth() ); + SetMaterialVarFloat( pMatDOF, "$farFocusDepth", GetFarFocusDepth() ); + SetMaterialVarFloat( pMatDOF, "$farBlurDepth", GetFarBlurDepth() ); + SetMaterialVarFloat( pMatDOF, "$nearBlurRadius", GetNearBlurRadius() ); + SetMaterialVarFloat( pMatDOF, "$farBlurRadius", GetFarBlurRadius() ); + SetMaterialVarInt( pMatDOF, "$quality", mat_dof_quality.GetInt() ); + + pRenderContext->DrawScreenSpaceRectangle( + pMatDOF, + 0, 0, nViewportWidth, nViewportHeight, + 0, 0, nSrcWidth-1, nSrcHeight-1, + nSrcWidth, nSrcHeight, GetClientWorldEntity()->GetClientRenderable() ); +} diff --git a/sp/src/game/client/viewpostprocess.h b/sp/src/game/client/viewpostprocess.h index eb2ad9cc..f40a6937 100644 --- a/sp/src/game/client/viewpostprocess.h +++ b/sp/src/game/client/viewpostprocess.h @@ -11,8 +11,20 @@ #pragma once #endif +struct PostProcessParameters_t; + void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, bool bPostVGui = false ); -void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h ); +void DoImageSpaceMotionBlur( const CViewSetup &viewSetup ); void DumpTGAofRenderTarget( const int width, const int height, const char *pFilename ); +void SetRenderTargetAndViewPort( ITexture *rt ); + +bool IsDepthOfFieldEnabled(); +void DoDepthOfField( const CViewSetup &view ); + +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters ); +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters, bool override ); + +void SetViewFadeParams( byte r, byte g, byte b, byte a, bool bModulate ); + #endif // VIEWPOSTPROCESS_H diff --git a/sp/src/game/client/viewrender.cpp b/sp/src/game/client/viewrender.cpp index 4ad77e8c..29f9c651 100644 --- a/sp/src/game/client/viewrender.cpp +++ b/sp/src/game/client/viewrender.cpp @@ -823,6 +823,8 @@ CLIENTEFFECT_REGISTER_BEGIN( PrecachePostProcessingEffects ) CLIENTEFFECT_MATERIAL( "dev/copyfullframefb_vanilla" ) CLIENTEFFECT_MATERIAL( "dev/copyfullframefb" ) CLIENTEFFECT_MATERIAL( "dev/engine_post" ) + CLIENTEFFECT_MATERIAL( "dev/depth_of_field" ) + CLIENTEFFECT_MATERIAL( "dev/blurgaussian_3x3" ) CLIENTEFFECT_MATERIAL( "dev/motion_blur" ) CLIENTEFFECT_MATERIAL( "dev/upscale" ) @@ -2104,14 +2106,24 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT RenderPlayerSprites(); // Image-space motion blur - if ( !building_cubemaps.GetBool() && view.m_bDoBloomAndToneMapping ) // We probably should use a different view. variable here + if ( !building_cubemaps.GetBool() /*&& view.m_bDoBloomAndToneMapping*/ ) // We probably should use a different view. variable here { + if ( IsDepthOfFieldEnabled() ) + { + pRenderContext.GetFrom( materials ); + { + PIXEVENT( pRenderContext, "DoDepthOfField()" ); + DoDepthOfField( view ); + } + pRenderContext.SafeRelease(); + } + if ( ( mat_motion_blur_enabled.GetInt() ) && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 90 ) ) { pRenderContext.GetFrom( materials ); { PIXEVENT( pRenderContext, "DoImageSpaceMotionBlur" ); - DoImageSpaceMotionBlur( view, view.x, view.y, view.width, view.height ); + DoImageSpaceMotionBlur( view ); } pRenderContext.SafeRelease(); } diff --git a/sp/src/game/server/ai_basenpc.cpp b/sp/src/game/server/ai_basenpc.cpp index e18fbb34..6333ed86 100644 --- a/sp/src/game/server/ai_basenpc.cpp +++ b/sp/src/game/server/ai_basenpc.cpp @@ -562,7 +562,7 @@ void CAI_BaseNPC::CleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput ) RemoveActorFromScriptedScenes( this, false /*all scenes*/ ); } else - DevMsg( "Unexpected double-death-cleanup\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "Unexpected double-death-cleanup\n" ); } void CAI_BaseNPC::SelectDeathPose( const CTakeDamageInfo &info ) @@ -2532,7 +2532,7 @@ void CAI_BaseNPC::OnListened() case SOUND_PLAYER_VEHICLE: condition = COND_HEAR_PLAYER; break; default: - DevMsg( "**ERROR: NPC %s hearing sound of unknown type %d!\n", GetClassname(), pCurrentSound->SoundType() ); + CGMsg( 1, CON_GROUP_NPC_AI, "**ERROR: NPC %s hearing sound of unknown type %d!\n", GetClassname(), pCurrentSound->SoundType() ); break; } } @@ -2720,7 +2720,7 @@ CSound* CAI_BaseNPC::GetBestSound( int validTypes ) return m_pLockedBestSound; CSound *pResult = GetSenses()->GetClosestSound( false, validTypes ); if ( pResult == NULL) - DevMsg( "Warning: NULL Return from GetBestSound\n" ); // condition previously set now no longer true. Have seen this when play too many sounds... + CGMsg( 1, CON_GROUP_NPC_AI, "Warning: NULL Return from GetBestSound\n" ); // condition previously set now no longer true. Have seen this when play too many sounds... return pResult; } @@ -2732,7 +2732,7 @@ CSound* CAI_BaseNPC::GetBestScent( void ) { CSound *pResult = GetSenses()->GetClosestSound( true ); if ( pResult == NULL) - DevMsg("Warning: NULL Return from GetBestScent\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "Warning: NULL Return from GetBestScent\n" ); return pResult; } @@ -4806,7 +4806,11 @@ void CAI_BaseNPC::SetState( NPC_STATE State ) if ( GetEnemy() != NULL ) { SetEnemy( NULL ); // not allowed to have an enemy anymore. +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_NPC_AI, "Stripped enemy pointer from NPC going back to idle\n" ); +#else DevMsg( 2, "Stripped\n" ); +#endif } break; } @@ -5199,7 +5203,7 @@ void CAI_BaseNPC::GatherConditions( void ) // @Note (toml 05-05-04): There seems to be a case where an NPC can not respond // to COND_NEW_ENEMY. Only evidence right now is save // games after the fact, so for now, just patching it up - DevMsg( 2, "Had to force COND_NEW_ENEMY\n" ); + CGMsg( 2, CON_GROUP_NPC_AI, "Had to force COND_NEW_ENEMY\n" ); SetCondition(COND_NEW_ENEMY); } } @@ -8528,7 +8532,7 @@ bool CAI_BaseNPC::InitSquad( void ) { if ( !m_SquadName ) { - DevMsg(2, "Found %s that isn't in a squad\n",GetClassname()); + CGMsg( 2, CON_GROUP_NPC_AI, "Found %s that isn't in a squad\n", GetClassname() ); } else { @@ -9181,7 +9185,7 @@ void CAI_BaseNPC::SetDefaultEyeOffset ( void ) { if ( Classify() != CLASS_NONE ) { - DevMsg( "WARNING: %s(%s) has no eye offset in .qc!\n", GetClassname(), STRING(GetModelName()) ); + CGMsg( 1, CON_GROUP_NPC_AI, "WARNING: %s(%s) has no eye offset in .qc!\n", GetClassname(), STRING( GetModelName() ) ); } VectorAdd( WorldAlignMins(), WorldAlignMaxs(), m_vDefaultEyeOffset ); m_vDefaultEyeOffset *= 0.75; @@ -11392,7 +11396,7 @@ bool CAI_BaseNPC::ChooseEnemy( void ) } else if ( !fHaveCondNewEnemy && !fHaveCondLostEnemy && GetCurSchedule() ) { - DevMsg( 2, "WARNING: AI enemy went NULL but schedule (%s) is not interested\n", GetCurSchedule()->GetName() ); + CGMsg( 2, CON_GROUP_NPC_AI, "WARNING: AI enemy went NULL but schedule (%s) is not interested\n", GetCurSchedule()->GetName() ); } m_bSkippedChooseEnemy = false; @@ -12016,6 +12020,15 @@ BEGIN_ENT_SCRIPTDESC( CAI_BaseNPC, CBaseCombatCharacter, "The base class all NPC DEFINE_SCRIPTFUNC_NAMED( VScriptGetState, "GetNPCState", "Get the NPC's current state." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptWake, "Wake", "Awakens the NPC if it is currently asleep." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSleep, "Sleep", "Puts the NPC into a sleeping state." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetSleepState, "GetSleepState", "Get the NPC's sleep state. (see AISS_ set of constants)" ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSetSleepState, "SetSleepState", "Set the NPC's sleep state. (see AISS_ set of constants)" ) + DEFINE_SCRIPTFUNC( AddSleepFlags, "Add to the NPC's sleep flags. (see AI_SLEEP_ set of constants)" ) + DEFINE_SCRIPTFUNC( RemoveSleepFlags, "Remove from NPC's sleep flags. (see AI_SLEEP_ set of constants)" ) + DEFINE_SCRIPTFUNC( HasSleepFlags, "Return true if the NPC has the specified sleep flags. (see AI_SLEEP_ set of constants)" ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetHintGroup, "GetHintGroup", "Get the name of the NPC's hint group." ) DEFINE_SCRIPTFUNC_NAMED( VScriptGetHintNode, "GetHintNode", "Get the NPC's current AI hint." ) @@ -12375,7 +12388,7 @@ void CAI_BaseNPC::DiscardScheduleState() // for now, just go back to idle and let the AI figure out what to do. SetState( NPC_STATE_IDLE ); SetIdealState( NPC_STATE_IDLE ); - DevMsg(1, "Scripted Sequence stripped on level transition for %s\n", GetDebugName() ); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted Sequence stripped on level transition for %s\n", GetDebugName() ); } } @@ -12759,7 +12772,7 @@ void CAI_BaseNPC::UpdateOnRemove(void) if ( !m_bDidDeathCleanup ) { if ( m_NPCState == NPC_STATE_DEAD ) - DevMsg( "May not have cleaned up on NPC death\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "May not have cleaned up on NPC death\n" ); CleanupOnDeath( NULL, false ); } @@ -13894,7 +13907,7 @@ static void AIMsgGuts( CAI_BaseNPC *pAI, unsigned flags, const char *pszMsg ) else pszFmt2 = "%s (%s: %d/%s) [%d]"; - DevMsg( pszFmt2, + CGMsg( 1, CON_GROUP_NPC_AI, pszFmt2, pszMsg, pAI->GetClassname(), pAI->entindex(), diff --git a/sp/src/game/server/ai_basenpc.h b/sp/src/game/server/ai_basenpc.h index cd909f33..74ef79bf 100644 --- a/sp/src/game/server/ai_basenpc.h +++ b/sp/src/game/server/ai_basenpc.h @@ -1224,6 +1224,12 @@ public: int VScriptGetState(); + void VScriptWake( HSCRIPT hActivator ) { Wake( ToEnt(hActivator) ); } + void VScriptSleep() { Sleep(); } + + int VScriptGetSleepState() { return (int)GetSleepState(); } + void VScriptSetSleepState( int sleepState ) { SetSleepState( (AI_SleepState_t)sleepState ); } + const char* VScriptGetHintGroup() { return STRING( GetHintGroup() ); } HSCRIPT VScriptGetHintNode(); @@ -2893,7 +2899,11 @@ public: derivedClass::AccessClassScheduleIdSpaceDirect().Init( #derivedClass, BaseClass::GetSchedulingSymbols(), &BaseClass::AccessClassScheduleIdSpaceDirect() ); \ derivedClass::gm_SquadSlotIdSpace.Init( &CAI_BaseNPC::gm_SquadSlotNamespace, &BaseClass::gm_SquadSlotIdSpace); +#ifdef MAPBASE +#define ADD_CUSTOM_INTERACTION( interaction ) { CBaseCombatCharacter::AddInteractionWithString( interaction, #interaction ); } +#else #define ADD_CUSTOM_INTERACTION( interaction ) { interaction = CBaseCombatCharacter::GetInteractionID(); } +#endif #define ADD_CUSTOM_SQUADSLOT_NAMED(derivedClass,squadSlotName,squadSlotEN)\ if ( !derivedClass::gm_SquadSlotIdSpace.AddSymbol( squadSlotName, squadSlotEN, "squadslot", derivedClass::gm_pszErrorClassName ) ) return; diff --git a/sp/src/game/server/ai_basenpc_schedule.cpp b/sp/src/game/server/ai_basenpc_schedule.cpp index 64a51518..10bf02e5 100644 --- a/sp/src/game/server/ai_basenpc_schedule.cpp +++ b/sp/src/game/server/ai_basenpc_schedule.cpp @@ -470,7 +470,7 @@ CAI_Schedule *CAI_BaseNPC::GetNewSchedule( void ) // You may not be in combat state with no enemy!!! (sjb) 11/4/03 if( m_NPCState == NPC_STATE_COMBAT && !GetEnemy() ) { - DevMsg("**ERROR: Combat State with no enemy! slamming to ALERT\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "**ERROR: Combat State with no enemy! slamming to ALERT\n" ); SetState( NPC_STATE_ALERT ); } @@ -693,7 +693,7 @@ void CAI_BaseNPC::MaintainSchedule ( void ) if ( !GetCurSchedule() || GetCurSchedule()->NumTasks() == 0 ) { - DevMsg("ERROR: Missing or invalid schedule!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR: Missing or invalid schedule!\n" ); SetActivity ( ACT_IDLE ); return; } @@ -1007,7 +1007,7 @@ bool CAI_BaseNPC::FindCoverFromBestSound( Vector *pCoverPos ) } else { - DevMsg( 2, "Attempting to find cover from best sound, but best sound not founc.\n" ); + CGMsg( 2, CON_GROUP_NPC_AI, "Attempting to find cover from best sound, but best sound not founc.\n" ); } return false; @@ -2743,7 +2743,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) case TASK_SOUND_ANGRY: { // sounds are complete as soon as we get here, cause we've already played them. - DevMsg( 2, "SOUND\n" ); + CGMsg( 2, CON_GROUP_NPC_AI, "SOUND\n" ); TaskComplete(); break; } @@ -2785,11 +2785,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) { if ( !m_hCine ) { -#ifdef MAPBASE CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); -#else - DevMsg( "Scripted sequence destroyed while in use\n" ); -#endif TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } @@ -2800,11 +2796,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) { if ( !m_hCine ) { -#ifdef MAPBASE CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); -#else - DevMsg( "Scripted sequence destroyed while in use\n" ); -#endif TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } @@ -3151,7 +3143,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) default: { - DevMsg( "No StartTask entry for %s\n", TaskName( task ) ); + CGMsg( 1, CON_GROUP_NPC_AI, "No StartTask entry for %s\n", TaskName( task ) ); } break; } @@ -3298,7 +3290,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) // Put a debugging check in here if (GetHintNode()->User() != this) { - DevMsg("Hint node (%s) being used by non-owner!\n",GetHintNode()->GetDebugName()); + CGMsg( 1, CON_GROUP_NPC_AI, "Hint node (%s) being used by non-owner!\n", GetHintNode()->GetDebugName() ); } if ( IsActivityFinished() ) @@ -4005,11 +3997,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) } else if (!m_hCine) { -#ifdef MAPBASE CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Cine died!\n" ); -#else - DevMsg( "Cine died!\n"); -#endif TaskComplete(); } else if ( IsRunningDynamicInteraction() ) @@ -4065,11 +4053,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) { if ( !m_hCine ) { -#ifdef MAPBASE CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); -#else - DevMsg( "Scripted sequence destroyed while in use\n" ); -#endif TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } @@ -4088,11 +4072,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) { if ( !m_hCine ) { -#ifdef MAPBASE CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); -#else - DevMsg( "Scripted sequence destroyed while in use\n" ); -#endif TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } @@ -4249,7 +4229,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) default: { - DevMsg( "No RunTask entry for %s\n", TaskName( pTask->iTask ) ); + CGMsg( 1, CON_GROUP_NPC_AI, "No RunTask entry for %s\n", TaskName( pTask->iTask ) ); TaskComplete(); } break; @@ -4421,11 +4401,7 @@ int CAI_BaseNPC::GetScriptCustomMoveSequence( void ) iSequence = LookupSequence( STRING( m_hCine->m_iszCustomMove ) ); if ( iSequence == ACTIVITY_NOT_AVAILABLE ) { -#ifdef MAPBASE CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "SCRIPT_CUSTOM_MOVE: %s has no sequence:%s\n", GetClassname(), STRING(m_hCine->m_iszCustomMove) ); -#else - DevMsg( "SCRIPT_CUSTOM_MOVE: %s has no sequence:%s\n", GetClassname(), STRING(m_hCine->m_iszCustomMove) ); -#endif } } else if ( m_iszSceneCustomMoveSeq != NULL_STRING ) diff --git a/sp/src/game/server/ai_speech.cpp b/sp/src/game/server/ai_speech.cpp index bdc0cd63..60190744 100644 --- a/sp/src/game/server/ai_speech.cpp +++ b/sp/src/game/server/ai_speech.cpp @@ -192,8 +192,13 @@ BEGIN_SCRIPTDESC_ROOT( CAI_Expresser, "Expresser class for complex speech." ) DEFINE_SCRIPTFUNC( BlockSpeechUntil, "Block speech for a certain amount of time. This is stored in curtime." ) DEFINE_SCRIPTFUNC( ForceNotSpeaking, "If the actor is speaking, force the system to recognize them as not speaking." ) + DEFINE_SCRIPTFUNC( GetVoicePitch, "Get the actor's voice pitch. Used in sentences." ) + DEFINE_SCRIPTFUNC( SetVoicePitch, "Set the actor's voice pitch. Used in sentences." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakRawScene, "SpeakRawScene", "Speak a raw, instanced VCD scene as though it were played through the Response System. Return whether the scene successfully plays." ) DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakAutoGeneratedScene, "SpeakAutoGeneratedScene", "Speak an automatically generated, instanced VCD scene for this sound as though it were played through the Response System. Return whether the scene successfully plays." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakRawSentence, "SpeakRawSentence", "Speak a raw sentence as though it were played through the Response System. Return the sentence's index; -1 if not successfully played." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeak, "Speak", "Speak a response concept with the specified modifiers." ) END_SCRIPTDESC(); #endif @@ -565,7 +570,7 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res if (replace) { - DevMsg("Replacing %s with %s...\n", response, replace); + CGMsg( 1, CON_GROUP_CHOREO, "Replacing %s with %s...\n", response, replace ); Q_strncpy(response, replace, sizeof(response)); // Precache it now because it may not have been precached before @@ -596,7 +601,7 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res if ( IsSpeaking() && concept[0] != 0 ) { - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); + CGMsg( 1, CON_GROUP_CHOREO, "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); // Tracker 15911: Can break the game if we stop an imported map placed lcs here, so only // cancel actor out of instanced scripted scenes. ywb @@ -605,7 +610,7 @@ 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 ); + CGMsg( 1, CON_GROUP_CHOREO, "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); delete result; return false; } @@ -633,7 +638,7 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res float speakTime = GetResponseDuration( result ); GetOuter()->EmitSound( response ); - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); + CGMsg( 1, CON_GROUP_CHOREO, "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); NoteSpeaking( speakTime, delay ); spoke = true; } @@ -1205,7 +1210,7 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ) } else { - DevMsg( "%s", string ); + CGMsg( 1, CON_GROUP_CHOREO "%s", string ); } UTIL_LogPrintf( string ); } diff --git a/sp/src/game/server/ai_speech.h b/sp/src/game/server/ai_speech.h index da204c5f..5ed12255 100644 --- a/sp/src/game/server/ai_speech.h +++ b/sp/src/game/server/ai_speech.h @@ -206,7 +206,8 @@ public: #ifdef MAPBASE_VSCRIPT bool ScriptSpeakRawScene( char const *soundname, float delay ) { return SpeakRawScene( soundname, delay, NULL ); } bool ScriptSpeakAutoGeneratedScene( char const *soundname, float delay ) { return SpeakAutoGeneratedScene( soundname, delay ); } - bool ScriptSpeak( AIConcept_t concept, const char *modifiers ) { return Speak( concept, modifiers ); } + int ScriptSpeakRawSentence( char const *pszSentence, float delay ) { return SpeakRawSentence( pszSentence, delay ); } + bool ScriptSpeak( char const *concept, const char *modifiers ) { return Speak( concept, modifiers[0] != '\0' ? modifiers : NULL ); } #endif protected: diff --git a/sp/src/game/server/ai_squad.cpp b/sp/src/game/server/ai_squad.cpp index bdd58d5d..15e7fb68 100644 --- a/sp/src/game/server/ai_squad.cpp +++ b/sp/src/game/server/ai_squad.cpp @@ -294,7 +294,7 @@ void CAI_Squad::RemoveFromSquad( CAI_BaseNPC *pNPC, bool bDeath ) int myIndex = m_SquadMembers.Find(pNPC); if (myIndex == -1) { - DevMsg("ERROR: Attempting to remove non-existing squad membmer!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR: Attempting to remove non-existing squad member!\n" ); return; } m_SquadMembers.Remove(myIndex); @@ -337,7 +337,7 @@ void CAI_Squad::AddToSquad(CAI_BaseNPC *pNPC) if (m_SquadMembers.Count() == MAX_SQUAD_MEMBERS) { - DevMsg("Error!! Squad %s is too big!!! Replacing last member\n", STRING( this->m_Name )); + CGMsg( 1, CON_GROUP_NPC_AI, "Error!! Squad %s is too big!!! Replacing last member\n", STRING( this->m_Name ) ); m_SquadMembers.Remove(m_SquadMembers.Count()-1); } m_SquadMembers.AddToTail(pNPC); @@ -559,7 +559,7 @@ void CAI_Squad::SquadNewEnemy( CBaseEntity *pEnemy ) { if ( !pEnemy ) { - DevMsg( "ERROR: SquadNewEnemy() - pEnemy is NULL!\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR: SquadNewEnemy() - pEnemy is NULL!\n" ); return; } @@ -678,7 +678,7 @@ bool CAI_Squad::OccupyStrategySlotRange( CBaseEntity *pEnemy, int slotIDStart, i // As a debug measure check to see if slot was filled if (!IsSlotOccupied(pEnemy, *pSlot)) { - DevMsg( "ERROR! Vacating an empty slot!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR! Vacating an empty slot!\n" ); } // Free the slot @@ -717,7 +717,7 @@ void CAI_Squad::VacateStrategySlot( CBaseEntity *pEnemy, int slot) // As a debug measure check to see if slot was filled if (!IsSlotOccupied(pEnemy, slot)) { - DevMsg( "ERROR! Vacating an empty slot!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR! Vacating an empty slot!\n" ); } // Free the slot diff --git a/sp/src/game/server/baseanimating.cpp b/sp/src/game/server/baseanimating.cpp index 0d6055bb..753cfc6a 100644 --- a/sp/src/game/server/baseanimating.cpp +++ b/sp/src/game/server/baseanimating.cpp @@ -326,9 +326,13 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" ) DEFINE_SCRIPTFUNC( GetBodygroupCount, "Gets the number of models in a bodygroup" ) DEFINE_SCRIPTFUNC( GetNumBodyGroups, "Gets the number of bodygroups" ) - DEFINE_SCRIPTFUNC( Dissolve, "" ) - DEFINE_SCRIPTFUNC( Ignite, "" ) + DEFINE_SCRIPTFUNC( Dissolve, "Use 'sprites/blueglow1.vmt' for the default material, Time() for the default start time, false for npcOnly if you don't want it to check if the entity is a NPC first, 0 for the default dissolve type, Vector(0,0,0) for the default dissolver origin, and 0 for the default magnitude." ) + DEFINE_SCRIPTFUNC( Ignite, "'NPCOnly' only lets this fall through if the entity is a NPC and 'CalledByLevelDesigner' determines whether to treat this like the Ignite input or just an internal ignition call." ) DEFINE_SCRIPTFUNC( Scorch, "Makes the entity darker from scorching" ) + + DEFINE_SCRIPTFUNC( BecomeRagdollOnClient, "" ) + DEFINE_SCRIPTFUNC( IsRagdoll, "" ) + DEFINE_SCRIPTFUNC( CanBecomeRagdoll, "" ) #endif END_SCRIPTDESC(); @@ -727,7 +731,7 @@ void CBaseAnimating::InputSetModelScale( inputdata_t &inputdata ) void CBaseAnimating::InputSetModel( inputdata_t &inputdata ) { const char *szModel = inputdata.value.String(); - if (PrecacheModel(szModel) != -1) + if (PrecacheModel(szModel, false) != -1) { SetModelName(AllocPooledString(szModel)); SetModel(szModel); diff --git a/sp/src/game/server/basecombatcharacter.cpp b/sp/src/game/server/basecombatcharacter.cpp index 1241e738..b740e3f0 100644 --- a/sp/src/game/server/basecombatcharacter.cpp +++ b/sp/src/game/server/basecombatcharacter.cpp @@ -163,6 +163,7 @@ BEGIN_ENT_SCRIPTDESC( CBaseCombatCharacter, CBaseFlex, "The base class shared by DEFINE_SCRIPTFUNC_NAMED( Weapon_ShootPosition, "ShootPosition", "Get the character's shoot position." ) DEFINE_SCRIPTFUNC_NAMED( Weapon_DropAll, "DropAllWeapons", "Make the character drop all of its weapons." ) DEFINE_SCRIPTFUNC_NAMED( ScriptEquipWeapon, "EquipWeapon", "Make the character equip the specified weapon entity. If they don't already own the weapon, they will acquire it instantly." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptDropWeapon, "DropWeapon", "Make the character drop the specified weapon entity if they own it." ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetAmmoCount, "GetAmmoCount", "Get the ammo count of the specified ammo type." ) DEFINE_SCRIPTFUNC_NAMED( ScriptSetAmmoCount, "SetAmmoCount", "Set the ammo count of the specified ammo type." ) @@ -309,6 +310,21 @@ int CBaseCombatCharacter::GetInteractionID(void) return (m_lastInteraction); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: New method of adding interactions which allows their name to be available (currently used for VScript) +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::AddInteractionWithString( int &interaction, const char *szName ) +{ + interaction = GetInteractionID(); + + if (g_pScriptVM) + { + ScriptRegisterConstantNamed( g_pScriptVM, interaction, szName, "An interaction which could be used with HandleInteraction or DispatchInteraction. NOTE: These are usually only initialized by certain types of NPCs when an instance of one spawns in the level for the first time!!! (the fact you're seeing this one means there was an NPC in the level which initialized it)" ); + } +} +#endif + // ============================================================================ bool CBaseCombatCharacter::HasHumanGibs( void ) { @@ -4405,13 +4421,31 @@ void CBaseCombatCharacter::GetScriptAllWeapons( HSCRIPT hTable ) } } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::ScriptDropWeapon( HSCRIPT hWeapon ) +{ + CBaseCombatWeapon *pWeapon = HScriptToClass( hWeapon ); + if (!pWeapon) + return; + + if (pWeapon->GetOwner() == this) + { + // Drop the weapon + Weapon_Drop( pWeapon ); + } + else + { + CGMsg( 1, CON_GROUP_VSCRIPT, "ScriptDropWeapon: %s is not owned by %s", pWeapon->GetDebugName(), GetDebugName() ); + } +} + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CBaseCombatCharacter::ScriptEquipWeapon( HSCRIPT hWeapon ) { - CBaseEntity *pEntity = ToEnt( hWeapon ); - CBaseCombatWeapon *pWeapon = pEntity->MyCombatWeaponPointer(); - if (!pEntity || !pWeapon) + CBaseCombatWeapon *pWeapon = HScriptToClass( hWeapon ); + if (!pWeapon) return; if (pWeapon->GetOwner() == this) diff --git a/sp/src/game/server/basecombatcharacter.h b/sp/src/game/server/basecombatcharacter.h index 9c4e2fca..6d971ca3 100644 --- a/sp/src/game/server/basecombatcharacter.h +++ b/sp/src/game/server/basecombatcharacter.h @@ -161,8 +161,10 @@ public: virtual bool ShouldShootMissTarget( CBaseCombatCharacter *pAttacker ); virtual CBaseEntity *FindMissTarget( void ); +#ifndef MAPBASE // This function now exists in CBaseEntity // Do not call HandleInteraction directly, use DispatchInteraction bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return ( interactionType > 0 ) ? HandleInteraction( interactionType, data, sourceEnt ) : false; } +#endif virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ); virtual QAngle BodyAngles(); @@ -421,6 +423,7 @@ public: void GetScriptAllWeapons( HSCRIPT hTable ); int ScriptGetCurrentWeaponProficiency() { return GetCurrentWeaponProficiency(); } + void ScriptDropWeapon( HSCRIPT hWeapon ); void ScriptEquipWeapon( HSCRIPT hWeapon ); int ScriptGetAmmoCount( int iType ) const; @@ -579,6 +582,11 @@ protected: public: static int GetInteractionID(); // Returns the next interaction # +#ifdef MAPBASE + // Mapbase's new method for adding interactions which allows them to be handled with their names, currently for VScript + static void AddInteractionWithString( int &interaction, const char *szName ); +#endif + protected: // Visibility-related stuff bool ComputeLOS( const Vector &vecEyePosition, const Vector &vecTarget ) const; diff --git a/sp/src/game/server/baseentity.cpp b/sp/src/game/server/baseentity.cpp index cd21794c..3cca68f5 100644 --- a/sp/src/game/server/baseentity.cpp +++ b/sp/src/game/server/baseentity.cpp @@ -2214,6 +2214,7 @@ ScriptHook_t CBaseEntity::g_Hook_UpdateOnRemove; ScriptHook_t CBaseEntity::g_Hook_VPhysicsCollision; ScriptHook_t CBaseEntity::g_Hook_FireBullets; ScriptHook_t CBaseEntity::g_Hook_OnDeath; +ScriptHook_t CBaseEntity::g_Hook_HandleInteraction; #endif BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" ) @@ -2328,13 +2329,16 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" DEFINE_SCRIPTFUNC_NAMED( ScriptGetContext, "GetContext", "Get a response context value" ) DEFINE_SCRIPTFUNC_NAMED( ScriptAddContext, "AddContext", "Add a response context value" ) + DEFINE_SCRIPTFUNC( GetContextExpireTime, "Get a response context's expiration time" ) + DEFINE_SCRIPTFUNC( GetContextCount, "Get the number of response contexts" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetContextIndex, "GetContextIndex", "Get a response context at a specific index in the form of a table" ) DEFINE_SCRIPTFUNC_NAMED( ScriptFollowEntity, "FollowEntity", "Begin following the specified entity. This makes this entity non-solid, parents it to the target entity, and teleports it to the specified entity's origin. The second parameter is whether or not to use bonemerging while following." ) DEFINE_SCRIPTFUNC( StopFollowingEntity, "Stops following an entity if we're following one." ) DEFINE_SCRIPTFUNC( IsFollowingEntity, "Returns true if this entity is following another entity." ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetFollowedEntity, "GetFollowedEntity", "Get the entity we're following." ) - DEFINE_SCRIPTFUNC_NAMED( ScriptClassify, "Classify", "Get Class_T class ID" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptClassify, "Classify", "Get Class_T class ID (corresponds to the CLASS_ set of constants)" ) DEFINE_SCRIPTFUNC_NAMED( ScriptAcceptInput, "AcceptInput", "" ) DEFINE_SCRIPTFUNC_NAMED( ScriptFireOutput, "FireOutput", "Fire an entity output" ) @@ -2417,6 +2421,11 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" DEFINE_SCRIPTFUNC_NAMED( IsBaseCombatWeapon, "IsWeapon", "Returns true if this entity is a weapon." ) DEFINE_SCRIPTFUNC( IsWorld, "Returns true if this entity is the world." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptDispatchInteraction, "DispatchInteraction", "Dispatches an interaction on this entity. See the g_interaction set of constants for more information." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetTakeDamage, "GetTakeDamage", "Gets this entity's m_takedamage value. (DAMAGE_YES, DAMAGE_NO, etc.)" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetTakeDamage, "SetTakeDamage", "Sets this entity's m_takedamage value. (DAMAGE_YES, DAMAGE_NO, etc.)" ) + // DEFINE_SCRIPTFUNC( IsMarkedForDeletion, "Returns true if the entity is valid and marked for deletion." ) #endif @@ -2458,6 +2467,12 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_OnDeath, "OnDeath", FIELD_BOOLEAN, "Called when the entity dies (Event_Killed). Returning false makes the entity cancel death, although this could have unforeseen consequences. For hooking any damage instead of just death, see filter_script and PassesFinalDamageFilter." ) DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_HandleInteraction, "HandleInteraction", FIELD_BOOLEAN, "Called for internal game interactions. See the g_interaction set of constants for more information. Returning true or false will return that value without falling to any internal handling. Returning nothing will allow the interaction to fall to any internal handling." ) + DEFINE_SCRIPTHOOK_PARAM( "interaction", FIELD_INTEGER ) + //DEFINE_SCRIPTHOOK_PARAM( "data", FIELD_VARIANT ) + DEFINE_SCRIPTHOOK_PARAM( "sourceEnt", FIELD_HSCRIPT ) + END_SCRIPTHOOK() #endif END_SCRIPTDESC(); @@ -4587,22 +4602,11 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, // Now, see if there's a function named Input in this entity's script file. // If so, execute it and let it decide whether to allow the default behavior to also execute. bool bCallInputFunc = true; // Always assume default behavior (do call the input function) - ScriptVariant_t functionReturn; if ( m_ScriptScope.IsInitialized() ) { - char szScriptFunctionName[255]; - Q_strcpy( szScriptFunctionName, "Input" ); - Q_strcat( szScriptFunctionName, szInputName, 255 ); - - g_pScriptVM->SetValue( "activator", ( pActivator ) ? ScriptVariant_t( pActivator->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); - g_pScriptVM->SetValue( "caller", ( pCaller ) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); -#ifdef MAPBASE_VSCRIPT - Value.SetScriptVariant( functionReturn ); - g_pScriptVM->SetValue( "parameter", functionReturn ); -#endif - - if( CallScriptFunction( szScriptFunctionName, &functionReturn ) ) + ScriptVariant_t functionReturn; + if ( ScriptInputHook( szInputName, pActivator, pCaller, Value, functionReturn ) ) { bCallInputFunc = functionReturn.m_bool; } @@ -4612,15 +4616,6 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, { (this->*pfnInput)( data ); } - - if ( m_ScriptScope.IsInitialized() ) - { - g_pScriptVM->ClearValue( "activator" ); - g_pScriptVM->ClearValue( "caller" ); -#ifdef MAPBASE_VSCRIPT - g_pScriptVM->ClearValue( "parameter" ); -#endif - } } else if ( dmap->dataDesc[i].flags & FTYPEDESC_KEY ) { @@ -4643,6 +4638,20 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, } } +#ifdef MAPBASE_VSCRIPT + // Allow VScript to handle unhandled inputs. + if (m_ScriptScope.IsInitialized()) + { + ScriptVariant_t functionReturn; + + if ( ScriptInputHook( szInputName, pActivator, pCaller, Value, functionReturn ) ) + { + if (functionReturn.m_bool) + return true; + } + } +#endif + #ifdef MAPBASE CGMsg( 2, CON_GROUP_IO_SYSTEM, "unhandled input: (%s) -> (%s,%s)\n", szInputName, STRING(m_iClassname), GetDebugName() ); #else @@ -4651,6 +4660,37 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, return false; } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseEntity::ScriptInputHook( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, ScriptVariant_t &functionReturn ) +{ + char szScriptFunctionName[255]; + Q_strcpy( szScriptFunctionName, "Input" ); + Q_strcat( szScriptFunctionName, szInputName, 255 ); + + g_pScriptVM->SetValue( "activator", ( pActivator ) ? ScriptVariant_t( pActivator->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); + g_pScriptVM->SetValue( "caller", ( pCaller ) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); +#ifdef MAPBASE_VSCRIPT + Value.SetScriptVariant( functionReturn ); + g_pScriptVM->SetValue( "parameter", functionReturn ); +#endif + + bool bHandled = false; + if( CallScriptFunction( szScriptFunctionName, &functionReturn ) ) + { + bHandled = true; + } + + g_pScriptVM->ClearValue( "activator" ); + g_pScriptVM->ClearValue( "caller" ); +#ifdef MAPBASE_VSCRIPT + g_pScriptVM->ClearValue( "parameter" ); +#endif + + return bHandled; +} + #ifdef MAPBASE_VSCRIPT bool CBaseEntity::ScriptAcceptInput( const char *szInputName, const char *szValue, HSCRIPT hActivator, HSCRIPT hCaller ) { @@ -5124,6 +5164,37 @@ void CBaseEntity::NotifySystemEvent( CBaseEntity *pNotify, notify_system_event_t } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseEntity::DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) +{ + if (interactionType <= 0) + return false; + + if (m_ScriptScope.IsInitialized() && g_Hook_HandleInteraction.CanRunInScope( m_ScriptScope )) + { + //HSCRIPT hData = g_pScriptVM->RegisterInstance( data ); + + // interaction, data, sourceEnt + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { interactionType/*, ScriptVariant_t( hData )*/, ScriptVariant_t( ToHScript( sourceEnt ) ) }; + if ( g_Hook_HandleInteraction.Call( m_ScriptScope, &functionReturn, args ) && (functionReturn.m_type == FIELD_BOOLEAN) ) + { + // Return the interaction here + //g_pScriptVM->RemoveInstance( hData ); + return functionReturn.m_bool; + } + + //g_pScriptVM->RemoveInstance( hData ); + } + + return HandleInteraction( interactionType, data, sourceEnt ); +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Holds an entity's previous abs origin and angles at the time of // teleportation. Used for child & constrained entity fixup to prevent @@ -7608,6 +7679,17 @@ const char *CBaseEntity::GetContextValue( const char *contextName ) const return m_ResponseContexts[ idx ].m_iszValue.ToCStr(); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +float CBaseEntity::GetContextExpireTime( const char *name ) +{ + int idx = FindContextByName( name ); + if ( idx == -1 ) + return 0.0f; + + return m_ResponseContexts[ idx ].m_fExpirationTime; +} + //----------------------------------------------------------------------------- // Purpose: Internal method or removing contexts and can remove multiple contexts in one call // Input : *contextName - @@ -10081,6 +10163,23 @@ const char *CBaseEntity::ScriptGetContext( const char *name ) return GetContextValue( name ); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptGetContextIndex( int index ) +{ + if (index >= m_ResponseContexts.Count()) + return NULL; + + ScriptVariant_t varTable; + g_pScriptVM->CreateTable( varTable ); + + g_pScriptVM->SetValue( varTable, "name", STRING( m_ResponseContexts[index].m_iszName ) ); + g_pScriptVM->SetValue( varTable, "value", STRING( m_ResponseContexts[index].m_iszValue ) ); + g_pScriptVM->SetValue( varTable, "expiration_time", m_ResponseContexts[index].m_fExpirationTime ); + + return varTable.m_hScript; +} + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int CBaseEntity::ScriptClassify( void ) @@ -10144,6 +10243,14 @@ HSCRIPT CBaseEntity::ScriptGetPhysicsObject( void ) else return NULL; } + +//----------------------------------------------------------------------------- +// Vscript: Dispatch an interaction to the entity +//----------------------------------------------------------------------------- +bool CBaseEntity::ScriptDispatchInteraction( int interactionType, HSCRIPT data, HSCRIPT sourceEnt ) +{ + return DispatchInteraction( interactionType, data, ToEnt( sourceEnt ) ? ToEnt( sourceEnt )->MyCombatCharacterPointer() : NULL ); +} #endif diff --git a/sp/src/game/server/baseentity.h b/sp/src/game/server/baseentity.h index 5a0227c7..79731f15 100644 --- a/sp/src/game/server/baseentity.h +++ b/sp/src/game/server/baseentity.h @@ -671,6 +671,8 @@ public: bool ScriptAcceptInput(const char *szInputName, const char *szValue, HSCRIPT hActivator, HSCRIPT hCaller); #endif + bool ScriptInputHook( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, ScriptVariant_t &functionReturn ); + // // Input handlers. // @@ -982,6 +984,7 @@ public: bool HasContext( string_t name, string_t value ) const; // NOTE: string_t version only compares pointers! bool HasContext( const char *nameandvalue ) const; const char *GetContextValue( const char *contextName ) const; + float GetContextExpireTime( const char *name ); void RemoveContext( const char *nameandvalue ); void AddContext( const char *name, const char *value, float duration = 0.0f ); #endif @@ -1327,7 +1330,9 @@ public: // // Also, keep in mind pretty much all existing DispatchInteraction() calls are only performed on CBaseCombatCharacters. // You'll need to change their code manually if you want other, non-character entities to use the interaction. - bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return ( interactionType > 0 ) ? HandleInteraction( interactionType, data, sourceEnt ) : false; } + bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ); + + // Do not call HandleInteraction directly, use DispatchInteraction virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return false; } #endif @@ -2066,6 +2071,7 @@ public: void ScriptAddContext( const char *name, const char *value, float duration = 0.0f ); const char *ScriptGetContext( const char *name ); + HSCRIPT ScriptGetContextIndex( int index ); int ScriptClassify(void); @@ -2090,10 +2096,16 @@ public: int ScriptGetMoveType() { return GetMoveType(); } void ScriptSetMoveType( int iMoveType ) { SetMoveType( (MoveType_t)iMoveType ); } + bool ScriptDispatchInteraction( int interactionType, HSCRIPT data, HSCRIPT sourceEnt ); + + int ScriptGetTakeDamage() { return m_takedamage; } + void ScriptSetTakeDamage( int val ) { m_takedamage = val; } + static ScriptHook_t g_Hook_UpdateOnRemove; static ScriptHook_t g_Hook_VPhysicsCollision; static ScriptHook_t g_Hook_FireBullets; static ScriptHook_t g_Hook_OnDeath; + static ScriptHook_t g_Hook_HandleInteraction; #endif string_t m_iszVScripts; diff --git a/sp/src/game/server/env_dof_controller.cpp b/sp/src/game/server/env_dof_controller.cpp new file mode 100644 index 00000000..d061fc73 --- /dev/null +++ b/sp/src/game/server/env_dof_controller.cpp @@ -0,0 +1,186 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: Depth of field controller entity +// +//============================================================================= + +#include "cbase.h" +#include "baseentity.h" +#include "entityoutput.h" +#include "env_dof_controller.h" +#include "ai_utils.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +LINK_ENTITY_TO_CLASS( env_dof_controller, CEnvDOFController ); + +BEGIN_DATADESC( CEnvDOFController ) + + DEFINE_KEYFIELD( m_bDOFEnabled, FIELD_BOOLEAN, "enabled" ), + DEFINE_KEYFIELD( m_flNearBlurDepth, FIELD_FLOAT, "near_blur" ), + DEFINE_KEYFIELD( m_flNearFocusDepth, FIELD_FLOAT, "near_focus" ), + DEFINE_KEYFIELD( m_flFarFocusDepth, FIELD_FLOAT, "far_focus" ), + DEFINE_KEYFIELD( m_flFarBlurDepth, FIELD_FLOAT, "far_blur" ), + DEFINE_KEYFIELD( m_flNearBlurRadius, FIELD_FLOAT, "near_radius" ), + DEFINE_KEYFIELD( m_flFarBlurRadius, FIELD_FLOAT, "far_radius" ), + DEFINE_KEYFIELD( m_strFocusTargetName, FIELD_STRING, "focus_target" ), + DEFINE_KEYFIELD( m_flFocusTargetRange, FIELD_FLOAT, "focus_range" ), + + DEFINE_FIELD( m_hFocusTarget, FIELD_EHANDLE ), + + DEFINE_THINKFUNC( UpdateParamBlend ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearBlurDepth", InputSetNearBlurDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearFocusDepth", InputSetNearFocusDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarFocusDepth", InputSetFarFocusDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarBlurDepth", InputSetFarBlurDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearBlurRadius", InputSetNearBlurRadius ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarBlurRadius", InputSetFarBlurRadius ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetFocusTarget", InputSetFocusTarget ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFocusTargetRange", InputSetFocusTargetRange ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CEnvDOFController, DT_EnvDOFController ) + SendPropInt( SENDINFO(m_bDOFEnabled), 1, SPROP_UNSIGNED ), + SendPropFloat( SENDINFO(m_flNearBlurDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flNearFocusDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flFarFocusDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flFarBlurDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flNearBlurRadius), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flFarBlurRadius), 0, SPROP_NOSCALE), +END_SEND_TABLE() + +void CEnvDOFController::Spawn() +{ + SetSolid( SOLID_NONE ); + SetMoveType( MOVETYPE_NONE ); + +#ifdef MAPBASE + // Find our target entity and hold on to it + m_hFocusTarget = gEntList.FindEntityByName( NULL, m_strFocusTargetName, this ); + + // Update if we have a focal target + if ( m_hFocusTarget ) + { + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +#endif +} + +void CEnvDOFController::Activate() +{ + BaseClass::Activate(); + +#ifndef MAPBASE // Mapbase moves this to Spawn() to avoid issues with save/restore and entities set via the SetFocusTarget input + // Find our target entity and hold on to it + m_hFocusTarget = gEntList.FindEntityByName( NULL, m_strFocusTargetName ); + + // Update if we have a focal target + if ( m_hFocusTarget ) + { + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +#endif +} + +int CEnvDOFController::UpdateTransmitState() +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + +void CEnvDOFController::InputSetNearBlurDepth( inputdata_t &inputdata ) +{ + m_flNearBlurDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetNearFocusDepth( inputdata_t &inputdata ) +{ + m_flNearFocusDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetFarFocusDepth( inputdata_t &inputdata ) +{ + m_flFarFocusDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetFarBlurDepth( inputdata_t &inputdata ) +{ + m_flFarBlurDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetNearBlurRadius( inputdata_t &inputdata ) +{ + m_flNearBlurRadius = inputdata.value.Float(); + m_bDOFEnabled = ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ); +} + +void CEnvDOFController::InputSetFarBlurRadius( inputdata_t &inputdata ) +{ + m_flFarBlurRadius = inputdata.value.Float(); + m_bDOFEnabled = ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ); +} + +void CEnvDOFController::SetControllerState( DOFControlSettings_t setting ) +{ + m_flNearBlurDepth = setting.flNearBlurDepth; + m_flNearBlurRadius = setting.flNearBlurRadius; + m_flNearFocusDepth = setting.flNearFocusDistance; + + m_flFarBlurDepth = setting.flFarBlurDepth; + m_flFarBlurRadius = setting.flFarBlurRadius; + m_flFarFocusDepth = setting.flFarFocusDistance; + + m_bDOFEnabled = ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ); +} + +#define BLUR_DEPTH 500.0f + +//----------------------------------------------------------------------------- +// Purpose: Blend the parameters to the specified value +//----------------------------------------------------------------------------- +void CEnvDOFController::UpdateParamBlend() +{ + // Update our focal target if we have one + if ( m_hFocusTarget ) + { + CBasePlayer *pPlayer = AI_GetSinglePlayer(); + float flDistToFocus = ( m_hFocusTarget->GetAbsOrigin() - pPlayer->GetAbsOrigin() ).Length(); + m_flFarFocusDepth.GetForModify() = flDistToFocus + m_flFocusTargetRange; + m_flFarBlurDepth.GetForModify() = m_flFarFocusDepth + BLUR_DEPTH; + + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Set the "focus" target entity +//----------------------------------------------------------------------------- +void CEnvDOFController::InputSetFocusTarget( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + m_hFocusTarget = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); +#else + m_hFocusTarget = gEntList.FindEntityByName( NULL, inputdata.value.String() ); +#endif + + // Update if we have a focal target + if ( m_hFocusTarget ) + { + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Set the range behind the focus entity that we'll blur (in units) +//----------------------------------------------------------------------------- +void CEnvDOFController::InputSetFocusTargetRange( inputdata_t &inputdata ) +{ + m_flFocusTargetRange = inputdata.value.Float(); +} diff --git a/sp/src/game/server/env_dof_controller.h b/sp/src/game/server/env_dof_controller.h new file mode 100644 index 00000000..e323ef52 --- /dev/null +++ b/sp/src/game/server/env_dof_controller.h @@ -0,0 +1,56 @@ +#pragma once + +struct DOFControlSettings_t +{ + // Near plane + float flNearBlurDepth; + float flNearBlurRadius; + float flNearFocusDistance; + // Far plane + float flFarBlurDepth; + float flFarBlurRadius; + float flFarFocusDistance; +}; + +//----------------------------------------------------------------------------- +// Purpose: Entity that controls depth of field postprocessing +//----------------------------------------------------------------------------- +class CEnvDOFController : public CPointEntity +{ + DECLARE_CLASS( CEnvDOFController, CPointEntity ); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + virtual void Spawn(); + virtual void Activate(); + virtual int UpdateTransmitState(); + void SetControllerState( DOFControlSettings_t setting ); + + void UpdateParamBlend(); + + // Inputs + void InputSetNearBlurDepth( inputdata_t &inputdata ); + void InputSetNearFocusDepth( inputdata_t &inputdata ); + void InputSetFarFocusDepth( inputdata_t &inputdata ); + void InputSetFarBlurDepth( inputdata_t &inputdata ); + void InputSetNearBlurRadius( inputdata_t &inputdata ); + void InputSetFarBlurRadius( inputdata_t &inputdata ); + + void InputSetFocusTarget( inputdata_t &inputdata ); + void InputSetFocusTargetRange( inputdata_t &inputdata ); + +private: + float m_flFocusTargetRange; + + string_t m_strFocusTargetName; // Name of the entity to focus on + EHANDLE m_hFocusTarget; + + CNetworkVar( bool, m_bDOFEnabled ); + CNetworkVar( float, m_flNearBlurDepth ); + CNetworkVar( float, m_flNearFocusDepth ); + CNetworkVar( float, m_flFarFocusDepth ); + CNetworkVar( float, m_flFarBlurDepth ); + CNetworkVar( float, m_flNearBlurRadius ); + CNetworkVar( float, m_flFarBlurRadius ); +}; diff --git a/sp/src/game/server/env_global_light.cpp b/sp/src/game/server/env_global_light.cpp index 36e8e1ba..6c1549b2 100644 --- a/sp/src/game/server/env_global_light.cpp +++ b/sp/src/game/server/env_global_light.cpp @@ -58,7 +58,6 @@ private: CNetworkVector( m_shadowDirection ); CNetworkVar( bool, m_bEnabled ); - bool m_bStartDisabled; CNetworkString( m_TextureName, MAX_PATH ); #ifdef MAPBASE @@ -86,7 +85,6 @@ LINK_ENTITY_TO_CLASS(env_global_light, CGlobalLight); BEGIN_DATADESC( CGlobalLight ) DEFINE_KEYFIELD( m_bEnabled, FIELD_BOOLEAN, "enabled" ), - DEFINE_KEYFIELD( m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled" ), DEFINE_AUTO_ARRAY_KEYFIELD( m_TextureName, FIELD_CHARACTER, "texturename" ), #ifdef MAPBASE DEFINE_KEYFIELD( m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe" ), @@ -107,6 +105,8 @@ BEGIN_DATADESC( CGlobalLight ) #endif DEFINE_KEYFIELD( m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime" ), + DEFINE_FIELD( m_shadowDirection, FIELD_VECTOR ), + // Inputs #ifdef MAPBASE DEFINE_INPUTFUNC( FIELD_FLOAT, "SetXOffset", InputSetXOffset ), @@ -184,6 +184,7 @@ CGlobalLight::CGlobalLight() m_flBrightnessScale = 1.0f; m_flOrthoSize = 1000.0f; #endif + m_bEnabled = true; } @@ -242,6 +243,10 @@ bool CGlobalLight::KeyValue( const char *szKeyName, const char *szValue ) Q_strcpy( m_TextureName.GetForModify(), szValue ); #endif } + else if ( FStrEq( szKeyName, "StartDisabled" ) ) + { + m_bEnabled.Set( atoi( szValue ) <= 0 ); + } return BaseClass::KeyValue( szKeyName, szValue ); } @@ -258,6 +263,11 @@ bool CGlobalLight::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLe Q_snprintf( szValue, iMaxLen, "%s", m_TextureName.Get() ); return true; } + else if ( FStrEq( szKeyName, "StartDisabled" ) ) + { + Q_snprintf( szValue, iMaxLen, "%d", !m_bEnabled.Get() ); + return true; + } return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen ); } @@ -268,15 +278,6 @@ void CGlobalLight::Spawn( void ) { Precache(); SetSolid( SOLID_NONE ); - - if( m_bStartDisabled ) - { - m_bEnabled = false; - } - else - { - m_bEnabled = true; - } } //------------------------------------------------------------------------------ diff --git a/sp/src/game/server/hl2/item_itemcrate.cpp b/sp/src/game/server/hl2/item_itemcrate.cpp index 6c5469fb..c1d47364 100644 --- a/sp/src/game/server/hl2/item_itemcrate.cpp +++ b/sp/src/game/server/hl2/item_itemcrate.cpp @@ -46,6 +46,10 @@ public: virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ); #ifdef MAPBASE + void InputSetContents( inputdata_t &data ); + void InputSetItemCount( inputdata_t &data ); + void InputMergeContentsWithPlayer( inputdata_t &data ); + // Item crates always override prop data for custom models bool OverridePropdata( void ) { return true; } #endif @@ -110,6 +114,10 @@ BEGIN_DATADESC( CItem_ItemCrate ) DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ), #ifdef MAPBASE DEFINE_OUTPUT( m_OnItem, "OnItem" ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetContents", InputSetContents ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetItemCount", InputSetItemCount ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "MergeContentsWithPlayer", InputMergeContentsWithPlayer ), #endif END_DATADESC() @@ -193,6 +201,67 @@ void CItem_ItemCrate::InputKill( inputdata_t &data ) UTIL_Remove( this ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &data - +//----------------------------------------------------------------------------- +void CItem_ItemCrate::InputSetContents( inputdata_t &data ) +{ + switch( m_CrateType ) + { + case CRATE_POINT_TEMPLATE: + ITEM_ITEMCRATE_TEMPLATE_TARGET = data.value.StringID(); + break; + + case CRATE_SPECIFIC_ITEM: + default: + m_strItemClass = data.value.StringID(); + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &data - +//----------------------------------------------------------------------------- +void CItem_ItemCrate::InputSetItemCount( inputdata_t &data ) +{ + m_nItemCount = data.value.Int(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &data - +//----------------------------------------------------------------------------- +void CItem_ItemCrate::InputMergeContentsWithPlayer( inputdata_t &data ) +{ + CBasePlayer *pPlayer = ToBasePlayer(data.value.Entity()); + if (!pPlayer) + pPlayer = UTIL_GetLocalPlayer(); + + if (pPlayer) + { + switch( m_CrateType ) + { + case CRATE_POINT_TEMPLATE: + { + Warning( "%s: item_itemcrate MergeContentsWithPlayer is not supported on template crates yet!!!\n", GetDebugName() ); + } break; + + case CRATE_SPECIFIC_ITEM: + default: + { + for (int i = 0; i < m_nItemCount; i++) + { + pPlayer->GiveNamedItem( STRING( m_strItemClass ) ); + } + } break; + } + } +} +#endif + //----------------------------------------------------------------------------- // Item crates blow up immediately diff --git a/sp/src/game/server/hl2/npc_attackchopper.cpp b/sp/src/game/server/hl2/npc_attackchopper.cpp index f91128ae..ddb9752a 100644 --- a/sp/src/game/server/hl2/npc_attackchopper.cpp +++ b/sp/src/game/server/hl2/npc_attackchopper.cpp @@ -115,6 +115,9 @@ static const char *s_pChunkModelName[CHOPPER_MAX_CHUNKS] = #define SF_HELICOPTER_IGNORE_AVOID_FORCES 0x00080000 #define SF_HELICOPTER_AGGRESSIVE 0x00100000 #define SF_HELICOPTER_LONG_SHADOW 0x00200000 +#ifdef MAPBASE +#define SF_HELICOPTER_AIM_WITH_GUN_OFF 0x00400000 +#endif #define CHOPPER_SLOW_BOMB_SPEED 250 @@ -4856,6 +4859,26 @@ void CNPC_AttackHelicopter::Hunt( void ) { BullrushBombs(); } +#ifdef MAPBASE + // Some may want the hunter-chopper to aim at different positions searching for its target + // without actually firing at anything. Gun aiming is only handled in FireGun(), which is + // disabled when the gun is disabled. point_posecontroller doesn't seem to work well for this either, + // so a new spawnflag is handled here to allow the chopper to aim at its enemy even when the gun is off. + else if ( HasSpawnFlags( SF_HELICOPTER_AIM_WITH_GUN_OFF ) && GetEnemy() ) + { + // Get gun attachment points + Vector vBasePos; + GetAttachment( m_nGunBaseAttachment, vBasePos ); + + Vector vecFireAtPosition; + ComputeFireAtPosition( &vecFireAtPosition ); + + Vector vTargetDir = vecFireAtPosition - vBasePos; + VectorNormalize( vTargetDir ); + + PoseGunTowardTargetDirection( vTargetDir ); + } +#endif } #ifdef HL2_EPISODIC diff --git a/sp/src/game/server/hl2/npc_combine.cpp b/sp/src/game/server/hl2/npc_combine.cpp index 397992ba..7599a6ac 100644 --- a/sp/src/game/server/hl2/npc_combine.cpp +++ b/sp/src/game/server/hl2/npc_combine.cpp @@ -1187,6 +1187,15 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) break; case TASK_RANGE_ATTACK1: { +#ifdef MAPBASE + // The game can crash if a soldier's weapon is removed while they're shooting + if (!GetActiveWeapon()) + { + TaskFail( "No weapon" ); + break; + } +#endif + m_nShots = GetActiveWeapon()->GetRandomBurst(); m_flShotDelay = GetActiveWeapon()->GetFireRate(); diff --git a/sp/src/game/server/hl2/npc_metropolice.cpp b/sp/src/game/server/hl2/npc_metropolice.cpp index af2efd40..8588c043 100644 --- a/sp/src/game/server/hl2/npc_metropolice.cpp +++ b/sp/src/game/server/hl2/npc_metropolice.cpp @@ -468,7 +468,14 @@ void CNPC_MetroPolice::NotifyDeadFriend( CBaseEntity* pFriend ) { BaseClass::NotifyDeadFriend(pFriend); +#ifdef MAPBASE + // m_hManhack is set to NULL after it's finished deploying, which means this has no chance of playing unless the manhack + // was still being deployed. This is thought to be an unintended oversight. + // Mapbase stores the metrocop thrower as the manhack's owner entity, so this code is now able to check that instead. + if ( pFriend->GetOwnerEntity() == this ) +#else if ( pFriend == m_hManhack ) +#endif { #ifdef METROPOLICE_USES_RESPONSE_SYSTEM SpeakIfAllowed(TLK_COP_MANHACKKILLED, "my_manhack:1", SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL); @@ -3239,7 +3246,7 @@ void CNPC_MetroPolice::OnAnimEventStartDeployManhack( void ) if ( m_iManhacks <= 0 ) { - DevMsg( "Error: Throwing manhack but out of manhacks!\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "Error: Throwing manhack but out of manhacks!\n" ); return; } @@ -3613,6 +3620,12 @@ void CNPC_MetroPolice::ReleaseManhack( void ) // Make us active m_hManhack->RemoveSpawnFlags( SF_NPC_WAIT_FOR_SCRIPT ); m_hManhack->ClearSchedule( "Manhack released by metropolice" ); + +#ifdef MAPBASE + // FSOLID_COLLIDE_WITH_OWNER allows us to be remembered as the manhack's owner without making us invulnerable to it + m_hManhack->SetOwnerEntity( this ); + m_hManhack->AddSolidFlags( FSOLID_COLLIDE_WITH_OWNER ); +#endif // Start him with knowledge of our current enemy if ( GetEnemy() ) @@ -3711,7 +3724,7 @@ int CNPC_MetroPolice::SelectRangeAttackSchedule() { if ( OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) { - return SCHED_RANGE_ATTACK2; + return SCHED_METROPOLICE_RANGE_ATTACK2; } } #endif @@ -3965,7 +3978,7 @@ int CNPC_MetroPolice::SelectCombatSchedule() //Msg("Time: %f Dist: %f\n", flTime, flDist ); if ( flTime <= COMBINE_GRENADE_FLUSH_TIME && flDist <= COMBINE_GRENADE_FLUSH_DIST && CanGrenadeEnemy( false ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) { - return SCHED_RANGE_ATTACK2; + return SCHED_METROPOLICE_RANGE_ATTACK2; } } #endif @@ -4466,7 +4479,7 @@ int CNPC_MetroPolice::SelectBehaviorOverrideSchedule() //Msg("Time: %f Dist: %f\n", flTime, flDist ); if ( flTime <= COMBINE_GRENADE_FLUSH_TIME && flDist <= COMBINE_GRENADE_FLUSH_DIST && CanGrenadeEnemy( false ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) { - return SCHED_RANGE_ATTACK2; + return SCHED_METROPOLICE_RANGE_ATTACK2; } } } @@ -6097,6 +6110,10 @@ AI_BEGIN_CUSTOM_NPC( npc_metropolice, CNPC_MetroPolice ) DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_DEPLOY_MANHACK ); DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_ATTACK_OCCLUDER1 ); DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_ATTACK_OCCLUDER2 ); +#ifdef MAPBASE + DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_COVERING_FIRE1 ); + DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_COVERING_FIRE2 ); +#endif DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_ARREST_ENEMY ); DECLARE_ACTIVITY( ACT_METROPOLICE_DRAW_PISTOL ); diff --git a/sp/src/game/server/mapbase/SystemConvarMod.cpp b/sp/src/game/server/mapbase/SystemConvarMod.cpp index 727e0c9d..2ff4380e 100644 --- a/sp/src/game/server/mapbase/SystemConvarMod.cpp +++ b/sp/src/game/server/mapbase/SystemConvarMod.cpp @@ -8,7 +8,7 @@ #include "cbase.h" #include "saverestore_utlvector.h" #include "SystemConvarMod.h" - +#include "fmtstr.h" ConVar g_debug_convarmod( "g_debug_convarmod", "0" ); @@ -133,8 +133,8 @@ void CVEnt_Activate(CMapbaseCVarModEntity *modent) { SetChangingCVars( modent ); - engine->ServerCommand( pszCommands ); - engine->ServerCommand( "mapbase_cvarsnotchanging" ); + engine->ServerCommand( CFmtStr("%s\n", pszCommands) ); + engine->ServerCommand( "mapbase_cvarsnotchanging\n" ); } else { @@ -245,16 +245,26 @@ void CMapbaseCVarModEntity::Spawn( void ) if (!m_bUseServer && !UTIL_GetLocalPlayer()) { // The local player doesn't exist yet, so we should wait until they do - SetContextThink( &CMapbaseCVarModEntity::CvarModActivate, gpGlobals->curtime, NULL ); + SetThink( &CMapbaseCVarModEntity::CvarModActivate ); + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); } else - CVEnt_Activate(this); + { + CVEnt_Activate( this ); + } } } void CMapbaseCVarModEntity::CvarModActivate() { - CVEnt_Activate(this); + if (UTIL_GetLocalPlayer()) + { + CVEnt_Activate( this ); + } + else + { + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); + } } void CMapbaseCVarModEntity::OnRestore( void ) diff --git a/sp/src/game/server/player.cpp b/sp/src/game/server/player.cpp index ba4ee6a7..2c57cc36 100644 --- a/sp/src/game/server/player.cpp +++ b/sp/src/game/server/player.cpp @@ -460,6 +460,7 @@ BEGIN_DATADESC( CBasePlayer ) DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetHUDVisibility", InputSetHUDVisibility ), DEFINE_INPUTFUNC( FIELD_STRING, "SetFogController", InputSetFogController ), + DEFINE_INPUTFUNC( FIELD_INPUT, "SetPostProcessController", InputSetPostProcessController ), DEFINE_INPUTFUNC( FIELD_STRING, "HandleMapEvent", InputHandleMapEvent ), #ifdef MAPBASE DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetSuppressAttacks", InputSetSuppressAttacks ), @@ -473,6 +474,8 @@ BEGIN_DATADESC( CBasePlayer ) DEFINE_FIELD( m_nNumCrateHudHints, FIELD_INTEGER ), + DEFINE_FIELD( m_hPostProcessCtrl, FIELD_EHANDLE ), + // DEFINE_FIELD( m_nBodyPitchPoseParam, FIELD_INTEGER ), @@ -534,6 +537,10 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetAutoaimVectorCustomMaxDist, "GetAutoaimVectorCustomMaxDist", "Gets the player's autoaim shooting direction with the specified scale and a custom max distance." ) DEFINE_SCRIPTFUNC( ShouldAutoaim, "Returns true if the player should be autoaiming." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEyeForward, "GetEyeForward", "Gets the player's forward eye vector." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEyeRight, "GetEyeRight", "Gets the player's right eye vector." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEyeUp, "GetEyeUp", "Gets the player's up eye vector." ) + // // Hooks // @@ -746,6 +753,8 @@ CBasePlayer::CBasePlayer( ) m_flLastUserCommandTime = 0.f; m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; + + m_hPostProcessCtrl.Set( NULL ); } CBasePlayer::~CBasePlayer( ) @@ -5142,6 +5151,7 @@ void CBasePlayer::Spawn( void ) // Initialize the fog and postprocess controllers. InitFogController(); + InitPostProcessController(); m_DmgTake = 0; m_DmgSave = 0; @@ -8701,6 +8711,9 @@ void SendProxy_ShiftPlayerSpawnflags( const SendProp *pProp, const void *pStruct SendPropArray ( SendPropEHandle( SENDINFO_ARRAY( m_hViewModel ) ), m_hViewModel ), SendPropString (SENDINFO(m_szLastPlaceName) ), + // Postprocess data + SendPropEHandle( SENDINFO( m_hPostProcessCtrl ) ), + #if defined USES_ECON_ITEMS SendPropUtlVector( SENDINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, SendPropEHandle( NULL, 0 ) ), #endif // USES_ECON_ITEMS @@ -9431,6 +9444,37 @@ void CBasePlayer::InitFogController( void ) m_Local.m_PlayerFog.m_hCtrl = FogSystem()->GetMasterFogController(); } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InitPostProcessController( void ) +{ + // Setup with the default master controller. + m_hPostProcessCtrl = PostProcessSystem()->GetMasterPostProcessController(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InputSetPostProcessController( inputdata_t& inputdata ) +{ + // Find the postprocess controller with the given name. + CPostProcessController* 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_hPostProcessCtrl.Set( pController ); + } +} + //----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - diff --git a/sp/src/game/server/player.h b/sp/src/game/server/player.h index 2e5c56d9..03709ade 100644 --- a/sp/src/game/server/player.h +++ b/sp/src/game/server/player.h @@ -404,6 +404,10 @@ public: int GetButtonLast() { return m_afButtonLast; } int GetButtonDisabled() { return m_afButtonDisabled; } int GetButtonForced() { return m_afButtonForced; } + + const Vector& ScriptGetEyeForward() { static Vector vecForward; EyeVectors( &vecForward, NULL, NULL ); return vecForward; } + const Vector& ScriptGetEyeRight() { static Vector vecRight; EyeVectors( NULL, &vecRight, NULL ); return vecRight; } + const Vector& ScriptGetEyeUp() { static Vector vecUp; EyeVectors( NULL, NULL, &vecUp ); return vecUp; } #endif // View model prediction setup @@ -880,6 +884,10 @@ public: void InitFogController( void ); void InputSetFogController( inputdata_t &inputdata ); + CNetworkHandle( CPostProcessController, m_hPostProcessCtrl ); // active postprocessing controller + void InitPostProcessController( void ); + void InputSetPostProcessController( inputdata_t& inputdata ); + // Used by env_soundscape_triggerable to manage when the player is touching multiple // soundscape triggers simultaneously. // The one at the HEAD of the list is always the current soundscape for the player. diff --git a/sp/src/game/server/playerlocaldata.h b/sp/src/game/server/playerlocaldata.h index 9a61d526..587dbd1a 100644 --- a/sp/src/game/server/playerlocaldata.h +++ b/sp/src/game/server/playerlocaldata.h @@ -15,6 +15,7 @@ #include "playernet_vars.h" #include "networkvar.h" #include "fogcontroller.h" +#include "postprocesscontroller.h" //----------------------------------------------------------------------------- // Purpose: Player specific data ( sent only to local player, too ) diff --git a/sp/src/game/server/postprocesscontroller.cpp b/sp/src/game/server/postprocesscontroller.cpp new file mode 100644 index 00000000..3e3fd6b5 --- /dev/null +++ b/sp/src/game/server/postprocesscontroller.cpp @@ -0,0 +1,207 @@ +//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ========== +// +// An entity that allows level designer control over the post-processing parameters. +// +//=================================================================================== + +#include "cbase.h" +#include "postprocesscontroller.h" +#include "entityinput.h" +#include "entityoutput.h" +#include "eventqueue.h" +#include "player.h" +#include "world.h" +#include "ndebugoverlay.h" +#include "triggers.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CPostProcessSystem s_PostProcessSystem( "PostProcessSystem" ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPostProcessSystem *PostProcessSystem() +{ + return &s_PostProcessSystem; +} + + +LINK_ENTITY_TO_CLASS( postprocess_controller, CPostProcessController ); + +BEGIN_DATADESC( CPostProcessController ) + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_FADE_TIME ], FIELD_FLOAT, "fadetime" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_LOCAL_CONTRAST_STRENGTH ], FIELD_FLOAT, "localcontraststrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_LOCAL_CONTRAST_EDGE_STRENGTH ], FIELD_FLOAT, "localcontrastedgestrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_VIGNETTE_START ], FIELD_TIME, "vignettestart" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_VIGNETTE_END ], FIELD_TIME, "vignetteend" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_VIGNETTE_BLUR_STRENGTH ], FIELD_FLOAT, "vignetteblurstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_FADE_TO_BLACK_STRENGTH ], FIELD_FLOAT, "fadetoblackstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_DEPTH_BLUR_FOCAL_DISTANCE ], FIELD_FLOAT, "depthblurfocaldistance" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_DEPTH_BLUR_STRENGTH ], FIELD_FLOAT, "depthblurstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_SCREEN_BLUR_STRENGTH ], FIELD_FLOAT, "screenblurstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_FILM_GRAIN_STRENGTH ], FIELD_FLOAT, "filmgrainstrength" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeTime", InputSetFadeTime ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLocalContrastStrength", InputSetLocalContrastStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLocalContrastEdgeStrength", InputSetLocalContrastEdgeStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVignetteStart", InputSetVignetteStart ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVignetteEnd", InputSetVignetteEnd ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVignetteBlurStrength", InputSetVignetteBlurStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeToBlackStrength", InputSetFadeToBlackStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDepthBlurFocalDistance", InputSetDepthBlurFocalDistance), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDepthBlurStrength", InputSetDepthBlurStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetScreenBlurStrength", InputSetScreenBlurStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFilmGrainStrength", InputSetFilmGrainStrength ), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CPostProcessController, DT_PostProcessController ) + SendPropArray3( SENDINFO_ARRAY3( m_flPostProcessParameters ), SendPropFloat( SENDINFO_ARRAY( m_flPostProcessParameters ) ) ), + SendPropBool( SENDINFO(m_bMaster) ), +END_SEND_TABLE() + + +CPostProcessController::CPostProcessController() +{ + m_bMaster = false; +} + +CPostProcessController::~CPostProcessController() +{ +} + +void CPostProcessController::Spawn() +{ + BaseClass::Spawn(); + + m_bMaster = IsMaster(); +} + +int CPostProcessController::UpdateTransmitState() +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + +void CPostProcessController::InputSetFadeTime( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_FADE_TIME, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetLocalContrastStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_LOCAL_CONTRAST_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetLocalContrastEdgeStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_LOCAL_CONTRAST_EDGE_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetVignetteStart( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_VIGNETTE_START, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetVignetteEnd( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_VIGNETTE_END, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetVignetteBlurStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_VIGNETTE_BLUR_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetFadeToBlackStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_FADE_TO_BLACK_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetDepthBlurFocalDistance( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_DEPTH_BLUR_FOCAL_DISTANCE, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetDepthBlurStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_DEPTH_BLUR_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetScreenBlurStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_SCREEN_BLUR_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetFilmGrainStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_FILM_GRAIN_STRENGTH, inputdata.value.Float() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Clear out the PostProcess controller. +//----------------------------------------------------------------------------- +void CPostProcessSystem::LevelInitPreEntity() +{ + m_hMasterController = nullptr; + ListenForGameEvent( "round_start" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Find the master controller. If no controller is +// set as Master, use the first controller found. +//----------------------------------------------------------------------------- +void CPostProcessSystem::InitMasterController() +{ + CPostProcessController *pPostProcessController = nullptr; + + do + { + pPostProcessController = dynamic_cast( gEntList.FindEntityByClassname( pPostProcessController, "postprocess_controller" ) ); + if ( pPostProcessController ) + { + if ( m_hMasterController.Get() == nullptr ) + { + m_hMasterController = pPostProcessController; + } + else + { + if ( pPostProcessController->IsMaster() ) + { + m_hMasterController = pPostProcessController; + } + } + } + } while ( pPostProcessController ); +} + +//----------------------------------------------------------------------------- +// Purpose: On a multiplayer map restart, re-find the master controller. +//----------------------------------------------------------------------------- +void CPostProcessSystem::FireGameEvent( IGameEvent *pEvent ) +{ + InitMasterController(); +} + +//----------------------------------------------------------------------------- +// Purpose: On level load find the master PostProcess controller. If no controller is +// set as Master, use the first PostProcess controller found. +//----------------------------------------------------------------------------- +void CPostProcessSystem::LevelInitPostEntity() +{ + 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 PostProcess 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_hPostProcessCtrl.Get() == nullptr ) ) + { + pPlayer->InitPostProcessController(); + } + } +} diff --git a/sp/src/game/server/postprocesscontroller.h b/sp/src/game/server/postprocesscontroller.h new file mode 100644 index 00000000..5608394a --- /dev/null +++ b/sp/src/game/server/postprocesscontroller.h @@ -0,0 +1,80 @@ +#pragma once + +#include "GameEventListener.h" +#include "postprocess_shared.h" + +// Spawn Flags +#define SF_POSTPROCESS_MASTER 0x0001 + +//============================================================================= +// Class Postprocess Controller: +//============================================================================= +class CPostProcessController : public CBaseEntity +{ +public: + DECLARE_SERVERCLASS(); + DECLARE_DATADESC(); + DECLARE_CLASS( CPostProcessController, CBaseEntity ); + + CPostProcessController(); + virtual ~CPostProcessController(); + + virtual int UpdateTransmitState(); + + // Input handlers + void InputSetFadeTime(inputdata_t &data); + void InputSetLocalContrastStrength(inputdata_t &data); + void InputSetLocalContrastEdgeStrength(inputdata_t &data); + void InputSetVignetteStart(inputdata_t &data); + void InputSetVignetteEnd(inputdata_t &data); + void InputSetVignetteBlurStrength(inputdata_t &data); + void InputSetFadeToBlackStrength(inputdata_t &data); + void InputSetDepthBlurFocalDistance(inputdata_t &data); + void InputSetDepthBlurStrength(inputdata_t &data); + void InputSetScreenBlurStrength(inputdata_t &data); + void InputSetFilmGrainStrength(inputdata_t &data); + + void InputTurnOn(inputdata_t &data); + void InputTurnOff(inputdata_t &data); + + void Spawn(); + + bool IsMaster() const { return HasSpawnFlags( SF_FOG_MASTER ); } + +public: + CNetworkArray( float, m_flPostProcessParameters, POST_PROCESS_PARAMETER_COUNT ); + + CNetworkVar( bool, m_bMaster ); +}; + +//============================================================================= +// +// Postprocess Controller System. +// +class CPostProcessSystem : public CAutoGameSystem, public CGameEventListener +{ +public: + + // Creation/Init. + CPostProcessSystem( char const *name ) : CAutoGameSystem( name ) + { + m_hMasterController = nullptr; + } + + ~CPostProcessSystem() + { + m_hMasterController = nullptr; + } + + virtual void LevelInitPreEntity(); + virtual void LevelInitPostEntity(); + virtual void FireGameEvent( IGameEvent *pEvent ); + CPostProcessController *GetMasterPostProcessController() { return m_hMasterController; } + +private: + + void InitMasterController(); + CHandle< CPostProcessController > m_hMasterController; +}; + +CPostProcessSystem *PostProcessSystem(); diff --git a/sp/src/game/server/server_mapbase.vpc b/sp/src/game/server/server_mapbase.vpc index c0e0d6b7..40581e0f 100644 --- a/sp/src/game/server/server_mapbase.vpc +++ b/sp/src/game/server/server_mapbase.vpc @@ -23,6 +23,10 @@ $Project $File "env_global_light.cpp" $File "skyboxswapper.cpp" $File "env_instructor_hint.cpp" + $File "postprocesscontroller.cpp" + $File "postprocesscontroller.h" + $File "env_dof_controller.cpp" + $File "env_dof_controller.h" $Folder "Mapbase" { diff --git a/sp/src/game/server/variant_t.cpp b/sp/src/game/server/variant_t.cpp index 04d96f79..3b45275b 100644 --- a/sp/src/game/server/variant_t.cpp +++ b/sp/src/game/server/variant_t.cpp @@ -70,13 +70,24 @@ void variant_t::SetScriptVariant( ScriptVariant_t &var ) { switch (FieldType()) { - case FIELD_INTEGER: var = Int(); break; - case FIELD_FLOAT: var = Float(); break; - case FIELD_STRING: var = String(); break; + case FIELD_VOID: var = NULL; break; + case FIELD_INTEGER: var = iVal; break; + case FIELD_FLOAT: var = flVal; break; + case FIELD_STRING: var = STRING(iszVal); break; case FIELD_POSITION_VECTOR: case FIELD_VECTOR: var = reinterpret_cast(&flVal); break; // HACKHACK - case FIELD_BOOLEAN: var = Bool(); break; - case FIELD_EHANDLE: var = ToHScript( Entity() ); break; + case FIELD_BOOLEAN: var = bVal; break; + case FIELD_EHANDLE: var = ToHScript( eVal ); break; + case FIELD_CLASSPTR: var = ToHScript( eVal ); break; + case FIELD_SHORT: var = (short)iVal; break; + case FIELD_CHARACTER: var = (char)iVal; break; + case FIELD_COLOR32: + { + Color *clr = new Color( rgbaVal.r, rgbaVal.g, rgbaVal.b, rgbaVal.a ); + var = g_pScriptVM->RegisterInstance( clr, true ); + break; + } + default: var = ToString(); break; } } #endif diff --git a/sp/src/game/server/vscript_server.cpp b/sp/src/game/server/vscript_server.cpp index 315e2a6d..63f0ac0d 100644 --- a/sp/src/game/server/vscript_server.cpp +++ b/sp/src/game/server/vscript_server.cpp @@ -714,6 +714,11 @@ static float IntervalPerTick() { return gpGlobals->interval_per_tick; } + +static int GetLoadType() +{ + return gpGlobals->eLoadType; +} #endif static void SendToConsole( const char *pszCommand ) @@ -978,6 +983,7 @@ bool VScriptServerInit() ScriptRegisterFunction( g_pScriptVM, SendToConsoleServer, "Send a string to the server console as a command" ); ScriptRegisterFunction( g_pScriptVM, MaxPlayers, "Get the maximum number of players allowed on this server" ); ScriptRegisterFunction( g_pScriptVM, IntervalPerTick, "Get the interval used between each tick" ); + ScriptRegisterFunction( g_pScriptVM, GetLoadType, "Get the way the current game was loaded (corresponds to the MapLoad enum)" ); ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate an entity i/o event" ) ); ScriptRegisterFunction( g_pScriptVM, DoEntFireByInstanceHandle, SCRIPT_ALIAS( "EntFireByHandle", "Generate an entity i/o event. First parameter is an entity instance." ) ); // ScriptRegisterFunction( g_pScriptVM, IsValidEntity, "Returns true if the entity is valid." ); @@ -1286,7 +1292,9 @@ public: { if ( pEnt->m_iszScriptId != NULL_STRING ) { +#ifndef MAPBASE_VSCRIPT g_pScriptVM->RegisterClass( pEnt->GetScriptDesc() ); +#endif m_InstanceMap.Insert( STRING( pEnt->m_iszScriptId ), pEnt ); } pEnt = gEntList.NextEnt( pEnt ); diff --git a/sp/src/game/shared/ammodef.cpp b/sp/src/game/shared/ammodef.cpp index 8cd95e27..cf3ad3e8 100644 --- a/sp/src/game/shared/ammodef.cpp +++ b/sp/src/game/shared/ammodef.cpp @@ -322,6 +322,8 @@ BEGIN_SCRIPTDESC_ROOT( CAmmoDef, SCRIPT_SINGLETON "The ammo type definition mana DEFINE_SCRIPTFUNC( MaxSplashSize, "Gets the maximum size of water splashes caused by impacts from this ammo type." ) DEFINE_SCRIPTFUNC( Flags, "Gets the flags this ammo type uses." ) + DEFINE_SCRIPTFUNC( GetNumAmmoTypes, "Gets the number of ammo types which currently exist." ) + END_SCRIPTDESC(); #endif diff --git a/sp/src/game/shared/ammodef.h b/sp/src/game/shared/ammodef.h index 79a86ed2..d5607e02 100644 --- a/sp/src/game/shared/ammodef.h +++ b/sp/src/game/shared/ammodef.h @@ -94,6 +94,11 @@ public: private: bool AddAmmoType(char const* name, int damageType, int tracerType, int nFlags, int minSplashSize, int maxSplashSize ); + +#ifdef MAPBASE_VSCRIPT + ALLOW_SCRIPT_ACCESS(); + int GetNumAmmoTypes() { return m_nAmmoIndex; } +#endif }; diff --git a/sp/src/game/shared/basecombatweapon_shared.cpp b/sp/src/game/shared/basecombatweapon_shared.cpp index 16cc766d..9f3b9be4 100644 --- a/sp/src/game/shared/basecombatweapon_shared.cpp +++ b/sp/src/game/shared/basecombatweapon_shared.cpp @@ -2948,6 +2948,8 @@ BEGIN_ENT_SCRIPTDESC( CBaseCombatWeapon, CBaseAnimating, "The base class for all DEFINE_SCRIPTFUNC_NAMED( ScriptGetDrawActivity, "GetDrawActivity", "Returns the weapon's draw activity." ) DEFINE_SCRIPTFUNC( GetDefaultAnimSpeed, "Returns the weapon's default animation speed." ) DEFINE_SCRIPTFUNC( SendWeaponAnim, "Sends a weapon animation." ) + DEFINE_SCRIPTFUNC( GetViewModelSequenceDuration, "Gets the sequence duration of the current view model animation." ) + DEFINE_SCRIPTFUNC( IsViewModelSequenceFinished, "Returns true if the current view model animation is finished." ) DEFINE_SCRIPTFUNC( FiresUnderwater, "Returns true if this weapon can fire underwater." ) DEFINE_SCRIPTFUNC( SetFiresUnderwater, "Sets whether this weapon can fire underwater." ) diff --git a/sp/src/game/shared/gamerules.cpp b/sp/src/game/shared/gamerules.cpp index 9fc5ccea..cb199617 100644 --- a/sp/src/game/shared/gamerules.cpp +++ b/sp/src/game/shared/gamerules.cpp @@ -71,6 +71,67 @@ IMPLEMENT_NETWORKCLASS_ALIASED( GameRulesProxy, DT_GameRulesProxy ) BEGIN_NETWORK_TABLE_NOBASE( CGameRulesProxy, DT_GameRulesProxy ) END_NETWORK_TABLE() +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CGameRules, SCRIPT_SINGLETON "The container of the game's rules, handling behavior which could be different on a game-by-game basis." ) + + DEFINE_SCRIPTFUNC( Name, "Gets the name of these rules." ) + + DEFINE_SCRIPTFUNC( Damage_IsTimeBased, "Damage types that are time-based." ) + DEFINE_SCRIPTFUNC( Damage_ShouldGibCorpse, "Damage types that gib the corpse." ) + DEFINE_SCRIPTFUNC( Damage_ShowOnHUD, "Damage types that have client HUD art." ) + DEFINE_SCRIPTFUNC( Damage_NoPhysicsForce, "Damage types that don't have to supply a physics force & position." ) + DEFINE_SCRIPTFUNC( Damage_ShouldNotBleed, "Damage types that don't make the player bleed." ) + + DEFINE_SCRIPTFUNC( ShouldCollide, "Returns whether two collision groups collide with each other in this game." ) + + DEFINE_SCRIPTFUNC( DefaultFOV, "Default player FOV in this game." ) + + DEFINE_SCRIPTFUNC( GetDamageMultiplier, "Ammo type damage multiplier." ) + + DEFINE_SCRIPTFUNC( IsMultiplayer, "Returns true if this is a multiplayer game (like co-op or deathmatch)." ) + + DEFINE_SCRIPTFUNC( InRoundRestart, "Returns true if the round is restarting." ) + + DEFINE_SCRIPTFUNC( AllowThirdPersonCamera, "Returns true if third-person camera is allowed." ) + +#ifdef CLIENT_DLL + + DEFINE_SCRIPTFUNC( IsBonusChallengeTimeBased, "" ) + DEFINE_SCRIPTFUNC( AllowMapParticleEffect, "" ) + DEFINE_SCRIPTFUNC( AllowWeatherParticles, "" ) + DEFINE_SCRIPTFUNC( AllowMapVisionFilterShaders, "" ) + DEFINE_SCRIPTFUNC( TranslateEffectForVisionFilter, "" ) + DEFINE_SCRIPTFUNC( IsLocalPlayer, "" ) + DEFINE_SCRIPTFUNC( ShouldWarnOfAbandonOnQuit, "" ) + +#else + + DEFINE_SCRIPTFUNC( RefreshSkillData, "" ) + + DEFINE_SCRIPTFUNC( IsSkillLevel, "Returns true if the game is set to the specified difficulty/skill level." ) + DEFINE_SCRIPTFUNC( GetSkillLevel, "Returns the game's difficulty/skill level." ) + DEFINE_SCRIPTFUNC( SetSkillLevel, "Sets the game's difficulty/skill level." ) + + DEFINE_SCRIPTFUNC_NAMED( FAllowFlashlight, "AllowFlashlight", "Returns true if players are allowed to switch on their flashlight." ) + + DEFINE_SCRIPTFUNC( IsDeathmatch, "" ) + DEFINE_SCRIPTFUNC( IsTeamplay, "" ) + DEFINE_SCRIPTFUNC( IsCoOp, "" ) + + DEFINE_SCRIPTFUNC( GetGameDescription, "This is the game description that gets seen in server browsers." ) + + DEFINE_SCRIPTFUNC( AllowSPRespawn, "" ) + + DEFINE_SCRIPTFUNC_NAMED( FAllowNPCs, "AllowNPCs", "Returns true if NPCs are allowed." ) + +#endif + + DEFINE_SCRIPTFUNC( GetGameTypeName, "" ) + DEFINE_SCRIPTFUNC( GetGameType, "" ) + +END_SCRIPTDESC() +#endif + CGameRulesProxy::CGameRulesProxy() { diff --git a/sp/src/game/shared/mapbase/mapbase_shared.cpp b/sp/src/game/shared/mapbase/mapbase_shared.cpp index 74d64ad0..2763b457 100644 --- a/sp/src/game/shared/mapbase/mapbase_shared.cpp +++ b/sp/src/game/shared/mapbase/mapbase_shared.cpp @@ -69,7 +69,7 @@ ConVar mapbase_load_actbusy("mapbase_load_actbusy", "1", FCVAR_ARCHIVE, "Should #ifdef GAME_DLL // This cvar should change with each Mapbase update -ConVar mapbase_version( "mapbase_version", "6.0", FCVAR_NONE, "The version of Mapbase currently being used in this mod." ); +ConVar mapbase_version( "mapbase_version", "6.1", FCVAR_NONE, "The version of Mapbase currently being used in this mod." ); extern void MapbaseGameLog_Init(); diff --git a/sp/src/game/shared/mapbase/vscript_consts_shared.cpp b/sp/src/game/shared/mapbase/vscript_consts_shared.cpp index a240633e..b03ee0e8 100644 --- a/sp/src/game/shared/mapbase/vscript_consts_shared.cpp +++ b/sp/src/game/shared/mapbase/vscript_consts_shared.cpp @@ -24,32 +24,32 @@ BEGIN_SCRIPTENUM( IN, "Button mask bindings" ) - DEFINE_ENUMCONST_NAMED( IN_ATTACK, "ATTACK", "" ) - DEFINE_ENUMCONST_NAMED( IN_JUMP, "JUMP", "" ) - DEFINE_ENUMCONST_NAMED( IN_DUCK, "DUCK", "" ) - DEFINE_ENUMCONST_NAMED( IN_FORWARD, "FORWARD", "" ) - DEFINE_ENUMCONST_NAMED( IN_BACK, "BACK", "" ) - DEFINE_ENUMCONST_NAMED( IN_USE, "USE", "" ) - DEFINE_ENUMCONST_NAMED( IN_CANCEL, "CANCEL", "" ) - DEFINE_ENUMCONST_NAMED( IN_LEFT, "LEFT", "" ) - DEFINE_ENUMCONST_NAMED( IN_RIGHT, "RIGHT", "" ) - DEFINE_ENUMCONST_NAMED( IN_MOVELEFT, "MOVELEFT", "" ) - DEFINE_ENUMCONST_NAMED( IN_MOVERIGHT, "MOVERIGHT", "" ) - DEFINE_ENUMCONST_NAMED( IN_ATTACK2, "ATTACK2", "" ) - DEFINE_ENUMCONST_NAMED( IN_RUN, "RUN", "" ) - DEFINE_ENUMCONST_NAMED( IN_RELOAD, "RELOAD", "" ) - DEFINE_ENUMCONST_NAMED( IN_ALT1, "ALT1", "" ) - DEFINE_ENUMCONST_NAMED( IN_ALT2, "ALT2", "" ) - DEFINE_ENUMCONST_NAMED( IN_SCORE, "SCORE", "" ) - DEFINE_ENUMCONST_NAMED( IN_SPEED, "SPEED", "" ) - DEFINE_ENUMCONST_NAMED( IN_WALK, "WALK", "" ) - DEFINE_ENUMCONST_NAMED( IN_ZOOM, "ZOOM", "" ) - DEFINE_ENUMCONST_NAMED( IN_WEAPON1, "WEAPON1", "" ) - DEFINE_ENUMCONST_NAMED( IN_WEAPON2, "WEAPON2", "" ) - DEFINE_ENUMCONST_NAMED( IN_BULLRUSH, "BULLRUSH", "" ) - DEFINE_ENUMCONST_NAMED( IN_GRENADE1, "GRENADE1", "" ) - DEFINE_ENUMCONST_NAMED( IN_GRENADE2, "GRENADE2", "" ) - DEFINE_ENUMCONST_NAMED( IN_ATTACK3, "ATTACK3", "" ) + DEFINE_ENUMCONST_NAMED( IN_ATTACK, "ATTACK", "Button for +attack" ) + DEFINE_ENUMCONST_NAMED( IN_JUMP, "JUMP", "Button for +jump" ) + DEFINE_ENUMCONST_NAMED( IN_DUCK, "DUCK", "Button for +duck" ) + DEFINE_ENUMCONST_NAMED( IN_FORWARD, "FORWARD", "Button for +forward" ) + DEFINE_ENUMCONST_NAMED( IN_BACK, "BACK", "Button for +back" ) + DEFINE_ENUMCONST_NAMED( IN_USE, "USE", "Button for +use" ) + DEFINE_ENUMCONST_NAMED( IN_CANCEL, "CANCEL", "Special button flag for attack cancel" ) + DEFINE_ENUMCONST_NAMED( IN_LEFT, "LEFT", "Button for +left" ) + DEFINE_ENUMCONST_NAMED( IN_RIGHT, "RIGHT", "Button for +right" ) + DEFINE_ENUMCONST_NAMED( IN_MOVELEFT, "MOVELEFT", "Button for +moveleft" ) + DEFINE_ENUMCONST_NAMED( IN_MOVERIGHT, "MOVERIGHT", "Button for +moveright" ) + DEFINE_ENUMCONST_NAMED( IN_ATTACK2, "ATTACK2", "Button for +attack2" ) + DEFINE_ENUMCONST_NAMED( IN_RUN, "RUN", "Unused button (see IN.SPEED for sprint)" ) + DEFINE_ENUMCONST_NAMED( IN_RELOAD, "RELOAD", "Button for +reload" ) + DEFINE_ENUMCONST_NAMED( IN_ALT1, "ALT1", "Button for +alt1" ) + DEFINE_ENUMCONST_NAMED( IN_ALT2, "ALT2", "Button for +alt2" ) + DEFINE_ENUMCONST_NAMED( IN_SCORE, "SCORE", "Button for +score" ) + DEFINE_ENUMCONST_NAMED( IN_SPEED, "SPEED", "Button for +speed" ) + DEFINE_ENUMCONST_NAMED( IN_WALK, "WALK", "Button for +walk" ) + DEFINE_ENUMCONST_NAMED( IN_ZOOM, "ZOOM", "Button for +zoom" ) + DEFINE_ENUMCONST_NAMED( IN_WEAPON1, "WEAPON1", "Special button used by weapons themselves" ) + DEFINE_ENUMCONST_NAMED( IN_WEAPON2, "WEAPON2", "Special button used by weapons themselves" ) + DEFINE_ENUMCONST_NAMED( IN_BULLRUSH, "BULLRUSH", "Unused button" ) + DEFINE_ENUMCONST_NAMED( IN_GRENADE1, "GRENADE1", "Button for +grenade1" ) + DEFINE_ENUMCONST_NAMED( IN_GRENADE2, "GRENADE2", "Button for +grenade2" ) + DEFINE_ENUMCONST_NAMED( IN_ATTACK3, "ATTACK3", "Button for +attack3" ) END_SCRIPTENUM(); @@ -92,6 +92,18 @@ END_SCRIPTENUM(); //============================================================================= //============================================================================= +BEGIN_SCRIPTENUM( MapLoad, "Map load enum for GetLoadType()" ) + + DEFINE_ENUMCONST_NAMED( MapLoad_NewGame, "NewGame", "Map was loaded from a new game" ) + DEFINE_ENUMCONST_NAMED( MapLoad_LoadGame, "LoadGame", "Map was loaded from a save file" ) + DEFINE_ENUMCONST_NAMED( MapLoad_Transition, "Transition", "Map was loaded from a level transition" ) + DEFINE_ENUMCONST_NAMED( MapLoad_Background, "Background", "Map was loaded as a background map" ) + +END_SCRIPTENUM(); + +//============================================================================= +//============================================================================= + void RegisterActivityConstants() { // Make sure there are no activities declared yet @@ -463,6 +475,16 @@ void RegisterSharedScriptConstants() ScriptRegisterConstant( g_pScriptVM, NPC_STATE_PRONE, "When in clutches of barnacle (NPC state type used in GetNPCState(), etc.)" ); ScriptRegisterConstant( g_pScriptVM, NPC_STATE_DEAD, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, AISS_AWAKE, "NPC is awake. (NPC sleep state used in Get/SetSleepState())" ); + ScriptRegisterConstant( g_pScriptVM, AISS_WAITING_FOR_THREAT, "NPC is asleep and will awaken upon seeing an enemy. (NPC sleep state used in Get/SetSleepState())" ); + ScriptRegisterConstant( g_pScriptVM, AISS_WAITING_FOR_PVS, "NPC is asleep and will awaken upon entering a player's PVS. (NPC sleep state used in Get/SetSleepState())" ); + ScriptRegisterConstant( g_pScriptVM, AISS_WAITING_FOR_INPUT, "NPC is asleep and will only awaken upon receiving the Wake input. (NPC sleep state used in Get/SetSleepState())" ); + //ScriptRegisterConstant( g_pScriptVM, AISS_AUTO_PVS, "" ); + //ScriptRegisterConstant( g_pScriptVM, AISS_AUTO_PVS_AFTER_PVS, "" ); + ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAGS_NONE, "No sleep flags. (NPC sleep flag used in Add/Remove/HasSleepFlags())" ); + ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAG_AUTO_PVS, "Indicates a NPC will sleep upon exiting PVS. (NPC sleep flag used in Add/Remove/HasSleepFlags())" ); + ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAG_AUTO_PVS_AFTER_PVS, "Indicates a NPC will sleep upon exiting PVS after entering PVS for the first time(?????) (NPC sleep flag used in Add/Remove/HasSleepFlags())" ); + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_PLAYING, "SCRIPT_PLAYING", "Playing the action animation." ); ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_WAIT, "SCRIPT_WAIT", "Waiting on everyone in the script to be ready. Plays the pre idle animation if there is one." ); ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_POST_IDLE, "SCRIPT_POST_IDLE", "Playing the post idle animation after playing the action animation." ); @@ -475,6 +497,11 @@ void RegisterSharedScriptConstants() // // Misc. General // + ScriptRegisterConstant( g_pScriptVM, DAMAGE_NO, "Don't take damage (Use with GetTakeDamage/SetTakeDamage)" ); + ScriptRegisterConstant( g_pScriptVM, DAMAGE_EVENTS_ONLY, "Call damage functions, but don't modify health (Use with GetTakeDamage/SetTakeDamage)" ); + ScriptRegisterConstant( g_pScriptVM, DAMAGE_YES, "Allow damage to be taken (Use with GetTakeDamage/SetTakeDamage)" ); + ScriptRegisterConstant( g_pScriptVM, DAMAGE_AIM, "(Use with GetTakeDamage/SetTakeDamage)" ); + #ifdef GAME_DLL ScriptRegisterConstant( g_pScriptVM, GLOBAL_OFF, "Global state used by the Globals singleton." ); ScriptRegisterConstant( g_pScriptVM, GLOBAL_ON, "Global state used by the Globals singleton." ); diff --git a/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp b/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp index cab7d67d..189f8883 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp @@ -50,12 +50,7 @@ bool ScriptMegaPhyscannonActive() #endif //----------------------------------------------------------------------------- -// Purpose: Returns how much damage the given ammo type should do to the victim -// when fired by the attacker. -// Input : pAttacker - Dude what shot the gun. -// pVictim - Dude what done got shot. -// nAmmoType - What been shot out. -// Output : How much hurt to put on dude what done got shot (pVictim). +// Purpose: //----------------------------------------------------------------------------- void CHalfLife2::RegisterScriptFunctions( void ) { diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp index 76aa7cdd..c0668e8f 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp @@ -81,8 +81,29 @@ void ParseScriptTableKeyValues( CBaseEntity *pEntity, HSCRIPT hKV ) switch (varValue.m_type) { case FIELD_CSTRING: pEntity->KeyValue( varKey.m_pszString, varValue.m_pszString ); break; + case FIELD_INTEGER: pEntity->KeyValueFromInt( varKey.m_pszString, varValue.m_int ); break; case FIELD_FLOAT: pEntity->KeyValue( varKey.m_pszString, varValue.m_float ); break; case FIELD_VECTOR: pEntity->KeyValue( varKey.m_pszString, *varValue.m_pVector ); break; + case FIELD_HSCRIPT: + { + if ( varValue.m_hScript ) + { + // Entity + if (ToEnt( varValue.m_hScript )) + { + pEntity->KeyValue( varKey.m_pszString, STRING( ToEnt( varValue.m_hScript )->GetEntityName() ) ); + } + + // Color + else if (Color *color = HScriptToClass( varValue.m_hScript )) + { + char szTemp[64]; + Q_snprintf( szTemp, sizeof( szTemp ), "%i %i %i %i", color->r(), color->g(), color->b(), color->a() ); + pEntity->KeyValue( varKey.m_pszString, szTemp ); + } + } + break; + } } g_pScriptVM->ReleaseValue( varKey ); @@ -94,7 +115,7 @@ void PrecacheEntityFromTable( const char *pszClassname, HSCRIPT hKV ) { if ( IsEntityCreationAllowedInScripts() == false ) { - Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + CGWarning( 0, CON_GROUP_VSCRIPT, "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); return; } @@ -118,7 +139,7 @@ HSCRIPT SpawnEntityFromTable( const char *pszClassname, HSCRIPT hKV ) { if ( IsEntityCreationAllowedInScripts() == false ) { - Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + CGWarning( 0, CON_GROUP_VSCRIPT, "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); return NULL; } @@ -162,6 +183,31 @@ HSCRIPT EntIndexToHScript( int index ) //----------------------------------------------------------------------------- #ifndef CLIENT_DLL +void SaveEntityKVToTable( HSCRIPT hEnt, HSCRIPT hTable ) +{ + CBaseEntity *pEnt = ToEnt( hEnt ); + if (pEnt == NULL) + return; + + variant_t var; // For Set() + ScriptVariant_t varScript, varTable = hTable; + + // loop through the data description list, reading each data desc block + for ( datamap_t *dmap = pEnt->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_KEY) ) + { + var.Set( dmap->dataDesc[i].fieldType, ((char*)pEnt) + dmap->dataDesc[i].fieldOffset[ TD_OFFSET_NORMAL ] ); + var.SetScriptVariant( varScript ); + g_pScriptVM->SetValue( varTable, dmap->dataDesc[i].externalName, varScript ); + } + } + } +} + HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV ) { if ( IsEntityCreationAllowedInScripts() == false ) @@ -279,8 +325,30 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( surfacedata_t, "surfacedata_t", "Handle for accessi DEFINE_SCRIPTFUNC( GetJumpFactor, "The surface's jump factor." ) DEFINE_SCRIPTFUNC( GetMaterialChar, "The surface's material character." ) + + DEFINE_SCRIPTFUNC( GetSoundStepLeft, "The surface's left step sound." ) + DEFINE_SCRIPTFUNC( GetSoundStepRight, "The surface's right step sound." ) + DEFINE_SCRIPTFUNC( GetSoundImpactSoft, "The surface's soft impact sound." ) + DEFINE_SCRIPTFUNC( GetSoundImpactHard, "The surface's hard impact sound." ) + DEFINE_SCRIPTFUNC( GetSoundScrapeSmooth, "The surface's smooth scrape sound." ) + DEFINE_SCRIPTFUNC( GetSoundScrapeRough, "The surface's rough scrape sound." ) + DEFINE_SCRIPTFUNC( GetSoundBulletImpact, "The surface's bullet impact sound." ) + DEFINE_SCRIPTFUNC( GetSoundRolling, "The surface's rolling sound." ) + DEFINE_SCRIPTFUNC( GetSoundBreak, "The surface's break sound." ) + DEFINE_SCRIPTFUNC( GetSoundStrain, "The surface's strain sound." ) END_SCRIPTDESC(); +const char* surfacedata_t::GetSoundStepLeft() { return physprops->GetString( sounds.stepleft ); } +const char* surfacedata_t::GetSoundStepRight() { return physprops->GetString( sounds.stepright ); } +const char* surfacedata_t::GetSoundImpactSoft() { return physprops->GetString( sounds.impactSoft ); } +const char* surfacedata_t::GetSoundImpactHard() { return physprops->GetString( sounds.impactHard ); } +const char* surfacedata_t::GetSoundScrapeSmooth() { return physprops->GetString( sounds.scrapeSmooth ); } +const char* surfacedata_t::GetSoundScrapeRough() { return physprops->GetString( sounds.scrapeRough ); } +const char* surfacedata_t::GetSoundBulletImpact() { return physprops->GetString( sounds.bulletImpact ); } +const char* surfacedata_t::GetSoundRolling() { return physprops->GetString( sounds.rolling ); } +const char* surfacedata_t::GetSoundBreak() { return physprops->GetString( sounds.breakSound ); } +const char* surfacedata_t::GetSoundStrain() { return physprops->GetString( sounds.strainSound ); } + BEGIN_SCRIPTDESC_ROOT_NAMED( CSurfaceScriptAccessor, "csurface_t", "Handle for accessing csurface_t info." ) DEFINE_SCRIPTFUNC( Name, "The surface's name." ) DEFINE_SCRIPTFUNC( SurfaceProps, "The surface's properties." ) @@ -717,6 +785,7 @@ void RegisterSharedScriptFunctions() ScriptRegisterFunction( g_pScriptVM, NXPrint, "Notification print, customised" ); #ifndef CLIENT_DLL + ScriptRegisterFunction( g_pScriptVM, SaveEntityKVToTable, "Saves an entity's keyvalues to a table." ); ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromKeyValues, "Spawns an entity with the keyvalues in a CScriptKeyValues handle." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchSpawn, "DispatchSpawn", "Spawns an unspawned entity." ); #endif diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.h b/sp/src/game/shared/mapbase/vscript_funcs_shared.h index 2c6aaa1d..ad3192bf 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_shared.h +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.h @@ -106,7 +106,7 @@ public: bool StartSolid() const { return m_tr.startsolid; } HSCRIPT Surface() { return m_surfaceAccessor; } - void SetSurface( HSCRIPT hPlaneAccessor ) { m_surfaceAccessor = hPlaneAccessor; } + void SetSurface( HSCRIPT hSurfAccessor ) { m_surfaceAccessor = hSurfAccessor; } HSCRIPT Plane() { return m_planeAccessor; } void SetPlane( HSCRIPT hPlaneAccessor ) { m_planeAccessor = hPlaneAccessor; } diff --git a/sp/src/game/shared/mapbase/vscript_singletons.cpp b/sp/src/game/shared/mapbase/vscript_singletons.cpp index 297b1b9a..0f7fcec4 100644 --- a/sp/src/game/shared/mapbase/vscript_singletons.cpp +++ b/sp/src/game/shared/mapbase/vscript_singletons.cpp @@ -1164,6 +1164,7 @@ HSCRIPT CScriptReadWriteFile::ScriptKeyValuesRead( const char *szFile ) KeyValues *pKV = new KeyValues( szFile ); if ( !pKV->LoadFromFile( g_pFullFileSystem, pszFullName, SCRIPT_RW_PATH_ID ) ) { + pKV->deleteThis(); return NULL; } @@ -1326,7 +1327,7 @@ void RegisterScriptSingletons() ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::ScriptFileWrite, "StringToFile", "Stores the string into the file" ); ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::ScriptFileRead, "FileToString", "Returns the string from the file, null if no file or file is too big." ); ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::ScriptKeyValuesWrite, "KeyValuesToFile", "Stores the CScriptKeyValues into the file" ); - ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::ScriptKeyValuesRead, "KeyValuesToString", "Returns the CScriptKeyValues from the file, null if no file or file is too big." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::ScriptKeyValuesRead, "FileToKeyValues", "Returns the CScriptKeyValues from the file, null if no file or file is too big." ); ScriptRegisterFunction( g_pScriptVM, ListenToGameEvent, "Register as a listener for a game event from script." ); ScriptRegisterFunctionNamed( g_pScriptVM, CScriptGameEventListener::StopListeningToGameEvent, "StopListeningToGameEvent", "Stop the specified event listener." ); @@ -1343,6 +1344,7 @@ void RegisterScriptSingletons() #endif // Singletons not unique to VScript (not declared or defined here) + g_pScriptVM->RegisterInstance( GameRules(), "GameRules" ); g_pScriptVM->RegisterInstance( GetAmmoDef(), "AmmoDef" ); #ifndef CLIENT_DLL g_pScriptVM->RegisterInstance( &g_AI_SquadManager, "Squads" ); diff --git a/sp/src/game/shared/postprocess_shared.h b/sp/src/game/shared/postprocess_shared.h new file mode 100644 index 00000000..9d3c7df0 --- /dev/null +++ b/sp/src/game/shared/postprocess_shared.h @@ -0,0 +1,54 @@ +//====== Copyright © 1996-2009, Valve Corporation, All rights reserved. ======= +// +// Purpose: common definitions for post-processing effects +// +//============================================================================= + +#ifndef POSTPROCESS_SHARED_H +#define POSTPROCESS_SHARED_H + +#if defined( COMPILER_MSVC ) +#pragma once +#endif + +enum PostProcessParameterNames_t +{ + PPPN_FADE_TIME = 0, + PPPN_LOCAL_CONTRAST_STRENGTH, + PPPN_LOCAL_CONTRAST_EDGE_STRENGTH, + PPPN_VIGNETTE_START, + PPPN_VIGNETTE_END, + PPPN_VIGNETTE_BLUR_STRENGTH, + PPPN_FADE_TO_BLACK_STRENGTH, + PPPN_DEPTH_BLUR_FOCAL_DISTANCE, + PPPN_DEPTH_BLUR_STRENGTH, + PPPN_SCREEN_BLUR_STRENGTH, + PPPN_FILM_GRAIN_STRENGTH, + + POST_PROCESS_PARAMETER_COUNT +}; + +struct PostProcessParameters_t +{ + PostProcessParameters_t() + { + memset( m_flParameters, 0, sizeof( m_flParameters ) ); + m_flParameters[ PPPN_VIGNETTE_START ] = 0.8f; + m_flParameters[ PPPN_VIGNETTE_END ] = 1.1f; + } + + float m_flParameters[ POST_PROCESS_PARAMETER_COUNT ]; + + bool operator !=(PostProcessParameters_t other) + { + for (int i = 0; i < POST_PROCESS_PARAMETER_COUNT; ++i) + { + if (m_flParameters[i] != other.m_flParameters[i]) + return true; + } + + return false; + } +}; + +#endif // POSTPROCESS_SHARED_H \ No newline at end of file diff --git a/sp/src/game/shared/util_shared.h b/sp/src/game/shared/util_shared.h index 6ed58bf2..dc8523e3 100644 --- a/sp/src/game/shared/util_shared.h +++ b/sp/src/game/shared/util_shared.h @@ -584,6 +584,22 @@ public: return (m_timestamp > 0.0f) ? m_duration : 0.0f; } + /// 1.0 for newly started, 0.0 for elapsed + float GetRemainingRatio( void ) const + { + if (HasStarted() && m_duration > 0.0f) + { + float left = GetRemainingTime() / m_duration; + if (left < 0.0f) + return 0.0f; + if (left > 1.0f) + return 1.0f; + return left; + } + + return 0.0f; + } + private: float m_duration; float m_timestamp; diff --git a/sp/src/materialsystem/stdshaders/blurgaussian_3x3_ps2x.fxc b/sp/src/materialsystem/stdshaders/blurgaussian_3x3_ps2x.fxc new file mode 100644 index 00000000..5dbf655e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/blurgaussian_3x3_ps2x.fxc @@ -0,0 +1,22 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +sampler g_texSampler : register( s0 ); + +struct PS_INPUT +{ + float2 uv : TEXCOORD0; +}; + +float2 g_vPsTapOffsets[2] : register( c0 ); + +float4 main( PS_INPUT i ) : COLOR +{ + float4 cOut; + + cOut = 0.25 * tex2D( g_texSampler, i.uv + g_vPsTapOffsets[0] ); + cOut += 0.25 * tex2D( g_texSampler, i.uv - g_vPsTapOffsets[0] ); + cOut += 0.25 * tex2D( g_texSampler, i.uv + g_vPsTapOffsets[1] ); + cOut += 0.25 * tex2D( g_texSampler, i.uv - g_vPsTapOffsets[1] ); + + return cOut; +} diff --git a/sp/src/materialsystem/stdshaders/depth_of_field_ps20b.fxc b/sp/src/materialsystem/stdshaders/depth_of_field_ps20b.fxc new file mode 100644 index 00000000..6eb5cb70 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depth_of_field_ps20b.fxc @@ -0,0 +1,137 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// DYNAMIC: "QUALITY" "0..3" + +// Includes ======================================================================================= +#include "common_ps_fxc.h" + +// Texture Samplers =============================================================================== +sampler g_tFullFB : register( s0 ); +sampler g_tSmallFB : register( s1 ); + +// Shaders Constants and Globals ================================================================== +float4 g_vDists : register( c0 ); +#define g_flNearBlurDist g_vDists.x +#define g_flNearFocusDist g_vDists.y +#define g_flFarFocusDist g_vDists.z +#define g_flFarBlurDist g_vDists.w + +float3 g_vBlurAmounts : register( c1 ); +#define g_flMaxBlurRadius g_vBlurAmounts.x +#define g_flNearBlurStrength g_vBlurAmounts.y +#define g_flFarBlurStrength g_vBlurAmounts.z + +float3 g_vNearFarDists : register( c2 ); +#define g_flNearPlaneDist g_vNearFarDists.x +#define g_flFarPlaneDist g_vNearFarDists.y +#define g_flDepthConv g_vNearFarDists.z + +float4 g_vMagicConsts : register( c3 ); + +#if ( QUALITY == 0 ) + #define NUM_SAMPLES 8 // These must match the C code +#elif ( QUALITY == 1 ) + #define NUM_SAMPLES 16 +#elif ( QUALITY == 2 ) + #define NUM_SAMPLES 16 +#elif ( QUALITY == 3 ) + #define NUM_SAMPLES 32 +#endif + +float4 g_vPoisson[ NUM_SAMPLES/2 ] : register( c4 ); + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float2 vUv0 : TEXCOORD0; +}; + +float DestAlphaDepthToViewSpaceDepth( float flDepth ) +{ + return g_flDepthConv * flDepth + g_flNearPlaneDist; +} + +// returns blur radius from depth as a fraction of max_blur. +float BlurAmountFromDepth( float flDestAlphaDepth ) +{ + /* + dist = DestAlphaDepthToViewSpaceDepth( flDestAlphaDepth ); + float flBlur = max( g_flNearBlurStrength * saturate( (flDestAlphaDepth - g_flNearFocusDist) / ( g_flNearBlurDist - g_flNearFocusDist ) ), + g_flFarBlurStrength * saturate( (flDestAlphaDepth - g_flFarFocusDist) / ( g_flFarBlurDist - g_flFarFocusDist ) ) ); + */ + + // A more optimized version that concatenates the math above and the one in DestAlphaDepthToViewSpaceDepth to a single muladd + float flBlur = max( g_flNearBlurStrength * saturate( g_vMagicConsts.x * flDestAlphaDepth + g_vMagicConsts.y ), + g_flFarBlurStrength * saturate( g_vMagicConsts.z * flDestAlphaDepth + g_vMagicConsts.w ) ); + return flBlur; +} + +float BlurRadiusFromDepth( float flDepth ) +{ + return g_flMaxBlurRadius * BlurAmountFromDepth( flDepth ); +} + +float4 ComputeTap( float flCenterDepth, float flCenterBlurRadius, float2 vUV, float2 vPoisson ) +{ + float4 cTapSmall; + float4 cTap; + float2 vPoissonUV = vUV.xy + flCenterBlurRadius * vPoisson.xy; + + cTapSmall = tex2D( g_tSmallFB, vPoissonUV.xy ); + cTap = tex2D( g_tFullFB, vPoissonUV.xy ); + + float flTapBlur = BlurAmountFromDepth( cTap.a ); // Maybe 50/50 mix between low and high here? + + cTap = lerp( cTap, cTapSmall, saturate( 2.2 * flTapBlur ) ); // TODO: tweak blur amount. + float flLerpedTapBlur = BlurAmountFromDepth( cTap.a ); + + float weight = ( cTap.a >= flCenterDepth ) ? 1.0 : ( flLerpedTapBlur*flLerpedTapBlur ); + return float4( cTap.rgb, 1 ) * weight; +} + +float4 ComputeTapHQ( float flCenterDepth, float flCenterBlurRadius, float2 vUV, float2 vPoisson ) +{ + float4 cTap; + + cTap = tex2D( g_tFullFB, vUV.xy + flCenterBlurRadius * vPoisson.xy ); + float flTapBlur = BlurAmountFromDepth( cTap.a ); + float weight = ( cTap.a >= flCenterDepth ) ? 1.0 : ( flTapBlur * flTapBlur ); + return float4( cTap.rgb, 1 ) * weight; +} + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // TODO: BETTER DOWNSAMPLE THAT TAKES DEPTH INTO ACCOUNT? + + float4 cOut = { 0, 0, 0, 0 }; + float4 cCenterTap = tex2D( g_tFullFB, i.vUv0 ); + float flCenterBlurRadius = BlurRadiusFromDepth( cCenterTap.a ); // circle of confusion radius for current pixel + cCenterTap.a -= 0.001; // z-bias to avoid strange banding artifact on almost orthogonal walls + +#if ( QUALITY < 2 ) + // ATI's Ruby1-style algorithm + for ( int t = 0; t < NUM_SAMPLES/2; t++ ) + { + cOut.rgba += ComputeTap( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].xy ); + cOut.rgba += ComputeTap( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].wz ); + } +#else + // Less fancy, with less fetches per tap and less math. Needs more samples to look smooth. + cOut = cCenterTap; + cOut.a = 1.0; // Use the center sample we just fetched + for ( int t = 0; t < NUM_SAMPLES/2; t++ ) + { + cOut.rgba += ComputeTapHQ( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].xy ); + cOut.rgba += ComputeTapHQ( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].wz ); + } +#endif + //cOut.rgb = cOut.a / float(NUM_SAMPLES+1); + //cOut = lerp( tex2D( g_tFullFB, i.vUv0 ), tex2D( g_tSmallFB, i.vUv0 ).aaaa, 0.5 ); + if ( cOut.a > 0.0 ) + cOut.rgba /= cOut.a; + else + cOut.rgba = cCenterTap.rgba; + + return cOut; +} diff --git a/sp/src/materialsystem/stdshaders/depth_of_field_vs20.fxc b/sp/src/materialsystem/stdshaders/depth_of_field_vs20.fxc new file mode 100644 index 00000000..37382c7d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depth_of_field_vs20.fxc @@ -0,0 +1,29 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// Includes ======================================================================================= +#include "common_vs_fxc.h" + +// Input values =================================================================================== +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +// Interpolated values ============================================================================ +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 vUv0 : TEXCOORD0; +}; + +// Main =========================================================================================== +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + o.projPos.xyzw = float4( i.vPos.xyz, 1.0f ); + o.vUv0.xy = i.vBaseTexCoord.xy; + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/depthoffield_dx9.cpp b/sp/src/materialsystem/stdshaders/depthoffield_dx9.cpp new file mode 100644 index 00000000..69650e74 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depthoffield_dx9.cpp @@ -0,0 +1,280 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: Depth of field material +// +//===========================================================================// + +#include "BaseVSShader.h" +#include "depth_of_field_vs20.inc" +#include "depth_of_field_ps20b.inc" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ConVar mat_dof_max_blur_radius( "mat_dof_max_blur_radius", "50" ); +ConVar mat_dof_quality( "mat_dof_quality", "3" ); +ConVar mat_dof_constant( "mat_dof_constant", "512" ); + +// 8 samples +static const float s_flPoissonConstsQuality0[16] = { + 0.0, 0.0, + 0.527837, -0.085868, + -0.040088, 0.536087, + -0.670445, -0.179949, + -0.419418, -0.616039, + 0.440453, -0.639399, + -0.757088, 0.349334, + 0.574619, 0.685879 +}; + +// 16 samples +static const float s_flPoissonConstsQuality1[32] = { + 0.0747, -0.8341, + -0.9138, 0.3251, + 0.8667, -0.3029, + -0.4642, 0.2187, + -0.1505, 0.7320, + 0.7310, -0.6786, + 0.2859, -0.3254, + -0.1311, -0.2292, + 0.3518, 0.6470, + -0.7485, -0.6307, + 0.1687, 0.1873, + -0.3604, -0.7483, + -0.5658, -0.1521, + 0.7102, 0.0536, + -0.6056, 0.7747, + 0.7793, 0.6194 +}; + +// 32 samples +static const float s_flPoissonConstsQuality2[64] = { + 0.0854f, -0.0644f, + 0.8744f, 0.1665f, + 0.2329f, 0.3995f, + -0.7804f, 0.5482f, + -0.4577f, 0.7647f, + -0.1936f, 0.5564f, + 0.4205f, -0.5768f, + -0.0304f, -0.9050f, + -0.5215f, 0.1854f, + 0.3161f, -0.2954f, + 0.0666f, -0.5564f, + -0.2137f, -0.0072f, + -0.4112f, -0.3311f, + 0.6438f, -0.2484f, + -0.9055f, -0.0360f, + 0.8323f, 0.5268f, + 0.5592f, 0.3459f, + -0.6797f, -0.5201f, + -0.4325f, -0.8857f, + 0.8768f, -0.4197f, + 0.3090f, -0.8646f, + 0.5034f, 0.8603f, + 0.3752f, 0.0627f, + -0.0161f, 0.2627f, + 0.0969f, 0.7054f, + -0.2291f, -0.6595f, + -0.5887f, -0.1100f, + 0.7048f, -0.6528f, + -0.8438f, 0.2706f, + -0.5061f, 0.4653f, + -0.1245f, -0.3302f, + -0.1801f, 0.8486f +}; + +DEFINE_FALLBACK_SHADER( DepthOfField, DepthOfField_dx9 ) +BEGIN_VS_SHADER_FLAGS( DepthOfField_dx9, "Depth of Field", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( SMALLFB, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallFB1", "Downsampled backbuffer" ) + SHADER_PARAM( NEARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Near plane depth" ) + SHADER_PARAM( FARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Far plane depth" ) + SHADER_PARAM( NEARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near blur plane depth" ) + SHADER_PARAM( NEARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near focus plane depth" ) + SHADER_PARAM( FARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far focus plane depth" ) + SHADER_PARAM( FARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far blur plane depth" ) + SHADER_PARAM( NEARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max near blur radius" ) + SHADER_PARAM( FARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max far blur radius" ) + SHADER_PARAM( QUALITY, SHADER_PARAM_TYPE_INTEGER, "0", "Quality level. Selects different algorithms." ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_PARAM_STRING_IF_NOT_DEFINED( SMALLFB, "_rt_SmallFB1" ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARPLANE, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARPLANE, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARFOCUSDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARFOCUSDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURRADIUS, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURRADIUS, 0.0f ); + SET_PARAM_INT_IF_NOT_DEFINED( QUALITY, 0 ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 92 ) + { + return "Wireframe"; + } + + return 0; + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if ( params[SMALLFB]->IsDefined() ) + { + LoadTexture( SMALLFB ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + pShaderShadow->EnableSRGBWrite( false ); + + DECLARE_STATIC_VERTEX_SHADER( depth_of_field_vs20 ); + SET_STATIC_VERTEX_SHADER( depth_of_field_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( depth_of_field_ps20b ); + SET_STATIC_PIXEL_SHADER( depth_of_field_ps20b ); + } + else + { + Assert( !"No ps_2_b. This shouldn't be happening" ); + } + + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( depth_of_field_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( depth_of_field_vs20 ); + + // Bind textures + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + BindTexture( SHADER_SAMPLER1, SMALLFB ); + + // near blur = blur of stuff in front of focus range + // far blur = blur of stuff behind focus range + + // C0: set near/far blur and focus distances + // x = near blur distance + // y = near focus distance + // z = far focus distance + // w = far blur distance + // C1: + // x = blur radius for near blur (in pixels) + // y = blur radius for far blur (in pixels) + // TODO: Specifying this stuff in pixels makes blurs look smaller on high backbuffer resolutions. + // This might be a problem for tweaking these values. + float vConst[16] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + + vConst[0] = params[NEARBLURDEPTH]->GetFloatValue(); + vConst[1] = params[NEARFOCUSDEPTH]->GetFloatValue(); + vConst[2] = params[FARFOCUSDEPTH]->GetFloatValue(); + vConst[3] = params[FARBLURDEPTH]->GetFloatValue();; + // max blur radius will need to be set based on quality level and screen res + vConst[4] = mat_dof_max_blur_radius.GetFloat(); + vConst[5] = MIN( params[NEARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4]; // near and far blur radius as fraction of max radius + vConst[6] = MIN( params[FARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4]; + + vConst[8] = params[NEARPLANE]->GetFloatValue(); + vConst[9] = params[FARPLANE]->GetFloatValue(); + + vConst[10] = mat_dof_constant.GetFloat() * ( vConst[9] - vConst[8] ) / vConst[9]; + + vConst[12] = vConst[10] / ( vConst[0] - vConst[1] ); + vConst[13] = ( vConst[8] - vConst[1] ) / ( vConst[0] - vConst[1] ); + vConst[14] = vConst[10] / ( vConst[3] - vConst[2] ); + vConst[15] = ( vConst[8] - vConst[2] ) / ( vConst[3] - vConst[2] ); + + pShaderAPI->SetPixelShaderConstant( 0, vConst, 4 ); + + // set up poisson sample location constants pre-divided by screen res + int nNumPoissonSamples = 0; + const float *pPoissonSrc = NULL; + switch ( params[QUALITY]->GetIntValue() ) + { + case 0: + // NOTE: These must match the shader + nNumPoissonSamples = 8; + pPoissonSrc = s_flPoissonConstsQuality0; + break; + + case 1: + case 2: + nNumPoissonSamples = 16; + pPoissonSrc = s_flPoissonConstsQuality1; + break; + + case 3: + nNumPoissonSamples = 32; + pPoissonSrc = s_flPoissonConstsQuality2; + break; + + default: + Warning( "Invalid mat_dof_quality value. Resetting to 0.\n" ); + mat_dof_quality.SetValue( 0 ); + nNumPoissonSamples = 8; + pPoissonSrc = s_flPoissonConstsQuality0; + break; + } + + float vPoissonConst[64]; // temp table + + // Get texture dimensions + ITexture *pTex = params[BASETEXTURE]->GetTextureValue(); + Assert( pTex ); + float flInvTexWidth = 1.0f / static_cast( pTex->GetActualWidth() ); + float flInvTexHeight = 1.0f / static_cast( pTex->GetActualHeight() ); + + for ( int i = 0; i < nNumPoissonSamples; i++ ) + { + vPoissonConst[ 2*i ] = pPoissonSrc[ 2*i ] * flInvTexWidth; + vPoissonConst[ 2*i+1 ] = pPoissonSrc[ 2*i+1 ] * flInvTexHeight; + } + + // swizzle every other 2-tuple so that I can use the free .wz swizzle in the shader + for ( int i = 1; i < nNumPoissonSamples; i += 2) + { + float t = vPoissonConst[ 2*i ]; + vPoissonConst[ 2*i ] = vPoissonConst[ 2*i+1 ]; + vPoissonConst[ 2*i+1 ] = t; + } + + pShaderAPI->SetPixelShaderConstant( 4, vPoissonConst, nNumPoissonSamples / 2 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( depth_of_field_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( QUALITY, params[QUALITY]->GetIntValue() ); + SET_DYNAMIC_PIXEL_SHADER( depth_of_field_ps20b ); + } + else + { + Assert( !"No ps_2_b. This shouldn't be happening" ); + } + } + + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/engine_post_dx9.cpp b/sp/src/materialsystem/stdshaders/engine_post_dx9.cpp new file mode 100644 index 00000000..1c3cdc2b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/engine_post_dx9.cpp @@ -0,0 +1,636 @@ +//========= Copyright © 1996-2007, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "BaseVSShader.h" + +#include "SDK_screenspaceeffect_vs20.inc" +#include "SDK_engine_post_ps20b.inc" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +ConVar mat_screen_blur_override( "mat_screen_blur_override", "-1.0" ); +ConVar mat_depth_blur_focal_distance_override( "mat_depth_blur_focal_distance_override", "-1.0" ); +ConVar mat_depth_blur_strength_override( "mat_depth_blur_strength_override", "-1.0" ); +ConVar mat_grain_scale_override( "mat_grain_scale_override", "-1.0" ); +ConVar mat_local_contrast_scale_override( "mat_local_contrast_scale_override", "0.0" ); +ConVar mat_local_contrast_midtone_mask_override( "mat_local_contrast_midtone_mask_override", "-1.0" ); +ConVar mat_local_contrast_vignette_start_override( "mat_local_contrast_vignette_start_override", "-1.0" ); +ConVar mat_local_contrast_vignette_end_override( "mat_local_contrast_vignette_end_override", "-1.0" ); +ConVar mat_local_contrast_edge_scale_override( "mat_local_contrast_edge_scale_override", "-1000.0" ); + +DEFINE_FALLBACK_SHADER( SDK_Engine_Post, SDK_Engine_Post_dx9 ) +BEGIN_VS_SHADER_FLAGS( SDK_Engine_Post_dx9, "Engine post-processing effects (software anti-aliasing, bloom, color-correction", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "Full framebuffer texture" ) + SHADER_PARAM( AAENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable software anti-aliasing" ) + SHADER_PARAM( AAINTERNAL1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" ) + SHADER_PARAM( AAINTERNAL2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" ) + SHADER_PARAM( AAINTERNAL3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" ) + SHADER_PARAM( BLOOMENABLE, SHADER_PARAM_TYPE_BOOL, "1", "Enable bloom" ) + SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "Bloom scale factor" ) + SHADER_PARAM( SCREENEFFECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "used for paint or vomit screen effect" ) + SHADER_PARAM( DEPTHBLURENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Inexpensive depth-of-field substitute" ) + + SHADER_PARAM( ALLOWVIGNETTE, SHADER_PARAM_TYPE_BOOL, "0", "Allow vignette" ) + SHADER_PARAM( VIGNETTEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable vignette" ) + SHADER_PARAM( INTERNAL_VIGNETTETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "dev/vignette", "" ) + + SHADER_PARAM( ALLOWNOISE, SHADER_PARAM_TYPE_BOOL, "0", "Allow noise" ) + SHADER_PARAM( NOISEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable noise" ) + SHADER_PARAM( NOISESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Noise scale" ) + SHADER_PARAM( NOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Noise texture" ) + + SHADER_PARAM( ALLOWLOCALCONTRAST, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" ) + SHADER_PARAM( LOCALCONTRASTENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" ) + SHADER_PARAM( LOCALCONTRASTSCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast scale" ) + SHADER_PARAM( LOCALCONTRASTMIDTONEMASK, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast midtone mask" ) + SHADER_PARAM( LOCALCONTRASTVIGNETTESTART, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" ) + SHADER_PARAM( LOCALCONTRASTVIGNETTEEND, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast scale" ) + SHADER_PARAM( LOCALCONTRASTEDGESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast midtone mask" ) + + SHADER_PARAM( BLURREDVIGNETTEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable blurred vignette" ) + SHADER_PARAM( BLURREDVIGNETTESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "blurred vignette strength" ) + SHADER_PARAM( FADETOBLACKSCALE, SHADER_PARAM_TYPE_FLOAT, "0", "fade strength" ) + + SHADER_PARAM( DEPTHBLURFOCALDISTANCE, SHADER_PARAM_TYPE_FLOAT, "0", "Distance in dest-alpha space [0,1] of focal plane." ) + SHADER_PARAM( DEPTHBLURSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0", "Strength of depth-blur effect" ) + SHADER_PARAM( SCREENBLURSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0", "Full-screen blur factor" ) + + SHADER_PARAM( VOMITCOLOR1, SHADER_PARAM_TYPE_VEC3, "[0 0 0 0]", "1st vomit blend color" ) + SHADER_PARAM( VOMITCOLOR2, SHADER_PARAM_TYPE_VEC3, "[0 0 0 0]", "2st vomit blend color" ) + SHADER_PARAM( VOMITREFRACTSCALE, SHADER_PARAM_TYPE_FLOAT, "0.15", "vomit refract strength" ) + SHADER_PARAM( VOMITENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable vomit refract" ) + + SHADER_PARAM( FADECOLOR, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "viewfade color" ) + SHADER_PARAM( FADE, SHADER_PARAM_TYPE_INTEGER, "0", "fade type. 0 = off, 1 = lerp, 2 = modulate" ) + + SHADER_PARAM( TV_GAMMA, SHADER_PARAM_TYPE_INTEGER, "0", "0 default, 1 used for laying off 360 movies" ) + SHADER_PARAM( DESATURATEENABLE, SHADER_PARAM_TYPE_INTEGER, "0", "Desaturate with math, turns off color correction" ) + SHADER_PARAM( DESATURATION, SHADER_PARAM_TYPE_FLOAT, "0", "Desaturation Amount" ) + + // Tool color correction setup + SHADER_PARAM( TOOLMODE, SHADER_PARAM_TYPE_BOOL, "1", "tool mode" ) + SHADER_PARAM( TOOLCOLORCORRECTION, SHADER_PARAM_TYPE_FLOAT, "1", "tool color correction override" ) + SHADER_PARAM( WEIGHT_DEFAULT, SHADER_PARAM_TYPE_FLOAT, "1", "weight default" ) + SHADER_PARAM( WEIGHT0, SHADER_PARAM_TYPE_FLOAT, "1", "weight0" ) + SHADER_PARAM( WEIGHT1, SHADER_PARAM_TYPE_FLOAT, "1", "weight1" ) + SHADER_PARAM( WEIGHT2, SHADER_PARAM_TYPE_FLOAT, "1", "weight2" ) + SHADER_PARAM( WEIGHT3, SHADER_PARAM_TYPE_FLOAT, "1", "weight3" ) + SHADER_PARAM( NUM_LOOKUPS, SHADER_PARAM_TYPE_FLOAT, "0", "num_lookups" ) + SHADER_PARAM( TOOLTIME, SHADER_PARAM_TYPE_FLOAT, "0", "tooltime" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( !params[ INTERNAL_VIGNETTETEXTURE ]->IsDefined() ) + { + params[ INTERNAL_VIGNETTETEXTURE ]->SetStringValue( "dev/vignette" ); + } + if ( !params[ AAENABLE ]->IsDefined() ) + { + params[ AAENABLE ]->SetIntValue( 0 ); + } + if ( !params[ AAINTERNAL1 ]->IsDefined() ) + { + params[ AAINTERNAL1 ]->SetVecValue( 0, 0, 0, 0 ); + } + if ( !params[ AAINTERNAL2 ]->IsDefined() ) + { + params[ AAINTERNAL2 ]->SetVecValue( 0, 0, 0, 0 ); + } + if ( !params[ AAINTERNAL3 ]->IsDefined() ) + { + params[ AAINTERNAL3 ]->SetVecValue( 0, 0, 0, 0 ); + } + if ( !params[ BLOOMENABLE ]->IsDefined() ) + { + params[ BLOOMENABLE ]->SetIntValue( 1 ); + } + if ( !params[ BLOOMAMOUNT ]->IsDefined() ) + { + params[ BLOOMAMOUNT ]->SetFloatValue( 1.0f ); + } + if ( !params[ DEPTHBLURENABLE ]->IsDefined() ) + { + params[ DEPTHBLURENABLE ]->SetIntValue( 0 ); + } + if ( !params[ ALLOWNOISE ]->IsDefined() ) + { + params[ ALLOWNOISE ]->SetIntValue( 1 ); + } + if ( !params[ NOISESCALE ]->IsDefined() ) + { + params[ NOISESCALE ]->SetFloatValue( 1.0f ); + } + if ( !params[ NOISEENABLE ]->IsDefined() ) + { + params[ NOISEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ ALLOWVIGNETTE ]->IsDefined() ) + { + params[ ALLOWVIGNETTE ]->SetIntValue( 1 ); + } + if ( !params[ VIGNETTEENABLE ]->IsDefined() ) + { + params[ VIGNETTEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ ALLOWLOCALCONTRAST ]->IsDefined() ) + { + params[ ALLOWLOCALCONTRAST ]->SetIntValue( 1 ); + } + if ( !params[ LOCALCONTRASTSCALE ]->IsDefined() ) + { + params[ LOCALCONTRASTSCALE ]->SetFloatValue( 1.0f ); + } + if ( !params[ LOCALCONTRASTMIDTONEMASK ]->IsDefined() ) + { + params[ LOCALCONTRASTMIDTONEMASK ]->SetFloatValue( 1000.0f ); + } + if ( !params[ LOCALCONTRASTENABLE ]->IsDefined() ) + { + params[ LOCALCONTRASTENABLE ]->SetIntValue( 0 ); + } + if ( !params[ LOCALCONTRASTVIGNETTESTART ]->IsDefined() ) + { + params[ LOCALCONTRASTVIGNETTESTART ]->SetFloatValue( 0.7f ); + } + if ( !params[ LOCALCONTRASTVIGNETTEEND ]->IsDefined() ) + { + params[ LOCALCONTRASTVIGNETTEEND ]->SetFloatValue( 1.0f ); + } + if ( !params[ LOCALCONTRASTEDGESCALE ]->IsDefined() ) + { + params[ LOCALCONTRASTEDGESCALE ]->SetFloatValue( 0.0f ); + } + if ( !params[ BLURREDVIGNETTEENABLE ]->IsDefined() ) + { + params[ BLURREDVIGNETTEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ BLURREDVIGNETTESCALE ]->IsDefined() ) + { + params[ BLURREDVIGNETTESCALE ]->SetFloatValue( 0.0f ); + } + if ( !params[ FADETOBLACKSCALE ]->IsDefined() ) + { + params[ FADETOBLACKSCALE ]->SetFloatValue( 0.0f ); + } + if ( !params[ DEPTHBLURFOCALDISTANCE ]->IsDefined() ) + { + params[ DEPTHBLURFOCALDISTANCE ]->SetFloatValue( 0.0f ); + } + if ( !params[ DEPTHBLURSTRENGTH ]->IsDefined() ) + { + params[ DEPTHBLURSTRENGTH ]->SetFloatValue( 0.0f ); + } + if ( !params[ SCREENBLURSTRENGTH ]->IsDefined() ) + { + params[ SCREENBLURSTRENGTH ]->SetFloatValue( 0.0f ); + } + if ( !params[ TOOLMODE ]->IsDefined() ) + { + params[ TOOLMODE ]->SetIntValue( 0 ); + } + if ( !params[ TOOLCOLORCORRECTION ]->IsDefined() ) + { + params[ TOOLCOLORCORRECTION ]->SetFloatValue( 0.0f ); + } + if ( !params[ VOMITENABLE ]->IsDefined() ) + { + params[ VOMITENABLE ]->SetIntValue( 0 ); + } + if ( !params[ VOMITREFRACTSCALE ]->IsDefined() ) + { + params[ VOMITREFRACTSCALE ]->SetFloatValue( 0.15f ); + } + if ( !params[ VOMITCOLOR1 ]->IsDefined() ) + { + params[ VOMITCOLOR1 ]->SetVecValue( 1.0, 1.0, 0.0 ); + } + if ( !params[ VOMITCOLOR2 ]->IsDefined() ) + { + params[ VOMITCOLOR2 ]->SetVecValue( 0.0, 1.0, 0.0 ); + } + if ( !params[ FADE ]->IsDefined() ) + { + params[ FADE ]->SetIntValue( 0 ); + } + if ( !params[ FADECOLOR ]->IsDefined() ) + { + params[ FADECOLOR ]->SetVecValue( 0.0f, 0.0f, 0.0f, 0.0f ); + } + if ( !params[ TV_GAMMA ]->IsDefined() ) + { + params[ TV_GAMMA ]->SetIntValue( 0 ); + } + if ( !params[ DESATURATEENABLE ]->IsDefined() ) + { + params[ DESATURATEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ DESATURATION ]->IsDefined() ) + { + params[ DESATURATION ]->SetFloatValue( 0.0f ); + } + + SET_FLAGS2( MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE ); + } + + SHADER_FALLBACK + { + // This shader should not be *used* unless we're >= DX9 (bloomadd.vmt/screenspace_general_dx8 should be used for DX8) + return 0; + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + + if ( params[FBTEXTURE]->IsDefined() ) + { + LoadTexture( FBTEXTURE ); + } + + if ( params[SCREENEFFECTTEXTURE]->IsDefined() ) + { + LoadTexture( SCREENEFFECTTEXTURE ); + } + + if ( params[NOISETEXTURE]->IsDefined() ) + { + LoadTexture( NOISETEXTURE ); + } + + if ( params[INTERNAL_VIGNETTETEXTURE]->IsDefined() ) + { + LoadTexture( INTERNAL_VIGNETTETEXTURE ); + } + } + + SHADER_DRAW + { + bool bToolMode = params[TOOLMODE]->GetIntValue() != 0; + bool bDepthBlurEnable = params[ DEPTHBLURENABLE ]->GetIntValue() != 0; + + SHADOW_STATE + { + // This shader uses opaque blending, but needs to match the behaviour of bloom_add/screen_spacegeneral, + // which uses additive blending (and is used when bloom is enabled but col-correction and AA are not). + // BUT! + // Hardware sRGB blending is incorrect (on pre-DX10 cards, sRGB values are added directly). + // SO... + // When doing the bloom addition in the pixel shader, we need to emulate that incorrect + // behaviour - by turning sRGB read OFF for the FB texture and by turning sRGB write OFF + // (which is fine, since the AA process works better on an sRGB framebuffer than a linear + // one; gamma colours more closely match luminance perception. The color-correction process + // has always taken gamma-space values as input anyway). + + pShaderShadow->EnableBlending( false ); + + // The (sRGB) bloom texture is bound to sampler 0 + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + pShaderShadow->EnableSRGBWrite( false ); + + // The (sRGB) full framebuffer texture is bound to sampler 1: + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + + // Up to 4 (sRGB) color-correction lookup textures are bound to samplers 2-5: + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, false ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, false ); + + // Noise + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false ); + + // Vignette + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, false ); + + // Screen effect texture + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, false ); + + pShaderShadow->EnableSRGBWrite( false ); + + int format = VERTEX_POSITION; + int numTexCoords = 1; + int * pTexCoordDimensions = NULL; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( format, numTexCoords, pTexCoordDimensions, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_engine_post_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( TOOL_MODE, bToolMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTH_BLUR_ENABLE, bDepthBlurEnable ); + SET_STATIC_PIXEL_SHADER( sdk_engine_post_ps20b ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + // FIXME: need to set FBTEXTURE to be point-sampled (will speed up this shader significantly on 360) + // and assert that it's set to SHADER_TEXWRAPMODE_CLAMP (since the shader will sample offscreen) + BindTexture( SHADER_SAMPLER1, FBTEXTURE, -1 ); + + ShaderColorCorrectionInfo_t ccInfo = { false, 0, 1.0f, { 1.0f, 1.0f, 1.0f, 1.0f } }; + + float flTime; + if ( bToolMode ) + { + flTime = params[TOOLTIME]->GetFloatValue(); + } + else + { + flTime = pShaderAPI->CurrentTime(); + } + + // PC, ps20b has a desaturation control that overrides color correction + bool bDesaturateEnable = bToolMode && ( params[DESATURATEENABLE]->GetIntValue() != 0 ) && g_pHardwareConfig->SupportsPixelShaders_2_b(); + + float vPsConst16[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst16[0] = params[ DESATURATION ]->GetFloatValue(); + vPsConst16[1] = ( params[FADE]->GetIntValue() == 2 ) ? 1.0f : 0.0f; // Enable lerping to ( color * fadecolor ) for FADE_COLOR=2 + pShaderAPI->SetPixelShaderConstant( 16, vPsConst16, 1 ); + + if ( params[FADE]->GetIntValue() == 0 ) + { + // Not fading, so set the constant to cause nothing to change about the pixel color + float vConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 15, vConst ); + } + else + { + pShaderAPI->SetPixelShaderConstant( 15, params[ FADECOLOR ]->GetVecValue(), 1 ); + } + + if ( !bDesaturateEnable ) // set up color correction + { + bool bToolColorCorrection = params[TOOLCOLORCORRECTION]->GetIntValue() != 0; + if ( bToolColorCorrection ) + { + ccInfo.m_bIsEnabled = true; + + ccInfo.m_nLookupCount = (int) params[NUM_LOOKUPS]->GetFloatValue(); + ccInfo.m_flDefaultWeight = params[WEIGHT_DEFAULT]->GetFloatValue(); + ccInfo.m_pLookupWeights[0] = params[WEIGHT0]->GetFloatValue(); + ccInfo.m_pLookupWeights[1] = params[WEIGHT1]->GetFloatValue(); + ccInfo.m_pLookupWeights[2] = params[WEIGHT2]->GetFloatValue(); + ccInfo.m_pLookupWeights[3] = params[WEIGHT3]->GetFloatValue(); + } + else + { + pShaderAPI->GetCurrentColorCorrection( &ccInfo ); + } + } + + int colCorrectNumLookups = MIN( ccInfo.m_nLookupCount, 3 ); + for ( int i = 0; i < colCorrectNumLookups; i++ ) + { + pShaderAPI->BindStandardTexture( (Sampler_t)(SHADER_SAMPLER2 + i), (StandardTextureId_t)(TEXTURE_COLOR_CORRECTION_VOLUME_0 + i) ); + } + + // Upload 1-pixel X&Y offsets [ (+dX,0,+dY,-dX) is chosen to work with the allowed ps20 swizzles ] + // The shader will sample in a cross (up/down/left/right from the current sample), for 5-tap + // (quality 0) mode and add another 4 samples in a diagonal cross, for 9-tap (quality 1) mode + ITexture * pTarget = params[FBTEXTURE]->GetTextureValue(); + int width = pTarget->GetActualWidth(); + int height = pTarget->GetActualHeight(); + float dX = 1.0f / width; + float dY = 1.0f / height; + float offsets[4] = { +dX, 0, +dY, -dX }; + pShaderAPI->SetPixelShaderConstant( 0, &offsets[0], 1 ); + + // Upload AA tweakables: + // x - strength (this can be used to toggle the AA off, or to weaken it where pathological cases are showing) + // y - reduction of 1-pixel-line blurring (blurring of 1-pixel lines causes issues, so it's tunable) + // z - edge threshold multiplier (default 1.0, < 1.0 => more edges softened, > 1.0 => fewer edges softened) + // w - tap offset multiplier (default 1.0, < 1.0 => sharper image, > 1.0 => blurrier image) + float tweakables[4] = { params[ AAINTERNAL1 ]->GetVecValue()[0], + params[ AAINTERNAL1 ]->GetVecValue()[1], + params[ AAINTERNAL3 ]->GetVecValue()[0], + params[ AAINTERNAL3 ]->GetVecValue()[1] }; + pShaderAPI->SetPixelShaderConstant( 1, &tweakables[0], 1 ); + + // Upload AA UV transform (converts bloom texture UVs to framebuffer texture UVs) + // NOTE: we swap the order of the z and w components since 'wz' is an allowed ps20 swizzle, but 'zw' is not: + float uvTrans[4] = { params[ AAINTERNAL2 ]->GetVecValue()[0], + params[ AAINTERNAL2 ]->GetVecValue()[1], + params[ AAINTERNAL2 ]->GetVecValue()[3], + params[ AAINTERNAL2 ]->GetVecValue()[2] }; + pShaderAPI->SetPixelShaderConstant( 2, &uvTrans[0], 1 ); + + // Upload color-correction weights: + pShaderAPI->SetPixelShaderConstant( 3, &ccInfo.m_flDefaultWeight ); + pShaderAPI->SetPixelShaderConstant( 4, ccInfo.m_pLookupWeights ); + + int aaEnabled = 0; + int bloomEnabled = ( params[ BLOOMENABLE ]->GetIntValue() == 0 ) ? 0 : 1; + int colCorrectEnabled = ccInfo.m_bIsEnabled; + + float flBloomFactor = bloomEnabled ? 1.0f : 0.0f; + flBloomFactor *= params[BLOOMAMOUNT]->GetFloatValue(); + float bloomConstant[4] = + { + flBloomFactor, + params[ SCREENBLURSTRENGTH ]->GetFloatValue(), + params[ DEPTHBLURFOCALDISTANCE ]->GetFloatValue(), + params[ DEPTHBLURSTRENGTH ]->GetFloatValue() + }; + + if ( mat_screen_blur_override.GetFloat() >= 0.0f ) + { + bloomConstant[1] = mat_screen_blur_override.GetFloat(); + } + if ( mat_depth_blur_focal_distance_override.GetFloat() >= 0.0f ) + { + bloomConstant[2] = mat_depth_blur_focal_distance_override.GetFloat(); + } + if ( mat_depth_blur_strength_override.GetFloat() >= 0.0f ) + { + bloomConstant[3] = mat_depth_blur_strength_override.GetFloat(); + } + + pShaderAPI->SetPixelShaderConstant( 5, bloomConstant ); + + // Vignette + bool bVignetteEnable = ( params[ VIGNETTEENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWVIGNETTE ]->GetIntValue() != 0 ); + if ( bVignetteEnable ) + { + BindTexture( SHADER_SAMPLER7, INTERNAL_VIGNETTETEXTURE ); + } + + // Noise + bool bNoiseEnable = ( params[ NOISEENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWNOISE ]->GetIntValue() != 0 ); + + int nFbTextureHeight = params[FBTEXTURE]->GetTextureValue()->GetActualHeight(); + if ( nFbTextureHeight < 720 ) + { + // Disable noise at low resolutions + bNoiseEnable = false; + } + + if ( bNoiseEnable ) + { + BindTexture( SHADER_SAMPLER6, NOISETEXTURE ); + + // Noise scale + float vPsConst6[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst6[0] = params[ NOISESCALE ]->GetFloatValue(); + if ( mat_grain_scale_override.GetFloat() != -1.0f ) + { + vPsConst6[0] = mat_grain_scale_override.GetFloat(); + } + + if ( vPsConst6[0] <= 0.0f ) + { + bNoiseEnable = false; + } + + pShaderAPI->SetPixelShaderConstant( 6, vPsConst6 ); + + // Time % 1000 for scrolling + float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst[0] = flTime; + vPsConst[0] -= (float)( (int)( vPsConst[0] / 1000.0f ) ) * 1000.0f; + pShaderAPI->SetPixelShaderConstant( 7, vPsConst, 1 ); + } + + // Local Contrast + bool bLocalContrastEnable = ( params[ LOCALCONTRASTENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWLOCALCONTRAST ]->GetIntValue() != 0 ); + bool bBlurredVignetteEnable = ( bLocalContrastEnable ) && ( params[ BLURREDVIGNETTEENABLE ]->GetIntValue() != 0 ); + + if ( bLocalContrastEnable ) + { + // Contrast scale + float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst[0] = params[ LOCALCONTRASTSCALE ]->GetFloatValue(); + if ( mat_local_contrast_scale_override.GetFloat() != 0.0f ) + { + vPsConst[0] = mat_local_contrast_scale_override.GetFloat(); + } + vPsConst[1] = params[ LOCALCONTRASTMIDTONEMASK ]->GetFloatValue(); + if ( mat_local_contrast_midtone_mask_override.GetFloat() >= 0.0f ) + { + vPsConst[1] = mat_local_contrast_midtone_mask_override.GetFloat(); + } + vPsConst[2] = params[ BLURREDVIGNETTESCALE ]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 8, vPsConst, 1 ); + + vPsConst[0] = params[ LOCALCONTRASTVIGNETTESTART ]->GetFloatValue(); + if ( mat_local_contrast_vignette_start_override.GetFloat() >= 0.0f ) + { + vPsConst[0] = mat_local_contrast_vignette_start_override.GetFloat(); + } + vPsConst[1] = params[ LOCALCONTRASTVIGNETTEEND ]->GetFloatValue(); + if ( mat_local_contrast_vignette_end_override.GetFloat() >= 0.0f ) + { + vPsConst[1] = mat_local_contrast_vignette_end_override.GetFloat(); + } + vPsConst[2] = params[ LOCALCONTRASTEDGESCALE ]->GetFloatValue(); + if ( mat_local_contrast_edge_scale_override.GetFloat() >= -1.0f ) + { + vPsConst[2] = mat_local_contrast_edge_scale_override.GetFloat(); + } + pShaderAPI->SetPixelShaderConstant( 9, vPsConst, 1 ); + } + + // fade to black + float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst[0] = params[ FADETOBLACKSCALE ]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 10, vPsConst, 1 ); + + bool bVomitEnable = ( params[ VOMITENABLE ]->GetIntValue() != 0 ); + if ( bVomitEnable ) + { + BindTexture( SHADER_SAMPLER8, SCREENEFFECTTEXTURE ); + + params[ VOMITCOLOR1 ]->GetVecValue( vPsConst, 3 ); + vPsConst[3] = params[ VOMITREFRACTSCALE ]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 11, vPsConst, 1 ); + params[ VOMITCOLOR2 ]->GetVecValue( vPsConst, 3 ); + vPsConst[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 12, vPsConst, 1 ); + + // Get viewport and render target dimensions and set shader constant to do a 2D mad + ShaderViewport_t vp; + pShaderAPI->GetViewports( &vp, 1 ); + int nViewportX = vp.m_nTopLeftX; + int nViewportY = vp.m_nTopLeftY; + int nViewportWidth = vp.m_nWidth; + int nViewportHeight = vp.m_nHeight; + + int nRtWidth, nRtHeight; + ITexture *pRenderTarget = pShaderAPI->GetRenderTargetEx( 0 ); + if( pRenderTarget != nullptr ) + { + nRtWidth = pRenderTarget->GetActualWidth(); + nRtHeight = pRenderTarget->GetActualHeight(); + } + else + { + pShaderAPI->GetBackBufferDimensions( nRtWidth, nRtHeight ); + } + + float vViewportMad[4]; + + // screen->viewport transform + vViewportMad[0] = ( float )nRtWidth / ( float )nViewportWidth; + vViewportMad[1] = ( float )nRtHeight / ( float )nViewportHeight; + vViewportMad[2] = -( float )nViewportX / ( float )nViewportWidth; + vViewportMad[3] = -( float )nViewportY / ( float )nViewportHeight; + pShaderAPI->SetPixelShaderConstant( 13, vViewportMad, 1 ); + + // viewport->screen transform + vViewportMad[0] = ( float )nViewportWidth / ( float )nRtWidth; + vViewportMad[1] = ( float )nViewportHeight / ( float )nRtHeight; + vViewportMad[2] = ( float )nViewportX / ( float )nRtWidth; + vViewportMad[3] = ( float )nViewportY / ( float )nRtHeight; + pShaderAPI->SetPixelShaderConstant( 14, vViewportMad, 1 ); + } + + if ( !colCorrectEnabled ) + { + colCorrectNumLookups = 0; + } + + bool bConvertFromLinear = ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT ); + + // JasonM - double check this if the SFM needs to use the engine post FX clip in main + bool bConvertToLinear = bToolMode && bConvertFromLinear && ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_engine_post_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_ENABLE, aaEnabled ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( COL_CORRECT_NUM_LOOKUPS, colCorrectNumLookups ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CONVERT_FROM_LINEAR, bConvertFromLinear ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CONVERT_TO_LINEAR, bConvertToLinear ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NOISE_ENABLE, bNoiseEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( VIGNETTE_ENABLE, bVignetteEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LOCAL_CONTRAST_ENABLE, bLocalContrastEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( BLURRED_VIGNETTE_ENABLE, bBlurredVignetteEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( VOMIT_ENABLE, bVomitEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( TV_GAMMA, params[TV_GAMMA]->GetIntValue() && bToolMode ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( DESATURATEENABLE, bDesaturateEnable ); + SET_DYNAMIC_PIXEL_SHADER( sdk_engine_post_ps20b ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20.inc new file mode 100644 index 00000000..01b921ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class blurgaussian_3x3_ps20_Static_Index +{ +public: + blurgaussian_3x3_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_blurgaussian_3x3_ps20 0 +class blurgaussian_3x3_ps20_Dynamic_Index +{ +public: + blurgaussian_3x3_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_blurgaussian_3x3_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20b.inc new file mode 100644 index 00000000..d5298ae8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/blurgaussian_3x3_ps20b.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class blurgaussian_3x3_ps20b_Static_Index +{ +public: + blurgaussian_3x3_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_blurgaussian_3x3_ps20b 0 +class blurgaussian_3x3_ps20b_Dynamic_Index +{ +public: + blurgaussian_3x3_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_blurgaussian_3x3_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_ps20b.inc new file mode 100644 index 00000000..99961231 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class depth_of_field_ps20b_Static_Index +{ +public: + depth_of_field_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depth_of_field_ps20b 0 +class depth_of_field_ps20b_Dynamic_Index +{ +private: + int m_nQUALITY; +#ifdef _DEBUG + bool m_bQUALITY; +#endif +public: + void SetQUALITY( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nQUALITY = i; +#ifdef _DEBUG + m_bQUALITY = true; +#endif + } + void SetQUALITY( bool i ) + { + m_nQUALITY = i ? 1 : 0; +#ifdef _DEBUG + m_bQUALITY = true; +#endif + } +public: + depth_of_field_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bQUALITY = false; +#endif // _DEBUG + m_nQUALITY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bQUALITY; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nQUALITY ) + 0; + } +}; +#define shaderDynamicTest_depth_of_field_ps20b psh_forgot_to_set_dynamic_QUALITY + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_vs20.inc new file mode 100644 index 00000000..a014d1b9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/depth_of_field_vs20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class depth_of_field_vs20_Static_Index +{ +public: + depth_of_field_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depth_of_field_vs20 0 +class depth_of_field_vs20_Dynamic_Index +{ +public: + depth_of_field_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_depth_of_field_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/engine_post_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/engine_post_ps20b.inc new file mode 100644 index 00000000..ec25f0d9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/engine_post_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class engine_post_ps20b_Static_Index +{ +private: + int m_nTOOL_MODE; +#ifdef _DEBUG + bool m_bTOOL_MODE; +#endif +public: + void SetTOOL_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTOOL_MODE = i; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } + void SetTOOL_MODE( bool i ) + { + m_nTOOL_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } +private: + int m_nDEPTH_BLUR_ENABLE; +#ifdef _DEBUG + bool m_bDEPTH_BLUR_ENABLE; +#endif +public: + void SetDEPTH_BLUR_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTH_BLUR_ENABLE = i; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } + void SetDEPTH_BLUR_ENABLE( bool i ) + { + m_nDEPTH_BLUR_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } +public: + engine_post_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTOOL_MODE = false; +#endif // _DEBUG + m_nTOOL_MODE = 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = false; +#endif // _DEBUG + m_nDEPTH_BLUR_ENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTOOL_MODE && m_bDEPTH_BLUR_ENABLE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2048 * m_nTOOL_MODE ) + ( 4096 * m_nDEPTH_BLUR_ENABLE ) + 0; + } +}; +#define shaderStaticTest_engine_post_ps20b psh_forgot_to_set_static_TOOL_MODE + psh_forgot_to_set_static_DEPTH_BLUR_ENABLE + 0 +class engine_post_ps20b_Dynamic_Index +{ +private: + int m_nAA_ENABLE; +#ifdef _DEBUG + bool m_bAA_ENABLE; +#endif +public: + void SetAA_ENABLE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nAA_ENABLE = i; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } + void SetAA_ENABLE( bool i ) + { + m_nAA_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } +private: + int m_nCOL_CORRECT_NUM_LOOKUPS; +#ifdef _DEBUG + bool m_bCOL_CORRECT_NUM_LOOKUPS; +#endif +public: + void SetCOL_CORRECT_NUM_LOOKUPS( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nCOL_CORRECT_NUM_LOOKUPS = i; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } + void SetCOL_CORRECT_NUM_LOOKUPS( bool i ) + { + m_nCOL_CORRECT_NUM_LOOKUPS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } +private: + int m_nCONVERT_FROM_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_FROM_LINEAR; +#endif +public: + void SetCONVERT_FROM_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_FROM_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } + void SetCONVERT_FROM_LINEAR( bool i ) + { + m_nCONVERT_FROM_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } +private: + int m_nCONVERT_TO_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_TO_LINEAR; +#endif +public: + void SetCONVERT_TO_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } + void SetCONVERT_TO_LINEAR( bool i ) + { + m_nCONVERT_TO_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } +private: + int m_nNOISE_ENABLE; +#ifdef _DEBUG + bool m_bNOISE_ENABLE; +#endif +public: + void SetNOISE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOISE_ENABLE = i; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } + void SetNOISE_ENABLE( bool i ) + { + m_nNOISE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } +private: + int m_nVIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bVIGNETTE_ENABLE; +#endif +public: + void SetVIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } + void SetVIGNETTE_ENABLE( bool i ) + { + m_nVIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } +private: + int m_nLOCAL_CONTRAST_ENABLE; +#ifdef _DEBUG + bool m_bLOCAL_CONTRAST_ENABLE; +#endif +public: + void SetLOCAL_CONTRAST_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLOCAL_CONTRAST_ENABLE = i; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } + void SetLOCAL_CONTRAST_ENABLE( bool i ) + { + m_nLOCAL_CONTRAST_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } +private: + int m_nBLURRED_VIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bBLURRED_VIGNETTE_ENABLE; +#endif +public: + void SetBLURRED_VIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRED_VIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } + void SetBLURRED_VIGNETTE_ENABLE( bool i ) + { + m_nBLURRED_VIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } +private: + int m_nVOMIT_ENABLE; +#ifdef _DEBUG + bool m_bVOMIT_ENABLE; +#endif +public: + void SetVOMIT_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVOMIT_ENABLE = i; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } + void SetVOMIT_ENABLE( bool i ) + { + m_nVOMIT_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } +private: + int m_nTV_GAMMA; +#ifdef _DEBUG + bool m_bTV_GAMMA; +#endif +public: + void SetTV_GAMMA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTV_GAMMA = i; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } + void SetTV_GAMMA( bool i ) + { + m_nTV_GAMMA = i ? 1 : 0; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } +private: + int m_nDESATURATEENABLE; +#ifdef _DEBUG + bool m_bDESATURATEENABLE; +#endif +public: + void SetDESATURATEENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDESATURATEENABLE = i; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } + void SetDESATURATEENABLE( bool i ) + { + m_nDESATURATEENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } +public: + engine_post_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bAA_ENABLE = false; +#endif // _DEBUG + m_nAA_ENABLE = 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = false; +#endif // _DEBUG + m_nCOL_CORRECT_NUM_LOOKUPS = 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_FROM_LINEAR = 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_TO_LINEAR = 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = false; +#endif // _DEBUG + m_nNOISE_ENABLE = 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nVIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = false; +#endif // _DEBUG + m_nLOCAL_CONTRAST_ENABLE = 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nBLURRED_VIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = false; +#endif // _DEBUG + m_nVOMIT_ENABLE = 0; +#ifdef _DEBUG + m_bTV_GAMMA = false; +#endif // _DEBUG + m_nTV_GAMMA = 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = false; +#endif // _DEBUG + m_nDESATURATEENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAA_ENABLE && m_bCOL_CORRECT_NUM_LOOKUPS && m_bCONVERT_FROM_LINEAR && m_bCONVERT_TO_LINEAR && m_bNOISE_ENABLE && m_bVIGNETTE_ENABLE && m_bLOCAL_CONTRAST_ENABLE && m_bBLURRED_VIGNETTE_ENABLE && m_bVOMIT_ENABLE && m_bTV_GAMMA && m_bDESATURATEENABLE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAA_ENABLE ) + ( 1 * m_nCOL_CORRECT_NUM_LOOKUPS ) + ( 4 * m_nCONVERT_FROM_LINEAR ) + ( 8 * m_nCONVERT_TO_LINEAR ) + ( 16 * m_nNOISE_ENABLE ) + ( 32 * m_nVIGNETTE_ENABLE ) + ( 64 * m_nLOCAL_CONTRAST_ENABLE ) + ( 128 * m_nBLURRED_VIGNETTE_ENABLE ) + ( 256 * m_nVOMIT_ENABLE ) + ( 512 * m_nTV_GAMMA ) + ( 1024 * m_nDESATURATEENABLE ) + 0; + } +}; +#define shaderDynamicTest_engine_post_ps20b psh_forgot_to_set_dynamic_AA_ENABLE + psh_forgot_to_set_dynamic_COL_CORRECT_NUM_LOOKUPS + psh_forgot_to_set_dynamic_CONVERT_FROM_LINEAR + psh_forgot_to_set_dynamic_CONVERT_TO_LINEAR + psh_forgot_to_set_dynamic_NOISE_ENABLE + psh_forgot_to_set_dynamic_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_LOCAL_CONTRAST_ENABLE + psh_forgot_to_set_dynamic_BLURRED_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_VOMIT_ENABLE + psh_forgot_to_set_dynamic_TV_GAMMA + psh_forgot_to_set_dynamic_DESATURATEENABLE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20.inc new file mode 100644 index 00000000..01b921ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class blurgaussian_3x3_ps20_Static_Index +{ +public: + blurgaussian_3x3_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_blurgaussian_3x3_ps20 0 +class blurgaussian_3x3_ps20_Dynamic_Index +{ +public: + blurgaussian_3x3_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_blurgaussian_3x3_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20b.inc new file mode 100644 index 00000000..d5298ae8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20b.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class blurgaussian_3x3_ps20b_Static_Index +{ +public: + blurgaussian_3x3_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_blurgaussian_3x3_ps20b 0 +class blurgaussian_3x3_ps20b_Dynamic_Index +{ +public: + blurgaussian_3x3_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_blurgaussian_3x3_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_ps20b.inc new file mode 100644 index 00000000..99961231 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class depth_of_field_ps20b_Static_Index +{ +public: + depth_of_field_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depth_of_field_ps20b 0 +class depth_of_field_ps20b_Dynamic_Index +{ +private: + int m_nQUALITY; +#ifdef _DEBUG + bool m_bQUALITY; +#endif +public: + void SetQUALITY( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nQUALITY = i; +#ifdef _DEBUG + m_bQUALITY = true; +#endif + } + void SetQUALITY( bool i ) + { + m_nQUALITY = i ? 1 : 0; +#ifdef _DEBUG + m_bQUALITY = true; +#endif + } +public: + depth_of_field_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bQUALITY = false; +#endif // _DEBUG + m_nQUALITY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bQUALITY; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nQUALITY ) + 0; + } +}; +#define shaderDynamicTest_depth_of_field_ps20b psh_forgot_to_set_dynamic_QUALITY + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_vs20.inc new file mode 100644 index 00000000..a014d1b9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_vs20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class depth_of_field_vs20_Static_Index +{ +public: + depth_of_field_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depth_of_field_vs20 0 +class depth_of_field_vs20_Dynamic_Index +{ +public: + depth_of_field_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_depth_of_field_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/engine_post_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/engine_post_ps20b.inc new file mode 100644 index 00000000..ec25f0d9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/engine_post_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class engine_post_ps20b_Static_Index +{ +private: + int m_nTOOL_MODE; +#ifdef _DEBUG + bool m_bTOOL_MODE; +#endif +public: + void SetTOOL_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTOOL_MODE = i; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } + void SetTOOL_MODE( bool i ) + { + m_nTOOL_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } +private: + int m_nDEPTH_BLUR_ENABLE; +#ifdef _DEBUG + bool m_bDEPTH_BLUR_ENABLE; +#endif +public: + void SetDEPTH_BLUR_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTH_BLUR_ENABLE = i; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } + void SetDEPTH_BLUR_ENABLE( bool i ) + { + m_nDEPTH_BLUR_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } +public: + engine_post_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTOOL_MODE = false; +#endif // _DEBUG + m_nTOOL_MODE = 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = false; +#endif // _DEBUG + m_nDEPTH_BLUR_ENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTOOL_MODE && m_bDEPTH_BLUR_ENABLE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2048 * m_nTOOL_MODE ) + ( 4096 * m_nDEPTH_BLUR_ENABLE ) + 0; + } +}; +#define shaderStaticTest_engine_post_ps20b psh_forgot_to_set_static_TOOL_MODE + psh_forgot_to_set_static_DEPTH_BLUR_ENABLE + 0 +class engine_post_ps20b_Dynamic_Index +{ +private: + int m_nAA_ENABLE; +#ifdef _DEBUG + bool m_bAA_ENABLE; +#endif +public: + void SetAA_ENABLE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nAA_ENABLE = i; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } + void SetAA_ENABLE( bool i ) + { + m_nAA_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } +private: + int m_nCOL_CORRECT_NUM_LOOKUPS; +#ifdef _DEBUG + bool m_bCOL_CORRECT_NUM_LOOKUPS; +#endif +public: + void SetCOL_CORRECT_NUM_LOOKUPS( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nCOL_CORRECT_NUM_LOOKUPS = i; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } + void SetCOL_CORRECT_NUM_LOOKUPS( bool i ) + { + m_nCOL_CORRECT_NUM_LOOKUPS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } +private: + int m_nCONVERT_FROM_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_FROM_LINEAR; +#endif +public: + void SetCONVERT_FROM_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_FROM_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } + void SetCONVERT_FROM_LINEAR( bool i ) + { + m_nCONVERT_FROM_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } +private: + int m_nCONVERT_TO_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_TO_LINEAR; +#endif +public: + void SetCONVERT_TO_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } + void SetCONVERT_TO_LINEAR( bool i ) + { + m_nCONVERT_TO_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } +private: + int m_nNOISE_ENABLE; +#ifdef _DEBUG + bool m_bNOISE_ENABLE; +#endif +public: + void SetNOISE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOISE_ENABLE = i; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } + void SetNOISE_ENABLE( bool i ) + { + m_nNOISE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } +private: + int m_nVIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bVIGNETTE_ENABLE; +#endif +public: + void SetVIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } + void SetVIGNETTE_ENABLE( bool i ) + { + m_nVIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } +private: + int m_nLOCAL_CONTRAST_ENABLE; +#ifdef _DEBUG + bool m_bLOCAL_CONTRAST_ENABLE; +#endif +public: + void SetLOCAL_CONTRAST_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLOCAL_CONTRAST_ENABLE = i; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } + void SetLOCAL_CONTRAST_ENABLE( bool i ) + { + m_nLOCAL_CONTRAST_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } +private: + int m_nBLURRED_VIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bBLURRED_VIGNETTE_ENABLE; +#endif +public: + void SetBLURRED_VIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRED_VIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } + void SetBLURRED_VIGNETTE_ENABLE( bool i ) + { + m_nBLURRED_VIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } +private: + int m_nVOMIT_ENABLE; +#ifdef _DEBUG + bool m_bVOMIT_ENABLE; +#endif +public: + void SetVOMIT_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVOMIT_ENABLE = i; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } + void SetVOMIT_ENABLE( bool i ) + { + m_nVOMIT_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } +private: + int m_nTV_GAMMA; +#ifdef _DEBUG + bool m_bTV_GAMMA; +#endif +public: + void SetTV_GAMMA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTV_GAMMA = i; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } + void SetTV_GAMMA( bool i ) + { + m_nTV_GAMMA = i ? 1 : 0; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } +private: + int m_nDESATURATEENABLE; +#ifdef _DEBUG + bool m_bDESATURATEENABLE; +#endif +public: + void SetDESATURATEENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDESATURATEENABLE = i; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } + void SetDESATURATEENABLE( bool i ) + { + m_nDESATURATEENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } +public: + engine_post_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bAA_ENABLE = false; +#endif // _DEBUG + m_nAA_ENABLE = 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = false; +#endif // _DEBUG + m_nCOL_CORRECT_NUM_LOOKUPS = 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_FROM_LINEAR = 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_TO_LINEAR = 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = false; +#endif // _DEBUG + m_nNOISE_ENABLE = 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nVIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = false; +#endif // _DEBUG + m_nLOCAL_CONTRAST_ENABLE = 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nBLURRED_VIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = false; +#endif // _DEBUG + m_nVOMIT_ENABLE = 0; +#ifdef _DEBUG + m_bTV_GAMMA = false; +#endif // _DEBUG + m_nTV_GAMMA = 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = false; +#endif // _DEBUG + m_nDESATURATEENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAA_ENABLE && m_bCOL_CORRECT_NUM_LOOKUPS && m_bCONVERT_FROM_LINEAR && m_bCONVERT_TO_LINEAR && m_bNOISE_ENABLE && m_bVIGNETTE_ENABLE && m_bLOCAL_CONTRAST_ENABLE && m_bBLURRED_VIGNETTE_ENABLE && m_bVOMIT_ENABLE && m_bTV_GAMMA && m_bDESATURATEENABLE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAA_ENABLE ) + ( 1 * m_nCOL_CORRECT_NUM_LOOKUPS ) + ( 4 * m_nCONVERT_FROM_LINEAR ) + ( 8 * m_nCONVERT_TO_LINEAR ) + ( 16 * m_nNOISE_ENABLE ) + ( 32 * m_nVIGNETTE_ENABLE ) + ( 64 * m_nLOCAL_CONTRAST_ENABLE ) + ( 128 * m_nBLURRED_VIGNETTE_ENABLE ) + ( 256 * m_nVOMIT_ENABLE ) + ( 512 * m_nTV_GAMMA ) + ( 1024 * m_nDESATURATEENABLE ) + 0; + } +}; +#define shaderDynamicTest_engine_post_ps20b psh_forgot_to_set_dynamic_AA_ENABLE + psh_forgot_to_set_dynamic_COL_CORRECT_NUM_LOOKUPS + psh_forgot_to_set_dynamic_CONVERT_FROM_LINEAR + psh_forgot_to_set_dynamic_CONVERT_TO_LINEAR + psh_forgot_to_set_dynamic_NOISE_ENABLE + psh_forgot_to_set_dynamic_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_LOCAL_CONTRAST_ENABLE + psh_forgot_to_set_dynamic_BLURRED_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_VOMIT_ENABLE + psh_forgot_to_set_dynamic_TV_GAMMA + psh_forgot_to_set_dynamic_DESATURATEENABLE + 0 diff --git a/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc b/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc index 46193fba..40d64143 100644 --- a/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc +++ b/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc @@ -61,6 +61,9 @@ $Project $File "MonitorScreen_dx9.cpp" $File "shatteredglass.cpp" $File "windowimposter_dx90.cpp" + + $File "engine_post_dx9.cpp" + $File "depthoffield_dx9.cpp" } //$Shaders "mapbase_dx9_20b.txt" diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp index 452a3433..b2a8ddcc 100644 --- a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp @@ -227,7 +227,7 @@ void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** pa } else if ( !params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ) { - Warning( "Warning! material %s: $envmapmasktransform and $phong are mutial exclusive. Disabling phong..\n", pMaterialName ); + Warning( "Warning! material %s: $envmapmasktransform and $phong are mutually exclusive. Disabling phong..\n", pMaterialName ); params[info.m_nPhong]->SetIntValue( 0 ); } } diff --git a/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt b/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt index 1a805f20..d191e9dc 100644 --- a/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt +++ b/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt @@ -95,3 +95,10 @@ SDK_ShatteredGlass_ps2x.fxc SDK_ShatteredGlass_vs20.fxc SDK_windowimposter_ps2x.fxc SDK_windowimposter_vs20.fxc + +SDK_engine_post_ps20b.fxc + +depth_of_field_ps20b.fxc +depth_of_field_vs20.fxc + +blurgaussian_3x3_ps2x.fxc diff --git a/sp/src/public/tier1/mapbase_con_groups.h b/sp/src/public/tier1/mapbase_con_groups.h index d21e0740..c0e35626 100644 --- a/sp/src/public/tier1/mapbase_con_groups.h +++ b/sp/src/public/tier1/mapbase_con_groups.h @@ -22,6 +22,7 @@ // Server #define CON_GROUP_IO_SYSTEM "I/O System" +#define CON_GROUP_NPC_AI "NPC AI" #define CON_GROUP_NPC_SCRIPTS "NPC Scripts" #define CON_GROUP_CHOREO "Choreo" diff --git a/sp/src/public/vphysics_interface.h b/sp/src/public/vphysics_interface.h index 4d5d48ae..d6e61935 100644 --- a/sp/src/public/vphysics_interface.h +++ b/sp/src/public/vphysics_interface.h @@ -970,6 +970,20 @@ struct surfacedata_t float GetJumpFactor() { return game.jumpFactor; } char GetMaterialChar() { return game.material; } + +#if defined(CLIENT_DLL) || defined(GAME_DLL) + const char* GetSoundStepLeft(); + const char* GetSoundStepRight(); + const char* GetSoundImpactSoft(); + const char* GetSoundImpactHard(); + const char* GetSoundScrapeSmooth(); + const char* GetSoundScrapeRough(); + const char* GetSoundBulletImpact(); + const char* GetSoundRolling(); + const char* GetSoundBreak(); + const char* GetSoundStrain(); +#endif + #endif }; diff --git a/sp/src/public/vscript/ivscript.h b/sp/src/public/vscript/ivscript.h index 97d47b52..fb3a1b79 100644 --- a/sp/src/public/vscript/ivscript.h +++ b/sp/src/public/vscript/ivscript.h @@ -267,6 +267,26 @@ struct ScriptFuncDescriptor_t CUtlVector m_Parameters; }; +#ifdef MAPBASE_VSCRIPT +//--------------------------------------------------------- +// VScript Member Variables +// +// An odd concept. Because IScriptInstanceHelper now supports +// get/set metamethods, classes are capable of pretending they +// have member variables which VScript can get and set. +// +// There's no default way of documenting these variables, so even though +// these are not actually binding anything, this is here to allow VScript +// to describe these fake member variables in its documentation. +//--------------------------------------------------------- +struct ScriptMemberDesc_t +{ + const char *m_pszScriptName; + const char *m_pszDescription; + ScriptDataType_t m_ReturnType; +}; +#endif + //--------------------------------------------------------- @@ -338,6 +358,7 @@ struct ScriptClassDesc_t #ifdef MAPBASE_VSCRIPT CUtlVector m_Hooks; + CUtlVector m_Members; #endif void *(*m_pfnConstruct)(); @@ -744,6 +765,9 @@ struct ScriptEnumDesc_t #define END_SCRIPTHOOK() \ pDesc->m_Hooks.AddToTail(pHook); \ } + +#define DEFINE_MEMBERVAR( varName, returnType, description ) \ + do { ScriptMemberDesc_t *pBinding = &((pDesc)->m_Members[(pDesc)->m_Members.AddToTail()]); pBinding->m_pszScriptName = varName; pBinding->m_pszDescription = description; pBinding->m_ReturnType = returnType; } while (0); #endif template ScriptClassDesc_t *GetScriptDesc(T *); diff --git a/sp/src/tier1/mapbase_con_groups.cpp b/sp/src/tier1/mapbase_con_groups.cpp index 028bb67e..533d5791 100644 --- a/sp/src/tier1/mapbase_con_groups.cpp +++ b/sp/src/tier1/mapbase_con_groups.cpp @@ -49,14 +49,15 @@ struct ConGroup_t // To define a console group, //----------------------------------------------------------------------------- -#define DEFINE_CON_GROUP_CVAR(name, def, desc) static ConVar con_group_##name##_color( "con_group_" #name "_color", def, FCVAR_ARCHIVE, desc, CV_ColorChanged ) +#define DEFINE_CON_GROUP_CVAR(name, def, desc) static ConVar con_group_##name##_color( "con_group_" #name "_color", def, FCVAR_ARCHIVE | FCVAR_REPLICATED, desc, CV_ColorChanged ) DEFINE_CON_GROUP_CVAR( mapbase_misc, "192 128 224", "Messages from misc. Mapbase functions, like map-specific files." ); DEFINE_CON_GROUP_CVAR( physics, "159 209 159", "Messages from physics-related events." ); DEFINE_CON_GROUP_CVAR( inputoutput, "220 170 220", "Messages from I/O events. (these display in developer 2)" ); +DEFINE_CON_GROUP_CVAR( npc_ai, "240 160 200", "Messages from NPC AI, etc. which display at various verbse levels." ); DEFINE_CON_GROUP_CVAR( npc_scripts, "255 115 215", "Messages from scripted_sequence, etc. (these display in developer 2)" ); -DEFINE_CON_GROUP_CVAR( choreo, "240 224 180", "Messages from choreographed scenes. (these display in developer 1, 2, etc.)" ); +DEFINE_CON_GROUP_CVAR( choreo, "240 224 180", "Messages from choreographed scenes and response expressers. (these display in developer 1, 2, etc.)" ); DEFINE_CON_GROUP_CVAR( vscript, "192 224 240", "Internal messages from VScript not produced by the user's scripts." ); DEFINE_CON_GROUP_CVAR( vscript_print, "80 186 255", "Messages from VScript's 'print' function." ); @@ -74,6 +75,7 @@ ConGroup_t g_ConGroups[] = { // Server DEFINE_CON_GROUP( CON_GROUP_IO_SYSTEM, inputoutput ), + DEFINE_CON_GROUP( CON_GROUP_NPC_AI, npc_ai ), DEFINE_CON_GROUP( CON_GROUP_NPC_SCRIPTS, npc_scripts ), DEFINE_CON_GROUP( CON_GROUP_CHOREO, choreo ), @@ -147,7 +149,7 @@ CON_COMMAND( con_group_toggle, "Toggles a console group." ) void CGMsg( int level, const char *pszGroup, const tchar* pMsg, ... ) { // Return early if we're not at this level - if (!IsSpewActive("console", level)) + if (!IsSpewActive("developer", level)) return; char string[ 2048 ]; diff --git a/sp/src/utils/vbsp/map.cpp b/sp/src/utils/vbsp/map.cpp index bd3604f3..f59305ba 100644 --- a/sp/src/utils/vbsp/map.cpp +++ b/sp/src/utils/vbsp/map.cpp @@ -2834,7 +2834,7 @@ bool LoadMapFile( const char *pszFileName ) { if (g_pParallaxObbStrs[i][0] != '\0' && g_pParallaxObbsDone[i] == false) { - Warning( "Testing OBB string %s\n", g_pParallaxObbStrs[i] ); + //Warning( "Testing OBB string %s\n", g_pParallaxObbStrs[i] ); entity_t* obbEnt = NULL; for (int i2 = 0; i2 < g_LoadingMap->num_entities; i2++) @@ -2844,7 +2844,7 @@ bool LoadMapFile( const char *pszFileName ) obbEnt = &g_LoadingMap->entities[i2]; g_pParallaxObbStrs[i] = ValueForKey(obbEnt, "transformationmatrix"); - Warning( "Using OBB transformation matrix \"%s\"\n", g_pParallaxObbStrs[i] ); + //Warning( "Using OBB transformation matrix \"%s\"\n", g_pParallaxObbStrs[i] ); g_pParallaxObbsDone[i] = true; break; diff --git a/sp/src/vscript/vscript_bindings_base.cpp b/sp/src/vscript/vscript_bindings_base.cpp index 16d37606..56da8435 100644 --- a/sp/src/vscript/vscript_bindings_base.cpp +++ b/sp/src/vscript/vscript_bindings_base.cpp @@ -26,6 +26,8 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +extern IScriptManager *scriptmanager; + //============================================================================= // // Prints @@ -202,6 +204,8 @@ BEGIN_SCRIPTDESC_ROOT( CScriptKeyValues, "Wrapper class over KeyValues instance" DEFINE_SCRIPTFUNC( TableToSubKeys, "Converts a script table to KeyValues." ); + DEFINE_SCRIPTFUNC_NAMED( ScriptFindOrCreateKey, "FindOrCreateKey", "Given a KeyValues object and a key name, find or create a KeyValues object associated with the key name" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetName, "GetName", "Given a KeyValues object, return its name" ); DEFINE_SCRIPTFUNC_NAMED( ScriptGetInt, "GetInt", "Given a KeyValues object, return its own associated integer value" ); DEFINE_SCRIPTFUNC_NAMED( ScriptGetFloat, "GetFloat", "Given a KeyValues object, return its own associated float value" ); @@ -315,6 +319,19 @@ void CScriptKeyValues::TableToSubKeys( HSCRIPT hTable ) } } +HSCRIPT CScriptKeyValues::ScriptFindOrCreateKey( const char *pszName ) +{ + KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName, true); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + const char *CScriptKeyValues::ScriptGetName() { const char *psz = m_pKeyValues->GetName(); @@ -397,7 +414,7 @@ CScriptKeyValues::CScriptKeyValues( KeyValues *pKeyValues = NULL ) { if (pKeyValues == NULL) { - m_pKeyValues = new KeyValues(""); + m_pKeyValues = new KeyValues("CScriptKeyValues"); } else { @@ -415,6 +432,90 @@ CScriptKeyValues::~CScriptKeyValues( ) m_pKeyValues = NULL; } +//============================================================================= +// +// matrix3x4_t +// +//============================================================================= +CScriptColorInstanceHelper g_ColorScriptInstanceHelper; + +BEGIN_SCRIPTDESC_ROOT( Color, "" ) + + DEFINE_SCRIPT_CONSTRUCTOR() + DEFINE_SCRIPT_INSTANCE_HELPER( &g_ColorScriptInstanceHelper ) + + DEFINE_SCRIPTFUNC( SetColor, "Sets the color." ) + + DEFINE_SCRIPTFUNC( SetRawColor, "Sets the raw color integer." ) + DEFINE_SCRIPTFUNC( GetRawColor, "Gets the raw color integer." ) + + DEFINE_MEMBERVAR( "r", FIELD_CHARACTER, "Member variable for red." ) + DEFINE_MEMBERVAR( "g", FIELD_CHARACTER, "Member variable for green." ) + DEFINE_MEMBERVAR( "b", FIELD_CHARACTER, "Member variable for blue." ) + DEFINE_MEMBERVAR( "a", FIELD_CHARACTER, "Member variable for alpha. (transparency)" ) + +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- + +bool CScriptColorInstanceHelper::ToString( void *p, char *pBuf, int bufSize ) +{ + Color *pClr = ((Color *)p); + V_snprintf( pBuf, bufSize, "(color: (%i, %i, %i, %i))", pClr->r(), pClr->g(), pClr->b(), pClr->a() ); + return true; +} + +bool CScriptColorInstanceHelper::Get( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + Color *pClr = ((Color *)p); + if ( strlen(pszKey) == 1 ) + { + switch (pszKey[0]) + { + case 'r': + variant = pClr->r(); + return true; + case 'g': + variant = pClr->g(); + return true; + case 'b': + variant = pClr->b(); + return true; + case 'a': + variant = pClr->a(); + return true; + } + } + return false; +} + +bool CScriptColorInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + Color *pClr = ((Color *)p); + if ( strlen(pszKey) == 1 ) + { + int iVal; + variant.AssignTo( &iVal ); + switch (pszKey[0]) + { + // variant.AssignTo( &(*pClr)[0] ); + case 'r': + (*pClr)[0] = iVal; + return true; + case 'g': + (*pClr)[1] = iVal; + return true; + case 'b': + (*pClr)[2] = iVal; + return true; + case 'a': + (*pClr)[3] = iVal; + return true; + } + } + return false; +} + //============================================================================= //============================================================================= @@ -435,6 +536,8 @@ void RegisterBaseBindings( IScriptVM *pVM ) pVM->RegisterClass( GetScriptDescForClass( CScriptKeyValues ) ); + pVM->RegisterClass( GetScriptDescForClass( Color ) ); + //----------------------------------------------------------------------------- // diff --git a/sp/src/vscript/vscript_bindings_base.h b/sp/src/vscript/vscript_bindings_base.h index 8496ac69..a2d9fb9a 100644 --- a/sp/src/vscript/vscript_bindings_base.h +++ b/sp/src/vscript/vscript_bindings_base.h @@ -36,6 +36,8 @@ public: // Functions below are new with Mapbase void TableToSubKeys( HSCRIPT hTable ); + HSCRIPT ScriptFindOrCreateKey( const char *pszName ); + const char *ScriptGetName(); int ScriptGetInt(); float ScriptGetFloat(); @@ -57,6 +59,17 @@ public: KeyValues *m_pKeyValues; // actual KeyValue entity }; +//----------------------------------------------------------------------------- +// Exposes Color to VScript +//----------------------------------------------------------------------------- +class CScriptColorInstanceHelper : public IScriptInstanceHelper +{ + bool ToString( void *p, char *pBuf, int bufSize ); + + bool Get( void *p, const char *pszKey, ScriptVariant_t &variant ); + bool Set( void *p, const char *pszKey, ScriptVariant_t &variant ); +}; + void RegisterBaseBindings( IScriptVM *pVM ); #endif diff --git a/sp/src/vscript/vscript_bindings_math.cpp b/sp/src/vscript/vscript_bindings_math.cpp index 312e053d..cb6c594d 100644 --- a/sp/src/vscript/vscript_bindings_math.cpp +++ b/sp/src/vscript/vscript_bindings_math.cpp @@ -169,6 +169,11 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( Quaternion, "Quaternion", "A quaternion." ) DEFINE_SCRIPT_INSTANCE_HELPER( &g_QuaternionScriptInstanceHelper ) DEFINE_SCRIPTFUNC_NAMED( ScriptInit, "Init", "Creates a quaternion with the given values." ) + DEFINE_MEMBERVAR( "x", FIELD_FLOAT, "The quaternion's i axis component." ) + DEFINE_MEMBERVAR( "y", FIELD_FLOAT, "The quaternion's j axis component." ) + DEFINE_MEMBERVAR( "z", FIELD_FLOAT, "The quaternion's k axis component." ) + DEFINE_MEMBERVAR( "w", FIELD_FLOAT, "The quaternion's scalar component." ) + END_SCRIPTDESC(); //----------------------------------------------------------------------------- diff --git a/sp/src/vscript/vscript_squirrel.cpp b/sp/src/vscript/vscript_squirrel.cpp index c716ee8a..be83623d 100644 --- a/sp/src/vscript/vscript_squirrel.cpp +++ b/sp/src/vscript/vscript_squirrel.cpp @@ -802,7 +802,10 @@ void PushVariant(HSQUIRRELVM vm, const ScriptVariant_t& value) sq_pushfloat(vm, value); break; case FIELD_CSTRING: - sq_pushstring(vm, value, -1); + if ( value.m_pszString ) + sq_pushstring(vm, value, -1); + else + sq_pushnull(vm); break; case FIELD_VECTOR: { @@ -1453,9 +1456,6 @@ void RegisterClassDocumentation(HSQUIRRELVM vm, const ScriptClassDesc_t* pClassD { SquirrelSafeCheck safeCheck(vm); - if (pClassDesc->m_pszDescription && pClassDesc->m_pszDescription[0] == SCRIPT_HIDE[0]) - return; - const char *name = pClassDesc->m_pszScriptName; const char *base = ""; if (pClassDesc->m_pBaseDesc) @@ -1463,6 +1463,19 @@ void RegisterClassDocumentation(HSQUIRRELVM vm, const ScriptClassDesc_t* pClassD base = pClassDesc->m_pBaseDesc->m_pszScriptName; } + const char *description = pClassDesc->m_pszDescription; + if (description) + { + if (description[0] == SCRIPT_HIDE[0]) + return; + if (description[0] == SCRIPT_SINGLETON[0]) + description++; + } + else + { + description = ""; + } + // RegisterClassHelp(name, base, description) sq_pushroottable(vm); sq_pushstring(vm, "RegisterClassHelp", -1); @@ -1471,7 +1484,7 @@ void RegisterClassDocumentation(HSQUIRRELVM vm, const ScriptClassDesc_t* pClassD sq_pushroottable(vm); sq_pushstring(vm, name, -1); sq_pushstring(vm, base, -1); - sq_pushstring(vm, pClassDesc->m_pszDescription ? pClassDesc->m_pszDescription : "", -1); + sq_pushstring(vm, description, -1); sq_call(vm, 4, SQFalse, SQFalse); sq_pop(vm, 1); } @@ -1492,8 +1505,9 @@ void RegisterEnumDocumentation(HSQUIRRELVM vm, const ScriptEnumDesc_t* pClassDes sq_remove(vm, -2); sq_pushroottable(vm); sq_pushstring(vm, name, -1); + sq_pushinteger(vm, pClassDesc->m_ConstantBindings.Count()); sq_pushstring(vm, pClassDesc->m_pszDescription ? pClassDesc->m_pszDescription : "", -1); - sq_call(vm, 3, SQFalse, SQFalse); + sq_call(vm, 4, SQFalse, SQFalse); sq_pop(vm, 1); } @@ -1577,6 +1591,41 @@ void RegisterHookDocumentation(HSQUIRRELVM vm, const ScriptHook_t* pHook, const sq_pop(vm, 1); } +void RegisterMemberDocumentation(HSQUIRRELVM vm, const ScriptMemberDesc_t& pDesc, ScriptClassDesc_t* pClassDesc = nullptr) +{ + SquirrelSafeCheck safeCheck(vm); + + if (pDesc.m_pszDescription && pDesc.m_pszDescription[0] == SCRIPT_HIDE[0]) + return; + + char name[256] = ""; + + if (pClassDesc) + { + V_strcat_safe(name, pClassDesc->m_pszScriptName); + V_strcat_safe(name, "."); + } + + if (pDesc.m_pszScriptName) + V_strcat_safe(name, pDesc.m_pszScriptName); + + + char signature[256] = ""; + V_snprintf(signature, sizeof(signature), "%s %s", ScriptDataTypeToName(pDesc.m_ReturnType), name); + + // RegisterHookHelp(name, signature, description) + sq_pushroottable(vm); + sq_pushstring(vm, "RegisterMemberHelp", -1); + sq_get(vm, -2); + sq_remove(vm, -2); + sq_pushroottable(vm); + sq_pushstring(vm, name, -1); + sq_pushstring(vm, signature, -1); + sq_pushstring(vm, pDesc.m_pszDescription ? pDesc.m_pszDescription : "", -1); + sq_call(vm, 4, SQFalse, SQFalse); + sq_pop(vm, 1); +} + bool SquirrelVM::Init() { @@ -2091,6 +2140,13 @@ bool SquirrelVM::RegisterClass(ScriptClassDesc_t* pClassDesc) RegisterHookDocumentation(vm_, scriptHook, scriptHook->m_desc, pClassDesc); } + for (int i = 0; i < pClassDesc->m_Members.Count(); ++i) + { + auto& member = pClassDesc->m_Members[i]; + + RegisterMemberDocumentation(vm_, member, pClassDesc); + } + sq_pushstring(vm_, pClassDesc->m_pszScriptName, -1); sq_push(vm_, -2); diff --git a/sp/src/vscript/vscript_squirrel.nut b/sp/src/vscript/vscript_squirrel.nut index e140f4d5..f4d28227 100644 --- a/sp/src/vscript/vscript_squirrel.nut +++ b/sp/src/vscript/vscript_squirrel.nut @@ -111,6 +111,7 @@ DocumentedClasses <- {} DocumentedEnums <- {} DocumentedConsts <- {} DocumentedHooks <- {} +DocumentedMembers <- {} function AddAliasedToTable(name, signature, description, table) { @@ -145,9 +146,9 @@ function RegisterClassHelp(name, baseclass, description) DocumentedClasses[name] <- [baseclass, description]; } -function RegisterEnumHelp(name, description) +function RegisterEnumHelp(name, num_elements, description) { - DocumentedEnums[name] <- description; + DocumentedEnums[name] <- [num_elements, description]; } function RegisterConstHelp(name, signature, description) @@ -167,6 +168,11 @@ function RegisterHookHelp(name, signature, description) DocumentedHooks[name] <- [signature, description]; } +function RegisterMemberHelp(name, signature, description) +{ + DocumentedMembers[name] <- [signature, description]; +} + function printdoc( text ) { return ::printc(200,224,255,text); @@ -179,147 +185,152 @@ function printdocl( text ) function PrintClass(name, doc) { - printdocl("====================================="); - printdocl("Class: " + name); - printdocl("Base: " + doc[0]); + local text = "=====================================\n"; + text += ("Class: " + name + "\n"); + text += ("Base: " + doc[0] + "\n"); if (doc[1].len()) - printdocl("Description: " + doc[1]); - printdocl("====================================="); - print("\n"); + text += ("Description: " + doc[1] + "\n"); + text += "=====================================\n\n"; + + printdoc(text); } function PrintFunc(name, doc) { - printdocl("Function: " + name); + local text = "Function: " + name + "\n" + if (doc[0] == null) { // Is an aliased function - printdoc("Signature: function " + name + "("); + text += ("Signature: function " + name + "("); foreach(k,v in this[name].getinfos().parameters) { if (k == 0 && v == "this") continue; - if (k > 1) printdoc(", "); - printdoc(v); + if (k > 1) text += (", "); + text += (v); } - printdocl(")"); + text += (")\n"); } else { - printdocl("Signature: " + doc[0]); + text += ("Signature: " + doc[0] + "\n"); } if (doc[1].len()) - printdocl("Description: " + doc[1]); - print("\n"); + text += ("Description: " + doc[1] + "\n"); + printdocl(text); +} + +function PrintMember(name, doc) +{ + local text = ("Member: " + name + "\n"); + text += ("Signature: " + doc[0] + "\n"); + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + printdocl(text); } function PrintEnum(name, doc) { - printdocl("====================================="); - printdocl("Enum: " + name); - if (doc.len()) - printdocl("Description: " + doc); - printdocl("====================================="); - print("\n"); + local text = "=====================================\n"; + text += ("Enum: " + name + "\n"); + text += ("Elements: " + doc[0] + "\n"); + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + text += "=====================================\n\n"; + + printdoc(text); } function PrintConst(name, doc) { - printdocl("Constant: " + name); + local text = ("Constant: " + name + "\n"); if (doc[0] == null) { - // Is an aliased function - printdoc("Signature: function " + name + "("); - foreach(k,v in this[name].getinfos().parameters) - { - if (k == 0 && v == "this") continue; - if (k > 1) printdoc(", "); - printdoc(v); - } - printdocl(")"); + text += ("Value: null\n"); } else { - printdocl("Value: " + doc[0]); + text += ("Value: " + doc[0] + "\n"); } if (doc[1].len()) - printdocl("Description: " + doc[1]); - print("\n"); + text += ("Description: " + doc[1] + "\n"); + printdocl(text); } function PrintHook(name, doc) { - printdocl("Hook: " + name); + local text = ("Hook: " + name + "\n"); if (doc[0] == null) { // Is an aliased function - printdoc("Signature: function " + name + "("); + text += ("Signature: function " + name + "("); foreach(k,v in this[name].getinfos().parameters) { if (k == 0 && v == "this") continue; - if (k > 1) printdoc(", "); - printdoc(v); + if (k > 1) text += (", "); + text += (v); } - printdocl(")"); + text += (")\n"); } else { - printdocl("Signature: " + doc[0]); + text += ("Signature: " + doc[0] + "\n"); } if (doc[1].len()) - printdocl("Description: " + doc[1]); - print("\n"); + text += ("Description: " + doc[1] + "\n"); + printdocl(text); +} + +function PrintMatchesInDocList(pattern, list, printfunc) +{ + local foundMatches = false; + + foreach(name, doc in list) + { + if (pattern == "*" || name.tolower().find(pattern) != null || (doc[1].len() && doc[1].tolower().find(pattern) != null)) + { + foundMatches = true; + printfunc(name, doc) + } + } + + return foundMatches; } function PrintHelp(pattern = "*") { local foundMatches = false; - foreach(name, doc in DocumentedClasses) - { - if (pattern == "*" || name.tolower().find(pattern.tolower()) != null) - { - foundMatches = true; - PrintClass(name, doc) - } - } + local patternLower = pattern.tolower(); - foreach(name, doc in DocumentedFuncs) - { - if (pattern == "*" || name.tolower().find(pattern.tolower()) != null) - { - foundMatches = true; - PrintFunc(name, doc) - } - } - - foreach(name, doc in DocumentedEnums) - { - if (pattern == "*" || name.tolower().find(pattern.tolower()) != null) - { - foundMatches = true; - PrintEnum(name, doc) - } - } - - foreach(name, doc in DocumentedConsts) - { - if (pattern == "*" || name.tolower().find(pattern.tolower()) != null) - { - foundMatches = true; - PrintConst(name, doc) - } - } - - foreach(name, doc in DocumentedHooks) - { - if (pattern == "*" || name.tolower().find(pattern.tolower()) != null) - { - foundMatches = true; - PrintHook(name, doc) - } - } + // Have a specific order + foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedEnums, PrintEnum ) || foundMatches ); + foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedConsts, PrintConst ) || foundMatches ); + foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedClasses, PrintClass ) || foundMatches ); + foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedFuncs, PrintFunc ) || foundMatches ); + foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedMembers, PrintMember ) || foundMatches ); + foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedHooks, PrintHook ) || foundMatches ); if (!foundMatches) printdocl("Pattern " + pattern + " not found"); } +// Vector documentation +RegisterClassHelp( "Vector", "", "Basic 3-float Vector class." ); +RegisterHelp( "Vector::Length", "float Vector::Length()", "Return the vector's length." ); +RegisterHelp( "Vector::LengthSqr", "float Vector::LengthSqr()", "Return the vector's squared length." ); +RegisterHelp( "Vector::Length2D", "float Vector::Length2D()", "Return the vector's 2D length." ); +RegisterHelp( "Vector::Length2DSqr", "float Vector::Length2DSqr()", "Return the vector's squared 2D length." ); + +RegisterHelp( "Vector::Normalized", "float Vector::Normalized()", "Return a normalized version of the vector." ); +RegisterHelp( "Vector::Norm", "void Vector::Norm()", "Normalize the vector in place." ); +RegisterHelp( "Vector::Scale", "vector Vector::Scale(float)", "Scale the vector's magnitude and return the result." ); +RegisterHelp( "Vector::Dot", "float Vector::Dot(vector)", "Return the dot/scalar product of two vectors." ); +RegisterHelp( "Vector::Cross", "float Vector::Cross(vector)", "Return the vector product of two vectors." ); + +RegisterHelp( "Vector::ToKVString", "string Vector::ToKVString()", "Return a vector as a string in KeyValue form, without separation commas." ); + +RegisterMemberHelp( "Vector.x", "float Vector.x", "The vector's X coordinate on the cartesian X axis." ); +RegisterMemberHelp( "Vector.y", "float Vector.y", "The vector's Y coordinate on the cartesian Y axis." ); +RegisterMemberHelp( "Vector.z", "float Vector.z", "The vector's Z coordinate on the cartesian Z axis." ); + )vscript"; \ No newline at end of file diff --git a/thirdpartylegalnotices.txt b/thirdpartylegalnotices.txt index 2c75083f..8fb734dd 100644 --- a/thirdpartylegalnotices.txt +++ b/thirdpartylegalnotices.txt @@ -873,8 +873,8 @@ Google Snappy ************************************************************************************ Mapbase integrates a few additional third-party libraries, all of which are from free and/or -open-source projects operating under MIT or GNU licenses. They can be used in any mod or -commercial product as long as the given notices are present here or elsewhere. +open-source projects operating under MIT licenses. They can be used in any mod or commercial +product as long as the given notices are present here or elsewhere. ************************************************************************************ Squirrel programming language (used in VScript)