1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2024-12-22 17:47:38 +08:00

Added most recent version of unmodified HL2 SDK for Orange Box engine

This commit is contained in:
Scott Ehlert 2008-09-15 01:07:45 -05:00
commit 055f5cd168
2907 changed files with 1271781 additions and 0 deletions

202
Everything_SDK-2005.sln Normal file
View File

@ -0,0 +1,202 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Glview", "utils\glview\glview-2005.vcproj", "{BD1604CA-F401-4C4B-821C-251F5AE157FE}"
ProjectSection(ProjectDependencies) = postProject
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Height2normal", "utils\height2normal\height2normal-2005.vcproj", "{0FDD99E4-130F-493C-8202-4C0236CC47EA}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Serverplugin_empty", "utils\serverplugin_sample\serverplugin_empty-2005.vcproj", "{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tgadiff", "utils\tgadiff\tgadiff-2005.vcproj", "{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vbsp", "utils\vbsp\vbsp-2005.vcproj", "{B78B6271-B19A-4CF6-926E-40B643548E23}"
ProjectSection(ProjectDependencies) = postProject
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vice", "utils\vice\vice-2005.vcproj", "{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vrad_launcher", "utils\vrad_launcher\vrad_launcher-2005.vcproj", "{914F19DF-64EC-4E7D-8B01-76477BF06479}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vtf2tga", "utils\vtf2tga\vtf2tga-2005.vcproj", "{2A1F656C-053C-46A4-AE33-304C1D865E0C}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vtfdiff", "utils\vtfdiff\vtfdiff-2005.vcproj", "{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}"
ProjectSection(ProjectDependencies) = postProject
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vvis_launcher", "utils\vvis_launcher\vvis_launcher-2005.vcproj", "{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xwad", "utils\xwad\xwad-2005.vcproj", "{B850012C-98A2-42F7-B023-9F65C448D938}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demoinfo", "utils\demoinfo\demoinfo-2005.vcproj", "{4FE3FDCA-9571-44B3-A521-C81448434490}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Motionmapper", "utils\motionmapper\motionmapper-2005.vcproj", "{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}"
ProjectSection(ProjectDependencies) = postProject
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QC_Eyes", "utils\qc_eyes\QC_Eyes-2005.vcproj", "{D373436F-7DBF-468B-A3E4-601FB8556544}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mathlib", "mathlib\mathlib-2005.vcproj", "{884C66F2-7F84-4570-AE6C-B634C1113D69}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tier1", "tier1\tier1-2005.vcproj", "{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Phonemeextractor", "utils\phonemeextractor\phonemeextractor-2005.vcproj", "{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vgui_controls", "vgui2\vgui_controls\vgui_controls-2005.vcproj", "{BF3EDBF5-ED65-4567-B348-504C1310A1BB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vrad_dll", "utils\vrad\vrad_dll-2005.vcproj", "{0DA02E11-F553-4DD1-83D1-F760F2D96862}"
ProjectSection(ProjectDependencies) = postProject
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vvis_dll", "utils\vvis\vvis_dll-2005.vcproj", "{CB353257-04B0-4EC8-9E47-F2F17B2675C9}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
{884C66F2-7F84-4570-AE6C-B634C1113D69} = {884C66F2-7F84-4570-AE6C-B634C1113D69}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vprojtomake", "utils\vprojtomake\vprojtomake-2005.vcproj", "{EA55446E-BC04-491C-A9F0-605DFCBB213A}"
ProjectSection(ProjectDependencies) = postProject
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Debug|Win32.ActiveCfg = Debug|Win32
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Debug|Win32.Build.0 = Debug|Win32
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Release|Win32.ActiveCfg = Release|Win32
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Release|Win32.Build.0 = Release|Win32
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Debug|Win32.ActiveCfg = Debug|Win32
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Debug|Win32.Build.0 = Debug|Win32
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Release|Win32.ActiveCfg = Release|Win32
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Release|Win32.Build.0 = Release|Win32
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Debug|Win32.ActiveCfg = Debug|Win32
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Debug|Win32.Build.0 = Debug|Win32
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Release|Win32.ActiveCfg = Release|Win32
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Release|Win32.Build.0 = Release|Win32
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Debug|Win32.ActiveCfg = Debug|Win32
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Debug|Win32.Build.0 = Debug|Win32
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Release|Win32.ActiveCfg = Release|Win32
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Release|Win32.Build.0 = Release|Win32
{B78B6271-B19A-4CF6-926E-40B643548E23}.Debug|Win32.ActiveCfg = Debug|Win32
{B78B6271-B19A-4CF6-926E-40B643548E23}.Debug|Win32.Build.0 = Debug|Win32
{B78B6271-B19A-4CF6-926E-40B643548E23}.Release|Win32.ActiveCfg = Release|Win32
{B78B6271-B19A-4CF6-926E-40B643548E23}.Release|Win32.Build.0 = Release|Win32
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Debug|Win32.ActiveCfg = Debug|Win32
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Debug|Win32.Build.0 = Debug|Win32
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Release|Win32.ActiveCfg = Release|Win32
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Release|Win32.Build.0 = Release|Win32
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Debug|Win32.ActiveCfg = Debug|Win32
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Debug|Win32.Build.0 = Debug|Win32
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Release|Win32.ActiveCfg = Release|Win32
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Release|Win32.Build.0 = Release|Win32
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Debug|Win32.ActiveCfg = Debug|Win32
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Debug|Win32.Build.0 = Debug|Win32
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Release|Win32.ActiveCfg = Release|Win32
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Release|Win32.Build.0 = Release|Win32
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Debug|Win32.ActiveCfg = Debug|Win32
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Debug|Win32.Build.0 = Debug|Win32
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Release|Win32.ActiveCfg = Release|Win32
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Release|Win32.Build.0 = Release|Win32
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Debug|Win32.ActiveCfg = Debug|Win32
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Debug|Win32.Build.0 = Debug|Win32
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Release|Win32.ActiveCfg = Release|Win32
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Release|Win32.Build.0 = Release|Win32
{B850012C-98A2-42F7-B023-9F65C448D938}.Debug|Win32.ActiveCfg = Debug|Win32
{B850012C-98A2-42F7-B023-9F65C448D938}.Debug|Win32.Build.0 = Debug|Win32
{B850012C-98A2-42F7-B023-9F65C448D938}.Release|Win32.ActiveCfg = Release|Win32
{B850012C-98A2-42F7-B023-9F65C448D938}.Release|Win32.Build.0 = Release|Win32
{4FE3FDCA-9571-44B3-A521-C81448434490}.Debug|Win32.ActiveCfg = Debug|Win32
{4FE3FDCA-9571-44B3-A521-C81448434490}.Debug|Win32.Build.0 = Debug|Win32
{4FE3FDCA-9571-44B3-A521-C81448434490}.Release|Win32.ActiveCfg = Release|Win32
{4FE3FDCA-9571-44B3-A521-C81448434490}.Release|Win32.Build.0 = Release|Win32
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Debug|Win32.ActiveCfg = Debug|Win32
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Debug|Win32.Build.0 = Debug|Win32
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Release|Win32.ActiveCfg = Release|Win32
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Release|Win32.Build.0 = Release|Win32
{D373436F-7DBF-468B-A3E4-601FB8556544}.Debug|Win32.ActiveCfg = Debug|Win32
{D373436F-7DBF-468B-A3E4-601FB8556544}.Debug|Win32.Build.0 = Debug|Win32
{D373436F-7DBF-468B-A3E4-601FB8556544}.Release|Win32.ActiveCfg = Release|Win32
{D373436F-7DBF-468B-A3E4-601FB8556544}.Release|Win32.Build.0 = Release|Win32
{884C66F2-7F84-4570-AE6C-B634C1113D69}.Debug|Win32.ActiveCfg = Debug|Win32
{884C66F2-7F84-4570-AE6C-B634C1113D69}.Debug|Win32.Build.0 = Debug|Win32
{884C66F2-7F84-4570-AE6C-B634C1113D69}.Release|Win32.ActiveCfg = Release|Win32
{884C66F2-7F84-4570-AE6C-B634C1113D69}.Release|Win32.Build.0 = Release|Win32
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Debug|Win32.ActiveCfg = Debug|Win32
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Debug|Win32.Build.0 = Debug|Win32
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Release|Win32.ActiveCfg = Release|Win32
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Release|Win32.Build.0 = Release|Win32
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Debug|Win32.ActiveCfg = Debug|Win32
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Debug|Win32.Build.0 = Debug|Win32
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Release|Win32.ActiveCfg = Release|Win32
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Release|Win32.Build.0 = Release|Win32
{BF3EDBF5-ED65-4567-B348-504C1310A1BB}.Debug|Win32.ActiveCfg = Debug|Win32
{BF3EDBF5-ED65-4567-B348-504C1310A1BB}.Debug|Win32.Build.0 = Debug|Win32
{BF3EDBF5-ED65-4567-B348-504C1310A1BB}.Release|Win32.ActiveCfg = Release|Win32
{BF3EDBF5-ED65-4567-B348-504C1310A1BB}.Release|Win32.Build.0 = Release|Win32
{0DA02E11-F553-4DD1-83D1-F760F2D96862}.Debug|Win32.ActiveCfg = Debug|Win32
{0DA02E11-F553-4DD1-83D1-F760F2D96862}.Debug|Win32.Build.0 = Debug|Win32
{0DA02E11-F553-4DD1-83D1-F760F2D96862}.Release|Win32.ActiveCfg = Release|Win32
{0DA02E11-F553-4DD1-83D1-F760F2D96862}.Release|Win32.Build.0 = Release|Win32
{CB353257-04B0-4EC8-9E47-F2F17B2675C9}.Debug|Win32.ActiveCfg = Debug|Win32
{CB353257-04B0-4EC8-9E47-F2F17B2675C9}.Debug|Win32.Build.0 = Debug|Win32
{CB353257-04B0-4EC8-9E47-F2F17B2675C9}.Release|Win32.ActiveCfg = Release|Win32
{CB353257-04B0-4EC8-9E47-F2F17B2675C9}.Release|Win32.Build.0 = Release|Win32
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Debug|Win32.ActiveCfg = Debug|Win32
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Debug|Win32.Build.0 = Debug|Win32
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Release|Win32.ActiveCfg = Release|Win32
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

25
Game_Episodic-2005.sln Normal file
View File

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Client (Episodic)", "game\client\client_episodic-2005.vcproj", "{306BEF7B-8A1F-F569-3761-3E05CFD6D683}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server (Episodic)", "game\server\server_episodic-2005.vcproj", "{31C796EE-3EE9-54FC-9EF2-AC09ED9C18F5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{306BEF7B-8A1F-F569-3761-3E05CFD6D683}.Debug|Win32.ActiveCfg = Debug|Win32
{306BEF7B-8A1F-F569-3761-3E05CFD6D683}.Debug|Win32.Build.0 = Debug|Win32
{306BEF7B-8A1F-F569-3761-3E05CFD6D683}.Release|Win32.ActiveCfg = Release|Win32
{306BEF7B-8A1F-F569-3761-3E05CFD6D683}.Release|Win32.Build.0 = Release|Win32
{31C796EE-3EE9-54FC-9EF2-AC09ED9C18F5}.Debug|Win32.ActiveCfg = Debug|Win32
{31C796EE-3EE9-54FC-9EF2-AC09ED9C18F5}.Debug|Win32.Build.0 = Debug|Win32
{31C796EE-3EE9-54FC-9EF2-AC09ED9C18F5}.Release|Win32.ActiveCfg = Release|Win32
{31C796EE-3EE9-54FC-9EF2-AC09ED9C18F5}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

25
Game_HL2-2005.sln Normal file
View File

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Client (HL2)", "game\client\client_hl2-2005.vcproj", "{F2D9D6B0-DEE5-4217-9336-A4FEBA24C790}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server (HL2)", "game\server\server_hl2-2005.vcproj", "{EB864878-8530-446B-B8E4-BE97D3F608F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F2D9D6B0-DEE5-4217-9336-A4FEBA24C790}.Debug|Win32.ActiveCfg = Debug|Win32
{F2D9D6B0-DEE5-4217-9336-A4FEBA24C790}.Debug|Win32.Build.0 = Debug|Win32
{F2D9D6B0-DEE5-4217-9336-A4FEBA24C790}.Release|Win32.ActiveCfg = Release|Win32
{F2D9D6B0-DEE5-4217-9336-A4FEBA24C790}.Release|Win32.Build.0 = Release|Win32
{EB864878-8530-446B-B8E4-BE97D3F608F7}.Debug|Win32.ActiveCfg = Debug|Win32
{EB864878-8530-446B-B8E4-BE97D3F608F7}.Debug|Win32.Build.0 = Debug|Win32
{EB864878-8530-446B-B8E4-BE97D3F608F7}.Release|Win32.ActiveCfg = Release|Win32
{EB864878-8530-446B-B8E4-BE97D3F608F7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

25
Game_HL2MP-2005.sln Normal file
View File

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Client (HL2MP)", "game\client\client_hl2mp-2005.vcproj", "{5FE91DC8-B6DF-4061-984E-36FD36623E72}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server (HL2MP)", "game\server\server_hl2mp-2005.vcproj", "{4254C2D9-2C38-4911-BD4A-EB034CBD48D1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5FE91DC8-B6DF-4061-984E-36FD36623E72}.Debug|Win32.ActiveCfg = Debug|Win32
{5FE91DC8-B6DF-4061-984E-36FD36623E72}.Debug|Win32.Build.0 = Debug|Win32
{5FE91DC8-B6DF-4061-984E-36FD36623E72}.Release|Win32.ActiveCfg = Release|Win32
{5FE91DC8-B6DF-4061-984E-36FD36623E72}.Release|Win32.Build.0 = Release|Win32
{4254C2D9-2C38-4911-BD4A-EB034CBD48D1}.Debug|Win32.ActiveCfg = Debug|Win32
{4254C2D9-2C38-4911-BD4A-EB034CBD48D1}.Debug|Win32.Build.0 = Debug|Win32
{4254C2D9-2C38-4911-BD4A-EB034CBD48D1}.Release|Win32.ActiveCfg = Release|Win32
{4254C2D9-2C38-4911-BD4A-EB034CBD48D1}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

25
Game_Scratch-2005.sln Normal file
View File

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Client (SDK)", "game\client\client_scratch-2005.vcproj", "{09603CC0-928D-4939-83E5-C255291B9466}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server (SDK)", "game\server\server_scratch-2005.vcproj", "{E8C0FE86-D8E1-4B44-8F76-F2A9A21E9C4F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{09603CC0-928D-4939-83E5-C255291B9466}.Debug|Win32.ActiveCfg = Debug|Win32
{09603CC0-928D-4939-83E5-C255291B9466}.Debug|Win32.Build.0 = Debug|Win32
{09603CC0-928D-4939-83E5-C255291B9466}.Release|Win32.ActiveCfg = Release|Win32
{09603CC0-928D-4939-83E5-C255291B9466}.Release|Win32.Build.0 = Release|Win32
{E8C0FE86-D8E1-4B44-8F76-F2A9A21E9C4F}.Debug|Win32.ActiveCfg = Debug|Win32
{E8C0FE86-D8E1-4B44-8F76-F2A9A21E9C4F}.Debug|Win32.Build.0 = Debug|Win32
{E8C0FE86-D8E1-4B44-8F76-F2A9A21E9C4F}.Release|Win32.ActiveCfg = Release|Win32
{E8C0FE86-D8E1-4B44-8F76-F2A9A21E9C4F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

113
common/GameUI/IGameUI.h Normal file
View File

@ -0,0 +1,113 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef IGAMEUI_H
#define IGAMEUI_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include "vgui/IPanel.h"
#if !defined( _X360 )
#include "xbox/xboxstubs.h"
#endif
// reasons why the user can't connect to a game server
enum ESteamLoginFailure
{
STEAMLOGINFAILURE_NONE,
STEAMLOGINFAILURE_BADTICKET,
STEAMLOGINFAILURE_NOSTEAMLOGIN,
STEAMLOGINFAILURE_VACBANNED,
STEAMLOGINFAILURE_LOGGED_IN_ELSEWHERE
};
enum ESystemNotify
{
SYSTEMNOTIFY_STORAGEDEVICES_CHANGED,
SYSTEMNOTIFY_USER_SIGNEDIN,
SYSTEMNOTIFY_USER_SIGNEDOUT,
SYSTEMNOTIFY_XUIOPENING,
SYSTEMNOTIFY_XUICLOSED,
SYSTEMNOTIFY_INVITE_SHUTDOWN, // Cross-game invite is causing us to shutdown
};
//-----------------------------------------------------------------------------
// Purpose: contains all the functions that the GameUI dll exports
//-----------------------------------------------------------------------------
abstract_class IGameUI
{
public:
// initialization/shutdown
virtual void Initialize( CreateInterfaceFn appFactory ) = 0;
virtual void PostInit() = 0;
// connect to other interfaces at the same level (gameui.dll/server.dll/client.dll)
virtual void Connect( CreateInterfaceFn gameFactory ) = 0;
virtual void Start() = 0;
virtual void Shutdown() = 0;
virtual void RunFrame() = 0;
// notifications
virtual void OnGameUIActivated() = 0;
virtual void OnGameUIHidden() = 0;
// OLD: Use OnConnectToServer2
virtual void OLD_OnConnectToServer(const char *game, int IP, int port) = 0;
virtual void OnDisconnectFromServer_OLD( uint8 eSteamLoginFailure, const char *username ) = 0;
virtual void OnLevelLoadingStarted(bool bShowProgressDialog) = 0;
virtual void OnLevelLoadingFinished(bool bError, const char *failureReason, const char *extendedReason) = 0;
// level loading progress, returns true if the screen needs updating
virtual bool UpdateProgressBar(float progress, const char *statusText) = 0;
// Shows progress desc, returns previous setting... (used with custom progress bars )
virtual bool SetShowProgressText( bool show ) = 0;
// !!!!!!!!!members added after "GameUI011" initial release!!!!!!!!!!!!!!!!!!!
virtual void ShowNewGameDialog( int chapter ) = 0;
// Xbox 360
virtual void SessionNotification( const int notification, const int param = 0 ) = 0;
virtual void SystemNotification( const int notification ) = 0;
virtual void ShowMessageDialog( const uint nType, vgui::Panel *pOwner ) = 0;
virtual void UpdatePlayerInfo( uint64 nPlayerId, const char *pName, int nTeam, byte cVoiceState, int nPlayersNeeded, bool bHost ) = 0;
virtual void SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping ) = 0;
virtual void OnCreditsFinished( void ) = 0;
// inserts specified panel as background for level load dialog
virtual void SetLoadingBackgroundDialog( vgui::VPANEL panel ) = 0;
// Bonus maps interfaces
virtual void BonusMapUnlock( const char *pchFileName = NULL, const char *pchMapName = NULL ) = 0;
virtual void BonusMapComplete( const char *pchFileName = NULL, const char *pchMapName = NULL ) = 0;
virtual void BonusMapChallengeUpdate( const char *pchFileName, const char *pchMapName, const char *pchChallengeName, int iBest ) = 0;
virtual void BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName ) = 0;
virtual void BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold ) = 0;
virtual void BonusMapDatabaseSave( void ) = 0;
virtual int BonusMapNumAdvancedCompleted( void ) = 0;
virtual void BonusMapNumMedals( int piNumMedals[ 3 ] ) = 0;
virtual void OnConnectToServer2(const char *game, int IP, int connectionPort, int queryPort) = 0;
// X360 Storage device validation:
// returns true right away if storage device has been previously selected.
// otherwise returns false and will set the variable pointed by pStorageDeviceValidated to 1
// once the storage device is selected by user.
virtual bool ValidateStorageDevice( int *pStorageDeviceValidated ) = 0;
virtual void SetProgressOnStart() = 0;
virtual void OnDisconnectFromServer( uint8 eSteamLoginFailure ) = 0;
};
#define GAMEUI_INTERFACE_VERSION "GameUI011"
#endif // IGAMEUI_H

View File

@ -0,0 +1,103 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Swap a compiled caption file.
//
// $NoKeywords: $
//=============================================================================//
#include "utlbuffer.h"
#include "byteswap.h"
#include "filesystem.h"
#include "tier2/fileutils.h"
#include "captioncompiler.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
BEGIN_BYTESWAP_DATADESC( CompiledCaptionHeader_t )
DEFINE_FIELD( magic, FIELD_INTEGER ),
DEFINE_FIELD( version, FIELD_INTEGER ),
DEFINE_FIELD( numblocks, FIELD_INTEGER ),
DEFINE_FIELD( blocksize, FIELD_INTEGER ),
DEFINE_FIELD( directorysize, FIELD_INTEGER ),
DEFINE_FIELD( dataoffset, FIELD_INTEGER ),
END_BYTESWAP_DATADESC()
BEGIN_BYTESWAP_DATADESC( CaptionLookup_t )
DEFINE_FIELD( hash, FIELD_INTEGER ),
DEFINE_FIELD( blockNum, FIELD_INTEGER ),
DEFINE_FIELD( offset, FIELD_SHORT ),
DEFINE_FIELD( length, FIELD_SHORT ),
END_BYTESWAP_DATADESC()
//-----------------------------------------------------------------------------
// Swap a compiled closecaption file
//-----------------------------------------------------------------------------
bool SwapClosecaptionFile( void *pData )
{
CByteswap swap;
swap.ActivateByteSwapping( true );
CompiledCaptionHeader_t *pHdr = (CompiledCaptionHeader_t*)pData;
if ( IsX360() )
{
// pre-swap file header
swap.SwapFieldsToTargetEndian( pHdr );
}
if ( pHdr->magic != COMPILED_CAPTION_FILEID || pHdr->version != COMPILED_CAPTION_VERSION )
{
// bad data
return false;
}
// lookup headers
pData = (byte*)pData + sizeof(CompiledCaptionHeader_t);
swap.SwapFieldsToTargetEndian( (CaptionLookup_t*)pData, pHdr->directorysize );
// unicode data
pData = (byte*)pHdr + pHdr->dataoffset;
swap.SwapBufferToTargetEndian( (wchar_t*)pData, (wchar_t*)pData, pHdr->numblocks * pHdr->blocksize / sizeof(wchar_t) );
if ( IsPC() )
{
// post-swap file header
swap.SwapFieldsToTargetEndian( pHdr );
}
return true;
}
#if defined( CLIENT_DLL )
//-----------------------------------------------------------------------------
// Callback for UpdateOrCreate - generates .360 file
//-----------------------------------------------------------------------------
static bool CaptionCreateCallback( const char *pSourceName, const char *pTargetName, const char *pPathID, void *pExtraData )
{
// Generate the file
CUtlBuffer buf;
bool bOk = g_pFullFileSystem->ReadFile( pSourceName, pPathID, buf );
if ( bOk )
{
bOk = SwapClosecaptionFile( buf.Base() );
if ( bOk )
{
bOk = g_pFullFileSystem->WriteFile( pTargetName, pPathID, buf );
}
else
{
Warning( "Failed to create %s\n", pTargetName );
}
}
return bOk;
}
//-----------------------------------------------------------------------------
// Calls utility function UpdateOrCreate
//-----------------------------------------------------------------------------
int UpdateOrCreateCaptionFile( const char *pSourceName, char *pTargetName, int maxLen, bool bForce )
{
return ::UpdateOrCreate( pSourceName, pTargetName, maxLen, "GAME", CaptionCreateCallback, bForce );
}
#endif

363
common/hl2orange.spa.h Normal file
View File

@ -0,0 +1,363 @@
////////////////////////////////////////////////////////////////////
//
// hl2orange.spa.h
//
// Auto-generated on Thursday, 13 September 2007 at 16:59:17
// XLAST project version 1.0.402.0
// SPA Compiler version 2.0.6274.0
//
////////////////////////////////////////////////////////////////////
#ifndef __THE_ORANGE_BOX_SPA_H__
#define __THE_ORANGE_BOX_SPA_H__
#ifdef __cplusplus
extern "C" {
#endif
//
// Title info
//
#define TITLEID_THE_ORANGE_BOX 0x4541080F
//
// Context ids
//
// These values are passed as the dwContextId to XUserSetContext.
//
#define CONTEXT_CHAPTER_HL2 0
#define CONTEXT_SCENARIO 1
#define CONTEXT_GAME 2
#define CONTEXT_CHAPTER_EP1 3
#define CONTEXT_CHAPTER_EP2 4
#define CONTEXT_CHAPTER_PORTAL 5
//
// Context values
//
// These values are passed as the dwContextValue to XUserSetContext.
//
// Values for CONTEXT_CHAPTER_HL2
#define CONTEXT_CHAPTER_HL2_POINT_INSERTION 0
#define CONTEXT_CHAPTER_HL2_A_RED_LETTER_DAY 1
#define CONTEXT_CHAPTER_HL2_ROUTE_KANAL 2
#define CONTEXT_CHAPTER_HL2_WATER_HAZARD 3
#define CONTEXT_CHAPTER_HL2_BLACK_MESA_EAST 4
#define CONTEXT_CHAPTER_HL2_RAVENHOLM 5
#define CONTEXT_CHAPTER_HL2_HIGHWAY_17 6
#define CONTEXT_CHAPTER_HL2_SANDTRAPS 7
#define CONTEXT_CHAPTER_HL2_NOVA_PROSPEKT 8
#define CONTEXT_CHAPTER_HL2_ENTANGLEMENT 9
#define CONTEXT_CHAPTER_HL2_ANTICITIZEN_ONE 10
#define CONTEXT_CHAPTER_HL2_FOLLOW_FREEMAN 11
#define CONTEXT_CHAPTER_HL2_OUR_BENEFACTORS 12
#define CONTEXT_CHAPTER_HL2_DARK_ENERGY 13
// Values for CONTEXT_SCENARIO
#define CONTEXT_SCENARIO_CTF_2FORT 0
#define CONTEXT_SCENARIO_CP_DUSTBOWL 1
#define CONTEXT_SCENARIO_CP_GRANARY 2
#define CONTEXT_SCENARIO_CP_WELL 3
#define CONTEXT_SCENARIO_CP_GRAVELPIT 4
#define CONTEXT_SCENARIO_TC_HYDRO 5
#define CONTEXT_SCENARIO_CTF_CLOAK 6
#define CONTEXT_SCENARIO_CP_CLOAK 7
// Values for CONTEXT_GAME
#define CONTEXT_GAME_GAME_HALF_LIFE_2 0
#define CONTEXT_GAME_GAME_EPISODE_ONE 1
#define CONTEXT_GAME_GAME_EPISODE_TWO 2
#define CONTEXT_GAME_GAME_PORTAL 3
#define CONTEXT_GAME_GAME_TEAM_FORTRESS 4
// Values for CONTEXT_CHAPTER_EP1
#define CONTEXT_CHAPTER_EP1_UNDUE_ALARM 0
#define CONTEXT_CHAPTER_EP1_DIRECT_INTERVENTION 1
#define CONTEXT_CHAPTER_EP1_LOWLIFE 2
#define CONTEXT_CHAPTER_EP1_URBAN_FLIGHT 3
#define CONTEXT_CHAPTER_EP1_EXIT_17 4
// Values for CONTEXT_CHAPTER_EP2
#define CONTEXT_CHAPTER_EP2_TO_THE_WHITE_FOREST 0
#define CONTEXT_CHAPTER_EP2_THIS_VORTAL_COIL 1
#define CONTEXT_CHAPTER_EP2_FREEMAN_PONTIFEX 2
#define CONTEXT_CHAPTER_EP2_RIDING_SHOTGUN 3
#define CONTEXT_CHAPTER_EP2_UNDER_THE_RADAR 4
#define CONTEXT_CHAPTER_EP2_OUR_MUTUAL_FIEND 5
#define CONTEXT_CHAPTER_EP2_T_MINUS_ONE 6
// Values for CONTEXT_CHAPTER_PORTAL
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_00 0
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_04 1
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_08 2
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_10 3
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_13 4
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_14 5
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_15 6
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_16 7
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_17 8
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_18 9
#define CONTEXT_CHAPTER_PORTAL_TESTCHAMBER_19 10
// Values for X_CONTEXT_PRESENCE
#define CONTEXT_PRESENCE_TF_CP 0
#define CONTEXT_PRESENCE_TF_CTF_LOSING 1
#define CONTEXT_PRESENCE_TF_CTF_TIED 2
#define CONTEXT_PRESENCE_TF_CTF_WINNING 3
#define CONTEXT_PRESENCE_APPCHOOSER 4
#define CONTEXT_PRESENCE_MENU 5
#define CONTEXT_PRESENCE_EP1_INGAME 6
#define CONTEXT_PRESENCE_HL2_INGAME 7
#define CONTEXT_PRESENCE_EP2_INGAME 8
#define CONTEXT_PRESENCE_PORTAL_INGAME 9
#define CONTEXT_PRESENCE_COMMENTARY 10
#define CONTEXT_PRESENCE_IDLE 11
// Values for X_CONTEXT_GAME_MODE
#define CONTEXT_GAME_MODE_MULTIPLAYER 0
#define CONTEXT_GAME_MODE_SINGLEPLAYER 1
//
// Property ids
//
// These values are passed as the dwPropertyId value to XUserSetProperty
// and as the dwPropertyId value in the XUSER_PROPERTY structure.
//
#define PROPERTY_CAPS_OWNED 0x10000000
#define PROPERTY_CAPS_TOTAL 0x10000001
#define PROPERTY_PLAYER_TEAM_SCORE 0x10000002
#define PROPERTY_OPPONENT_TEAM_SCORE 0x10000003
#define PROPERTY_FLAG_CAPTURE_LIMIT 0x1000000B
#define PROPERTY_NUMBER_OF_ROUNDS 0x1000000C
#define PROPERTY_GAME_SIZE 0x1000000D
#define PROPERTY_AUTOBALANCE 0x1000000E
#define PROPERTY_PRIVATE_SLOTS 0x1000000F
#define PROPERTY_MAX_GAME_TIME 0x10000010
#define PROPERTY_NUMBER_OF_KILLS 0x10000011
#define PROPERTY_DAMAGE_DEALT 0x10000012
#define PROPERTY_PLAY_TIME 0x10000013
#define PROPERTY_POINT_CAPTURES 0x10000014
#define PROPERTY_POINT_DEFENSES 0x10000015
#define PROPERTY_DOMINATIONS 0x10000016
#define PROPERTY_REVENGE 0x10000017
#define PROPERTY_BUILDINGS_DESTROYED 0x10000019
#define PROPERTY_HEADSHOTS 0x1000001A
#define PROPERTY_HEALTH_POINTS_HEALED 0x1000001B
#define PROPERTY_INVULNS 0x1000001C
#define PROPERTY_KILL_ASSISTS 0x1000001D
#define PROPERTY_BACKSTABS 0x1000001E
#define PROPERTY_HEALTH_POINTS_LEACHED 0x1000001F
#define PROPERTY_BUILDINGS_BUILT 0x10000020
#define PROPERTY_SENTRY_KILLS 0x10000021
#define PROPERTY_TELEPORTS 0x10000022
#define PROPERTY_KILLS 0x10000023
#define PROPERTY_NUMBER_OF_TEAMS 0x10000025
#define PROPERTY_TEAM_RED 0x10000026
#define PROPERTY_TEAM_BLUE 0x10000027
#define PROPERTY_TEAM_SPECTATOR 0x10000028
#define PROPERTY_TEAM 0x10000029
#define PROPERTY_WIN_LIMIT 0x1000002A
#define PROPERTY_RANKING_TEST 0x2000000A
#define PROPERTY_POINTS_SCORED 0x20000018
//
// Achievement ids
//
// These values are used in the dwAchievementId member of the
// XUSER_ACHIEVEMENT structure that is used with
// XUserWriteAchievements and XUserCreateAchievementEnumerator.
//
#define ACHIEVEMENT_HLX_KILL_ENEMIES_WITHPHYSICS 43
#define ACHIEVEMENT_HLX_KILL_ENEMY_WITHHOPPERMINE 44
#define ACHIEVEMENT_HLX_KILL_ENEMIES_WITHMANHACK 45
#define ACHIEVEMENT_HLX_KILL_SOLDIER_WITHHISGRENADE 46
#define ACHIEVEMENT_HLX_KILL_ENEMIES_WITHONEENERGYBALL 47
#define ACHIEVEMENT_HLX_KILL_ELITESOLDIER_WITHHISENERGYBALL 48
#define ACHIEVEMENT_EPX_GET_ZOMBINEGRENADE 50
#define ACHIEVEMENT_EPX_KILL_ZOMBIES_WITHFLARES 51
#define ACHIEVEMENT_HL2_HIT_CANCOP_WITHCAN 52
#define ACHIEVEMENT_HL2_PUT_CANINTRASH 53
#define ACHIEVEMENT_HL2_ESCAPE_APARTMENTRAID 54
#define ACHIEVEMENT_HL2_BREAK_MINITELEPORTER 55
#define ACHIEVEMENT_HL2_GET_CROWBAR 56
#define ACHIEVEMENT_HL2_KILL_BARNACLESWITHBARREL 57
#define ACHIEVEMENT_HL2_GET_AIRBOAT 58
#define ACHIEVEMENT_HL2_GET_AIRBOATGUN 60
#define ACHIEVEMENT_HL2_FIND_VORTIGAUNTCAVE 61
#define ACHIEVEMENT_HL2_KILL_CHOPPER 62
#define ACHIEVEMENT_HL2_FIND_HEVFACEPLATE 63
#define ACHIEVEMENT_HL2_GET_GRAVITYGUN 64
#define ACHIEVEMENT_HL2_MAKEABASKET 65
#define ACHIEVEMENT_HL2_BEAT_RAVENHOLM_NOWEAPONS 66
#define ACHIEVEMENT_HL2_BEAT_CEMETERY 67
#define ACHIEVEMENT_HL2_KILL_ENEMIES_WITHCRANE 68
#define ACHIEVEMENT_HL2_PIN_SOLDIER_TOBILLBOARD 69
#define ACHIEVEMENT_HL2_KILL_ODESSAGUNSHIP 70
#define ACHIEVEMENT_HL2_KILL_THREEGUNSHIPS 71
#define ACHIEVEMENT_HL2_BEAT_DONTTOUCHSAND 72
#define ACHIEVEMENT_HL2_KILL_ENEMIES_WITHANTLIONS 74
#define ACHIEVEMENT_HL2_KILL_ENEMY_WITHTOILET 75
#define ACHIEVEMENT_HL2_BEAT_TURRETSTANDOFF2 76
#define ACHIEVEMENT_HL2_BEAT_TOXICTUNNEL 78
#define ACHIEVEMENT_HL2_BEAT_PLAZASTANDOFF 79
#define ACHIEVEMENT_HL2_KILL_ALLC1709SNIPERS 80
#define ACHIEVEMENT_HL2_BEAT_SUPRESSIONDEVICE 81
#define ACHIEVEMENT_HL2_BEAT_C1713STRIDERSTANDOFF 82
#define ACHIEVEMENT_HL2_BEAT_GAME 84
#define ACHIEVEMENT_HL2_FIND_ALLLAMBDAS 86
#define ACHIEVEMENT_EP1_BEAT_MAINELEVATOR 87
#define ACHIEVEMENT_EP1_BEAT_CITADELCORE 88
#define ACHIEVEMENT_EP1_BEAT_CITADELCORE_NOSTALKERKILLS 89
#define ACHIEVEMENT_EP1_KILL_ANTLIONS_WITHCARS 90
#define ACHIEVEMENT_EP1_BEAT_GARAGEELEVATORSTANDOFF 91
#define ACHIEVEMENT_EP1_KILL_ENEMIES_WITHSNIPERALYX 92
#define ACHIEVEMENT_EP1_BEAT_HOSPITALATTICGUNSHIP 93
#define ACHIEVEMENT_EP1_BEAT_CITIZENESCORT_NOCITIZENDEATHS 94
#define ACHIEVEMENT_EP1_BEAT_GAME 95
#define ACHIEVEMENT_EP1_BEAT_GAME_ONEBULLET 96
#define ACHIEVEMENT_EP2_KILL_POISONANTLION 97
#define ACHIEVEMENT_EP2_KILL_ALLGRUBS 98
#define ACHIEVEMENT_EP2_BREAK_ALLWEBS 99
#define ACHIEVEMENT_EP2_BEAT_ANTLIONINVASION 100
#define ACHIEVEMENT_EP2_BEAT_ANTLIONGUARDS 101
#define ACHIEVEMENT_EP2_KILL_ENEMIES_WITHCAR 102
#define ACHIEVEMENT_EP2_BEAT_HUNTERAMBUSH 103
#define ACHIEVEMENT_EP2_KILL_CHOPPER_NOMISSES 104
#define ACHIEVEMENT_EP2_KILL_COMBINECANNON 105
#define ACHIEVEMENT_EP2_FIND_ALLRADARCACHES 106
#define ACHIEVEMENT_EP2_BEAT_ROCKETCACHEPUZZLE 107
#define ACHIEVEMENT_EP2_BEAT_RACEWITHDOG 108
#define ACHIEVEMENT_EP2_BEAT_WHITEFORESTINN 109
#define ACHIEVEMENT_EP2_PUT_ITEMINROCKET 110
#define ACHIEVEMENT_EP2_BEAT_MISSILESILO2 111
#define ACHIEVEMENT_EP2_BEAT_OUTLAND12_NOBUILDINGSDESTROYED 112
#define ACHIEVEMENT_EP2_BEAT_GAME 113
#define ACHIEVEMENT_EP2_KILL_HUNTER_WITHFLECHETTES 114
#define ACHIEVEMENT_PORTAL_GET_PORTALGUNS 115
#define ACHIEVEMENT_PORTAL_KILL_COMPANIONCUBE 116
#define ACHIEVEMENT_PORTAL_ESCAPE_TESTCHAMBERS 117
#define ACHIEVEMENT_PORTAL_BEAT_GAME 118
#define ACHIEVEMENT_PORTAL_INFINITEFALL 119
#define ACHIEVEMENT_PORTAL_LONGJUMP 120
#define ACHIEVEMENT_PORTAL_BEAT_2ADVANCEDMAPS 121
#define ACHIEVEMENT_PORTAL_BEAT_4ADVANCEDMAPS 122
#define ACHIEVEMENT_PORTAL_BEAT_6ADVANCEDMAPS 123
#define ACHIEVEMENT_PORTAL_GET_ALLBRONZE 124
#define ACHIEVEMENT_PORTAL_GET_ALLSILVER 125
#define ACHIEVEMENT_PORTAL_GET_ALLGOLD 126
#define ACHIEVEMENT_TF_GET_TURRETKILLS 127
#define ACHIEVEMENT_TF_KILL_NEMESIS 128
#define ACHIEVEMENT_TF_GET_CONSECUTIVEKILLS_NODEATHS 129
#define ACHIEVEMENT_TF_GET_HEALED_BYENEMY 130
#define ACHIEVEMENT_TF_PLAY_GAME_FRIENDSONLY 131
#define ACHIEVEMENT_TF_WIN_MULTIPLEGAMES 132
#define ACHIEVEMENT_TF_GET_MULTIPLEKILLS 133
#define ACHIEVEMENT_TF_WIN_2FORT_NOENEMYCAPS 134
#define ACHIEVEMENT_TF_WIN_WELL_MINIMUMTIME 135
#define ACHIEVEMENT_TF_WIN_HYDRO_NOENEMYCAPS 136
#define ACHIEVEMENT_TF_WIN_DUSTBOWL_NOENEMYCAPS 137
#define ACHIEVEMENT_TF_WIN_GRAVELPIT_NOENEMYCAPS 138
#define ACHIEVEMENT_TF_PLAY_GAME_EVERYCLASS 139
#define ACHIEVEMENT_TF_PLAY_GAME_EVERYMAP 140
#define ACHIEVEMENT_TF_GET_HEALPOINTS 141
#define ACHIEVEMENT_TF_BURN_PLAYERSINMINIMIMTIME 142
#define ACHIEVEMENT_HL2_DISINTEGRATE_SOLDIERSINFIELD 143
#define ACHIEVEMENT_HL2_FOLLOW_FREEMAN 144
#define ACHIEVEMENT_TF_GET_HEADSHOTS 145
#define ACHIEVEMENT_PORTAL_DETACH_ALL_CAMERAS 146
#define ACHIEVEMENT_PORTAL_HIT_TURRET_WITH_TURRET 148
//
// Stats view ids
//
// These are used in the dwViewId member of the XUSER_STATS_SPEC structure
// passed to the XUserReadStats* and XUserCreateStatsEnumerator* functions.
//
// Skill leaderboards for ranked game modes
#define STATS_VIEW_SKILL_RANKED_MULTIPLAYER 0xFFFF0000
#define STATS_VIEW_SKILL_RANKED_SINGLEPLAYER 0xFFFF0001
// Skill leaderboards for unranked (standard) game modes
#define STATS_VIEW_SKILL_STANDARD_MULTIPLAYER 0xFFFE0000
#define STATS_VIEW_SKILL_STANDARD_SINGLEPLAYER 0xFFFE0001
// Title defined leaderboards
#define STATS_VIEW_PLAYER_MAX_UNRANKED 1
#define STATS_VIEW_PLAYER_MAX_RANKED 2
//
// Stats view column ids
//
// These ids are used to read columns of stats views. They are specified in
// the rgwColumnIds array of the XUSER_STATS_SPEC structure. Rank, rating
// and gamertag are not retrieved as custom columns and so are not included
// in the following definitions. They can be retrieved from each row's
// header (e.g., pStatsResults->pViews[x].pRows[y].dwRank, etc.).
//
// Column ids for PLAYER_MAX_UNRANKED
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_POINTS_SCORED 2
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_KILLS 3
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_POINTS_CAPPED 1
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_DAMAGE_DEALT 4
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_PLAY_TIME 5
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_POINT_DEFENSES 6
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_DOMINATIONS 7
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_REVENGE 8
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_BUILDINGS_DESTROYED 9
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_HEADSHOTS 10
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_HEALTH_POINTS_HEALED 11
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_INVULNS 12
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_KILL_ASSISTS 13
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_BACKSTABS 14
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_HEALTH_POINTS_LEACHED 15
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_BUILDINGS_BUILT 16
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_SENTRY_KILLS 17
#define STATS_COLUMN_PLAYER_MAX_UNRANKED_TELEPORTS 18
// Column ids for PLAYER_MAX_RANKED
#define STATS_COLUMN_PLAYER_MAX_RANKED_POINTS_SCORED 2
//
// Matchmaking queries
//
// These values are passed as the dwProcedureIndex parameter to
// XSessionSearch to indicate which matchmaking query to run.
//
#define SESSION_MATCH_QUERY_PLAYER_MATCH 0
//
// Gamer pictures
//
// These ids are passed as the dwPictureId parameter to XUserAwardGamerTile.
//
#ifdef __cplusplus
}
#endif
#endif // __THE_ORANGE_BOX_SPA_H__

View File

@ -0,0 +1,45 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef IFILESYSTEMOPENDIALOG_H
#define IFILESYSTEMOPENDIALOG_H
#ifdef _WIN32
#pragma once
#endif
#define FILESYSTEMOPENDIALOG_VERSION "FileSystemOpenDlg003"
class IFileSystem;
abstract_class IFileSystemOpenDialog
{
public:
// You must call this first to set the hwnd.
virtual void Init( CreateInterfaceFn factory, void *parentHwnd ) = 0;
// Call this to free the dialog.
virtual void Release() = 0;
// Use these to configure the dialog.
virtual void AddFileMask( const char *pMask ) = 0;
virtual void SetInitialDir( const char *pDir, const char *pPathID = NULL ) = 0;
virtual void SetFilterMdlAndJpgFiles( bool bFilter ) = 0;
virtual void GetFilename( char *pOut, int outLen ) const = 0; // Get the filename they chose.
// Call this to make the dialog itself. Returns true if they clicked OK and false
// if they canceled it.
virtual bool DoModal() = 0;
// This uses the standard windows file open dialog.
virtual bool DoModal_WindowsDialog() = 0;
};
#endif // IFILESYSTEMOPENDIALOG_H

27
common/randoverride.cpp Normal file
View File

@ -0,0 +1,27 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB)
#include "stdlib.h"
#include "vstdlib/random.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#ifdef _LINUX
#define __cdecl
#endif
void __cdecl srand(unsigned int)
{
}
int __cdecl rand()
{
return RandomInt( 0, 0x7fff );
}
#endif // !_STATIC_LINKED || _SHARED_LIB

3133
common/studiobyteswap.cpp Normal file

File diff suppressed because it is too large Load Diff

38
common/studiobyteswap.h Normal file
View File

@ -0,0 +1,38 @@
//========= Copyright © 1996-2006, Valve LLC, All rights reserved. ============
//
// Purpose: StudioMDL byteswapping functions.
//
// $NoKeywords: $
//=============================================================================
#ifndef STUDIOBYTESWAP_H
#define STUDIOBYTESWAP_H
#if defined(_WIN32)
#pragma once
#endif
#include "byteswap.h"
struct studiohdr_t;
class IPhysicsCollision;
namespace StudioByteSwap
{
typedef bool (*CompressFunc_t)( const void *pInput, int inputSize, void **pOutput, int *pOutputSize );
//void SetTargetBigEndian( bool bigEndian );
void ActivateByteSwapping( bool bActivate );
void SourceIsNative( bool bActivate );
void SetVerbose( bool bVerbose );
void SetCollisionInterface( IPhysicsCollision *pPhysicsCollision );
int ByteswapStudioFile( const char *pFilename, void *pOutBase, const void *pFileBase, int fileSize, studiohdr_t *pHdr, CompressFunc_t pCompressFunc = NULL );
int ByteswapPHY( void *pOutBase, const void *pFileBase, int fileSize );
int ByteswapANI( studiohdr_t* pHdr, void *pOutBase, const void *pFileBase, int filesize );
int ByteswapVVD( void *pOutBase, const void *pFileBase, int fileSize );
int ByteswapVTX( void *pOutBase, const void *pFileBase, int fileSize );
int ByteswapMDL( void *pOutBase, const void *pFileBase, int fileSize );
#define BYTESWAP_ALIGNMENT_PADDING 4096
}
#endif // STUDIOBYTESWAP_H

236
common/xbox/xboxstubs.h Normal file
View File

@ -0,0 +1,236 @@
//========= Copyright © 1996-2004, Valve LLC, All rights reserved. ============
//
// Purpose: Win32 replacements for XBox.
//
//=============================================================================
#if !defined( XBOXSTUBS_H ) && !defined( _X360 )
#define XBOXSTUBS_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
// Content creation/open flags
#define XCONTENTFLAG_NONE 0x00
#define XCONTENTFLAG_CREATENEW 0x00
#define XCONTENTFLAG_CREATEALWAYS 0x00
#define XCONTENTFLAG_OPENEXISTING 0x00
#define XCONTENTFLAG_OPENALWAYS 0x00
#define XCONTENTFLAG_TRUNCATEEXISTING 0x00
// Content attributes
#define XCONTENTFLAG_NOPROFILE_TRANSFER 0x00
#define XCONTENTFLAG_NODEVICE_TRANSFER 0x00
#define XCONTENTFLAG_STRONG_SIGNED 0x00
#define XCONTENTFLAG_ALLOWPROFILE_TRANSFER 0x00
#define XCONTENTFLAG_MOVEONLY_TRANSFER 0x00
// Console device ports
#define XDEVICE_PORT0 0
#define XDEVICE_PORT1 1
#define XDEVICE_PORT2 2
#define XDEVICE_PORT3 3
#define XUSER_MAX_COUNT 4
#define XUSER_INDEX_NONE 0x000000FE
#define XBX_CLR_DEFAULT 0xFF000000
#define XBX_CLR_WARNING 0x0000FFFF
#define XBX_CLR_ERROR 0x000000FF
#define XBOX_MINBORDERSAFE 0
#define XBOX_MAXBORDERSAFE 0
typedef enum
{
XK_NULL,
XK_BUTTON_UP,
XK_BUTTON_DOWN,
XK_BUTTON_LEFT,
XK_BUTTON_RIGHT,
XK_BUTTON_START,
XK_BUTTON_BACK,
XK_BUTTON_STICK1,
XK_BUTTON_STICK2,
XK_BUTTON_A,
XK_BUTTON_B,
XK_BUTTON_X,
XK_BUTTON_Y,
XK_BUTTON_LEFT_SHOULDER,
XK_BUTTON_RIGHT_SHOULDER,
XK_BUTTON_LTRIGGER,
XK_BUTTON_RTRIGGER,
XK_STICK1_UP,
XK_STICK1_DOWN,
XK_STICK1_LEFT,
XK_STICK1_RIGHT,
XK_STICK2_UP,
XK_STICK2_DOWN,
XK_STICK2_LEFT,
XK_STICK2_RIGHT,
XK_MAX_KEYS,
} xKey_t;
//typedef enum
//{
// XVRB_NONE, // off
// XVRB_ERROR, // fatal error
// XVRB_ALWAYS, // no matter what
// XVRB_WARNING, // non-fatal warnings
// XVRB_STATUS, // status reports
// XVRB_ALL,
//} xverbose_e;
typedef unsigned short WORD;
#ifndef _LINUX
typedef unsigned long DWORD;
typedef void* HANDLE;
#endif
#ifdef _LINUX
typedef int32 COLORREF;
#endif
#ifndef INVALID_HANDLE_VALUE
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
#endif
// typedef struct {
// IN_ADDR ina; // IP address (zero if not static/DHCP)
// IN_ADDR inaOnline; // Online IP address (zero if not online)
// WORD wPortOnline; // Online port
// BYTE abEnet[6]; // Ethernet MAC address
// BYTE abOnline[20]; // Online identification
// } XNADDR;
typedef int XNADDR;
typedef uint64 XUID;
typedef struct {
BYTE ab[8]; // xbox to xbox key identifier
} XNKID;
typedef struct {
BYTE ab[16]; // xbox to xbox key exchange key
} XNKEY;
typedef struct _XSESSION_INFO
{
XNKID sessionID; // 8 bytes
XNADDR hostAddress; // 36 bytes
XNKEY keyExchangeKey; // 16 bytes
} XSESSION_INFO, *PXSESSION_INFO;
typedef struct _XUSER_DATA
{
BYTE type;
union
{
int nData; // XUSER_DATA_TYPE_INT32
int64 i64Data; // XUSER_DATA_TYPE_INT64
double dblData; // XUSER_DATA_TYPE_DOUBLE
struct // XUSER_DATA_TYPE_UNICODE
{
uint cbData; // Includes null-terminator
char * pwszData;
} string;
float fData; // XUSER_DATA_TYPE_FLOAT
struct // XUSER_DATA_TYPE_BINARY
{
uint cbData;
char * pbData;
} binary;
};
} XUSER_DATA, *PXUSER_DATA;
typedef struct _XUSER_PROPERTY
{
DWORD dwPropertyId;
XUSER_DATA value;
} XUSER_PROPERTY, *PXUSER_PROPERTY;
typedef struct _XUSER_CONTEXT
{
DWORD dwContextId;
DWORD dwValue;
} XUSER_CONTEXT, *PXUSER_CONTEXT;
typedef struct _XSESSION_SEARCHRESULT
{
XSESSION_INFO info;
DWORD dwOpenPublicSlots;
DWORD dwOpenPrivateSlots;
DWORD dwFilledPublicSlots;
DWORD dwFilledPrivateSlots;
DWORD cProperties;
DWORD cContexts;
PXUSER_PROPERTY pProperties;
PXUSER_CONTEXT pContexts;
} XSESSION_SEARCHRESULT, *PXSESSION_SEARCHRESULT;
typedef struct _XSESSION_SEARCHRESULT_HEADER
{
DWORD dwSearchResults;
XSESSION_SEARCHRESULT *pResults;
} XSESSION_SEARCHRESULT_HEADER, *PXSESSION_SEARCHRESULT_HEADER;
typedef struct _XSESSION_REGISTRANT
{
uint64 qwMachineID;
DWORD bTrustworthiness;
DWORD bNumUsers;
XUID *rgUsers;
} XSESSION_REGISTRANT;
typedef struct _XSESSION_REGISTRATION_RESULTS
{
DWORD wNumRegistrants;
XSESSION_REGISTRANT *rgRegistrants;
} XSESSION_REGISTRATION_RESULTS, *PXSESSION_REGISTRATION_RESULTS;
typedef struct {
BYTE bFlags;
BYTE bReserved;
WORD cProbesXmit;
WORD cProbesRecv;
WORD cbData;
BYTE * pbData;
WORD wRttMinInMsecs;
WORD wRttMedInMsecs;
DWORD dwUpBitsPerSec;
DWORD dwDnBitsPerSec;
} XNQOSINFO;
typedef struct {
uint cxnqos;
uint cxnqosPending;
XNQOSINFO axnqosinfo[1];
} XNQOS;
#define XSESSION_CREATE_HOST 0
#define XUSER_DATA_TYPE_INT32 0
#define XSESSION_CREATE_USES_ARBITRATION 0
#define XNET_QOS_LISTEN_ENABLE 0
#define XNET_QOS_LISTEN_DISABLE 0
#define XNET_QOS_LISTEN_SET_DATA 0
FORCEINLINE void XBX_ProcessEvents() {}
FORCEINLINE unsigned int XBX_GetSystemTime() { return 0; }
FORCEINLINE int XBX_GetPrimaryUserId() { return 0; }
FORCEINLINE void XBX_SetPrimaryUserId( DWORD idx ) {}
FORCEINLINE int XBX_GetStorageDeviceId() { return 0; }
FORCEINLINE void XBX_SetStorageDeviceId( DWORD idx ) {}
FORCEINLINE const char *XBX_GetLanguageString() { return ""; }
FORCEINLINE bool XBX_IsLocalized() { return false; }
#define XCONTENT_MAX_DISPLAYNAME_LENGTH 128
#define XCONTENT_MAX_FILENAME_LENGTH 42
#define XBX_INVALID_STORAGE_ID ((DWORD) -1)
#define XBX_STORAGE_DECLINED ((DWORD) -2)
#endif // XBOXSTUBS_H

949
devtools/bin/fxc_prep.pl Normal file
View File

@ -0,0 +1,949 @@
BEGIN {use File::Basename; push @INC, dirname($0); }
require "valve_perl_helpers.pl";
sub ReadInputFile
{
local( $filename ) = shift;
local( *INPUT );
local( @output );
open INPUT, "<$filename" || die;
local( $line );
local( $linenum ) = 1;
while( $line = <INPUT> )
{
# print "LINE: $line";
# $line =~ s/\n//g;
# local( $postfix ) = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
# $postfix .= "; LINEINFO($filename)($linenum)\n";
if( $line =~ m/\#include\s+\"(.*)\"/i )
{
push @output, &ReadInputFile( $1 );
}
else
{
# push @output, $line . $postfix;
push @output, $line;
}
$linenum++;
}
close INPUT;
# print "-----------------\n";
# print @output;
# print "-----------------\n";
return @output;
}
$dynamic_compile = defined $ENV{"dynamic_shaders"} && $ENV{"dynamic_shaders"} != 0;
$generateListingFile = 0;
$spewCombos = 0;
@startTimes = times;
$startTime = time;
$g_produceCppClasses = 1;
$g_produceCompiledVcs = 1;
while( 1 )
{
$fxc_filename = shift;
if( $fxc_filename =~ m/-source/ )
{
shift;
}
elsif( $fxc_filename =~ m/-nv3x/i )
{
$nvidia = 1;
}
elsif( $fxc_filename =~ m/-ps20a/i )
{
$ps2a = 1;
}
elsif( $fxc_filename =~ m/-x360/i )
{
# enable x360
$g_x360 = 1;
}
elsif( $fxc_filename =~ m/-novcs/i )
{
$g_produceCompiledVcs = 0;
}
elsif( $fxc_filename =~ m/-nocpp/i )
{
$g_produceCppClasses = 0;
}
else
{
last;
}
}
$argstring = $fxc_filename;
$fxc_basename = $fxc_filename;
$fxc_basename =~ s/^.*-----//;
$fxc_filename =~ s/-----.*$//;
$debug = 0;
$forcehalf = 0;
sub ToUpper
{
local( $in ) = shift;
$in =~ tr/a-z/A-Z/;
return $in;
}
sub CreateCCodeToSpewDynamicCombo
{
local( $out ) = "";
$out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename dynamic index\" );\n";
$out .= "\t\tchar tmp[128];\n";
$out .= "\t\tint shaderID = ";
local( $scale ) = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
local( $name ) = @dynamicDefineNames[$i];
local( $varname ) = "m_n" . $name;
$out .= "( $scale * $varname ) + ";
$scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
$out .= "0;\n";
if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
{
$out .= "\t\tint nCombo = shaderID;\n";
}
my $type = GetShaderType( $fxc_filename );
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % ";
$out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
$out .= ";\n";
$out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n";
$out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]";
$out .= "=\" );\n";
$out .= "\t\tOutputDebugString( tmp );\n";
$out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
$out .= "\n";
}
$out .= "\t\tOutputDebugString( \"\\n\" );\n";
return $out;
}
sub CreateCCodeToSpewStaticCombo
{
local( $out ) = "";
$out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename static index\" );\n";
$out .= "\t\tchar tmp[128];\n";
$out .= "\t\tint shaderID = ";
local( $scale ) = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
local( $name ) = @staticDefineNames[$i];
local( $varname ) = "m_n" . $name;
$out .= "( $scale * $varname ) + ";
$scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
}
$out .= "0;\n";
# $out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n";
# $out .= "\t\tOutputDebugString( tmp );\n\n";
if( scalar( @staticDefineNames ) + scalar( @staticDefineNames ) > 0 )
{
$out .= "\t\tint nCombo = shaderID;\n";
}
my $type = GetShaderType( $fxc_filename );
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
$out .= "\t\tint n$staticDefineNames[$i] = nCombo % ";
$out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
$out .= ";\n";
$out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n";
$out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]";
$out .= "=\" );\n";
$out .= "\t\tOutputDebugString( tmp );\n";
$out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n";
$out .= "\n";
}
$out .= "\t\tOutputDebugString( \"\\n\" );\n";
return $out;
}
sub WriteHelperVar
{
local( $name ) = shift;
local( $min ) = shift;
local( $max ) = shift;
local( $varname ) = "m_n" . $name;
local( $boolname ) = "m_b" . $name;
push @outputHeader, "private:\n";
push @outputHeader, "\tint $varname;\n";
push @outputHeader, "#ifdef _DEBUG\n";
push @outputHeader, "\tbool $boolname;\n";
push @outputHeader, "#endif\n";
push @outputHeader, "public:\n";
# int version of set function
push @outputHeader, "\tvoid Set" . $name . "( int i )\n";
push @outputHeader, "\t{\n";
push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n";
push @outputHeader, "\t\t$varname = i;\n";
push @outputHeader, "#ifdef _DEBUG\n";
push @outputHeader, "\t\t$boolname = true;\n";
push @outputHeader, "#endif\n";
push @outputHeader, "\t}\n";
# bool version of set function
push @outputHeader, "\tvoid Set" . $name . "( bool i )\n";
push @outputHeader, "\t{\n";
# push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n";
push @outputHeader, "\t\t$varname = i ? 1 : 0;\n";
push @outputHeader, "#ifdef _DEBUG\n";
push @outputHeader, "\t\t$boolname = true;\n";
push @outputHeader, "#endif\n";
push @outputHeader, "\t}\n";
}
sub WriteStaticBoolExpression
{
local( $prefix ) = shift;
local( $operator ) = shift;
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
if( $i )
{
push @outputHeader, " $operator ";
}
local( $name ) = @staticDefineNames[$i];
local( $boolname ) = "m_b" . $name;
push @outputHeader, "$prefix$boolname";
}
push @outputHeader, ";\n";
}
sub WriteDynamicBoolExpression
{
local( $prefix ) = shift;
local( $operator ) = shift;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
if( $i )
{
push @outputHeader, " $operator ";
}
local( $name ) = @dynamicDefineNames[$i];
local( $boolname ) = "m_b" . $name;
push @outputHeader, "$prefix$boolname";
}
push @outputHeader, ";\n";
}
sub WriteDynamicHelperClasses
{
local( $basename ) = $fxc_basename;
$basename =~ tr/A-Z/a-z/;
local( $classname ) = $basename . "_Dynamic_Index";
push @outputHeader, "class $classname\n";
push @outputHeader, "{\n";
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$name = $dynamicDefineNames[$i];
$min = $dynamicDefineMin[$i];
$max = $dynamicDefineMax[$i];
&WriteHelperVar( $name, $min, $max );
}
push @outputHeader, "public:\n";
# push @outputHeader, "void SetPixelShaderIndex( IShaderAPI *pShaderAPI ) { pShaderAPI->SetPixelShaderIndex( GetIndex() ); }\n";
push @outputHeader, "\t$classname()\n";
push @outputHeader, "\t{\n";
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
local( $name ) = @dynamicDefineNames[$i];
local( $boolname ) = "m_b" . $name;
local( $varname ) = "m_n" . $name;
push @outputHeader, "#ifdef _DEBUG\n";
push @outputHeader, "\t\t$boolname = false;\n";
push @outputHeader, "#endif // _DEBUG\n";
push @outputHeader, "\t\t$varname = 0;\n";
}
push @outputHeader, "\t}\n";
push @outputHeader, "\tint GetIndex()\n";
push @outputHeader, "\t{\n";
push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n";
foreach $skip (@perlskipcodeindividual)
{
# can't do this static and dynamic can see each other.
# $skip =~ s/\$/m_n/g;
# $skip =~ s/defined//g;
# push @outputHeader, "\t\tAssert( !( $skip ) );\n";
# print "\t\tAssert( !( $skip ) );\n";
}
push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n";
push @outputHeader, "#ifdef _DEBUG\n";
if( scalar( @dynamicDefineNames ) > 0 )
{
push @outputHeader, "\t\tbool bAllDynamicVarsDefined = ";
WriteDynamicBoolExpression( "", "&&" );
}
if( scalar( @dynamicDefineNames ) > 0 )
{
push @outputHeader, "\t\tAssert( bAllDynamicVarsDefined );\n";
}
push @outputHeader, "#endif // _DEBUG\n";
if( $spewCombos && scalar( @dynamicDefineNames ) )
{
push @outputHeader, &CreateCCodeToSpewDynamicCombo();
}
push @outputHeader, "\t\treturn ";
local( $scale ) = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
local( $name ) = @dynamicDefineNames[$i];
local( $varname ) = "m_n" . $name;
push @outputHeader, "( $scale * $varname ) + ";
$scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
push @outputHeader, "0;\n";
push @outputHeader, "\t}\n";
push @outputHeader, "};\n";
push @outputHeader, "\#define shaderDynamicTest_" . $basename . " ";
my $prefix;
my $shaderType = &GetShaderType( $fxc_filename );
if( $shaderType =~ m/^vs/i )
{
$prefix = "vsh_";
}
else
{
$prefix = "psh_";
}
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
local( $name ) = @dynamicDefineNames[$i];
push @outputHeader, $prefix . "forgot_to_set_dynamic_" . $name . " + ";
}
push @outputHeader, "0\n";
}
sub WriteStaticHelperClasses
{
local( $basename ) = $fxc_basename;
$basename =~ tr/A-Z/a-z/;
local( $classname ) = $basename . "_Static_Index";
push @outputHeader, "#include \"shaderlib/cshader.h\"\n";
push @outputHeader, "class $classname\n";
push @outputHeader, "{\n";
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
$name = $staticDefineNames[$i];
$min = $staticDefineMin[$i];
$max = $staticDefineMax[$i];
&WriteHelperVar( $name, $min, $max );
}
push @outputHeader, "public:\n";
# push @outputHeader, "void SetShaderIndex( IShaderShadow *pShaderShadow ) { pShaderShadow->SetPixelShaderIndex( GetIndex() ); }\n";
push @outputHeader, "\t$classname( )\n";
push @outputHeader, "\t{\n";
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
local( $name ) = @staticDefineNames[$i];
local( $boolname ) = "m_b" . $name;
local( $varname ) = "m_n" . $name;
if ( length( $staticDefineInit{$name} ) )
{
push @outputHeader, "#ifdef _DEBUG\n";
push @outputHeader, "\t\t$boolname = true;\n";
push @outputHeader, "#endif // _DEBUG\n";
push @outputHeader, "\t\t$varname = $staticDefineInit{$name};\n";
}
else
{
push @outputHeader, "#ifdef _DEBUG\n";
push @outputHeader, "\t\t$boolname = false;\n";
push @outputHeader, "#endif // _DEBUG\n";
push @outputHeader, "\t\t$varname = 0;\n";
}
}
push @outputHeader, "\t}\n";
push @outputHeader, "\tint GetIndex()\n";
push @outputHeader, "\t{\n";
push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n";
foreach $skip (@perlskipcodeindividual)
{
$skip =~ s/\$/m_n/g;
# push @outputHeader, "\t\tAssert( !( $skip ) );\n";
}
push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n";
push @outputHeader, "#ifdef _DEBUG\n";
if( scalar( @staticDefineNames ) > 0 )
{
push @outputHeader, "\t\tbool bAllStaticVarsDefined = ";
WriteStaticBoolExpression( "", "&&" );
}
if( scalar( @staticDefineNames ) > 0 )
{
push @outputHeader, "\t\tAssert( bAllStaticVarsDefined );\n";
}
push @outputHeader, "#endif // _DEBUG\n";
if( $spewCombos && scalar( @staticDefineNames ) )
{
push @outputHeader, &CreateCCodeToSpewStaticCombo();
}
push @outputHeader, "\t\treturn ";
local( $scale ) = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
local( $name ) = @staticDefineNames[$i];
local( $varname ) = "m_n" . $name;
push @outputHeader, "( $scale * $varname ) + ";
$scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
}
push @outputHeader, "0;\n";
push @outputHeader, "\t}\n";
push @outputHeader, "};\n";
push @outputHeader, "\#define shaderStaticTest_" . $basename . " ";
my $prefix;
my $shaderType = &GetShaderType( $fxc_filename );
if( $shaderType =~ m/^vs/i )
{
$prefix = "vsh_";
}
else
{
$prefix = "psh_";
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
local( $name ) = @staticDefineNames[$i];
push @outputHeader, $prefix . "forgot_to_set_static_" . $name . " + " unless (length($staticDefineInit{$name} ));
}
push @outputHeader, "0\n";
}
sub GetNewMainName
{
local( $shadername ) = shift;
local( $combo ) = shift;
local( $i );
$shadername =~ s/\./_/g;
local( $name ) = $shadername;
for( $i = 0; $i < scalar( @defineNames ); $i++ )
{
local( $val ) = ( $combo % ( $defineMax[$i] - $defineMin[$i] + 1 ) ) + $defineMin[$i];
$name .= "_" . $defineNames[$i] . "_" . $val;
$combo = $combo / ( $defineMax[$i] - $defineMin[$i] + 1 );
}
# return $name;
return "main";
}
sub RenameMain
{
local( $shadername ) = shift;
local( $combo ) = shift;
local( $name ) = &GetNewMainName( $shadername, $combo );
return "/Dmain=$name /E$name ";
}
sub GetShaderType
{
local( $shadername ) = shift; # hack - use global variables
$shadername = $fxc_basename;
if( $shadername =~ m/ps30/i )
{
if( $debug )
{
return "ps_3_sw";
}
else
{
return "ps_3_0";
}
}
elsif( $shadername =~ m/ps20b/i )
{
return "ps_2_b";
}
elsif( $shadername =~ m/ps20/i )
{
if( $debug )
{
return "ps_2_sw";
}
else
{
if( $ps2a )
{
return "ps_2_a";
}
else
{
return "ps_2_0";
}
}
}
elsif( $shadername =~ m/ps14/i )
{
return "ps_1_4";
}
elsif( $shadername =~ m/ps11/i )
{
return "ps_1_1";
}
elsif( $shadername =~ m/vs30/i )
{
if( $debug )
{
return "vs_3_sw";
}
else
{
return "vs_3_0";
}
}
elsif( $shadername =~ m/vs20/i )
{
if( $debug )
{
return "vs_2_sw";
}
else
{
return "vs_2_0";
}
}
elsif( $shadername =~ m/vs14/i )
{
return "vs_1_1";
}
elsif( $shadername =~ m/vs11/i )
{
return "vs_1_1";
}
else
{
die "\n\nSHADERNAME = $shadername\n\n";
}
}
sub CalcNumCombos
{
local( $i, $numCombos );
$numCombos = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
$numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
}
return $numCombos;
}
sub CalcNumDynamicCombos
{
local( $i, $numCombos );
$numCombos = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
return $numCombos;
}
sub CreateCFuncToCreateCompileCommandLine
{
local( $out ) = "";
$out .= "\t\tOutputDebugString( \"compiling src:$fxc_filename vcs:$fxc_basename \" );\n";
$out .= "\t\tchar tmp[128];\n";
$out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n";
$out .= "\t\tOutputDebugString( tmp );\n";
$out .= "\t\tstatic PrecompiledShaderByteCode_t byteCode;\n";
if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
{
$out .= "\t\tint nCombo = shaderID;\n";
}
# $out .= "\tvoid BuildCompileCommandLine( int nCombo, char *pResult, int maxLength )\n";
# $out .= "\t{\n";
$out .= "\t\tD3DXMACRO ";
$out .= "defineMacros";
$out .= "[";
$out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) + 1; # add 1 for null termination
$out .= "];\n";
if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
{
$out .= "\t\tchar tmpStringBuf[1024];\n";
$out .= "\t\tchar *pTmpString = tmpStringBuf;\n\n";
}
local( $i );
my $type = GetShaderType( $fxc_filename );
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % ";
$out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
$out .= " );\n";
$out .= "\t\tdefineMacros";
$out .= "[";
$out .= $i;
$out .= "]";
$out .= "\.Name = ";
$out .= "\"$dynamicDefineNames[$i]\";\n";
$out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % ";
$out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
$out .= ";\n";
$out .= "\t\tUNUSED( n$dynamicDefineNames[$i] );\n";
$out .= "\t\tdefineMacros";
$out .= "[";
$out .= $i;
$out .= "]";
$out .= "\.Definition = ";
$out .= "pTmpString;\n";
$out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n";
$out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n";
$out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]";
$out .= "=\" );\n";
$out .= "\t\tOutputDebugString( tmp );\n";
$out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
$out .= "\n";
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
$out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % ";
$out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
$out .= " );\n";
$out .= "\t\tdefineMacros";
$out .= "[";
$out .= $i + scalar( @dynamicDefineNames );
$out .= "]";
$out .= "\.Name = ";
$out .= "\"$staticDefineNames[$i]\";\n";
$out .= "\t\tint n$staticDefineNames[$i] = nCombo % ";
$out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
$out .= ";\n";
$out .= "\t\tUNUSED( n$staticDefineNames[$i] );\n";
$out .= "\t\tdefineMacros";
$out .= "[";
$out .= $i + scalar( @dynamicDefineNames );
$out .= "]";
$out .= "\.Definition = ";
$out .= "pTmpString;\n";
$out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n";
$out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n";
$out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]";
$out .= "=\" );\n";
$out .= "\t\tOutputDebugString( tmp );\n";
$out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n";
$out .= "\n";
}
$out .= "\t\tOutputDebugString( \"\\n\" );\n";
$cskipcode = $perlskipcode;
$cskipcode =~ s/\$/n/g;
$out .= "\t\tif( $cskipcode )\n\t\t{\n";
$out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n";
$out .= "\t\t\tbyteCode.m_pRawData = blah;\n";
$out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n";
$out .= "\t\t\treturn byteCode;\n";
$out .= "\t\t}\n";
$out .= "\t\t// Must null terminate macros.\n";
$out .= "\t\tdefineMacros[";
$out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames );
$out .= "]";
$out .= ".Name = NULL;\n";
$out .= "\t\tdefineMacros[";
$out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames );
$out .= "]";
$out .= ".Definition = NULL;\n\n";
$out .= "\t\tLPD3DXBUFFER pShader; // NOTE: THESE LEAK!!!\n";
$out .= "\t\tLPD3DXBUFFER pErrorMessages; // NOTE: THESE LEAK!!!\n";
$out .= "\t\tHRESULT hr = D3DXCompileShaderFromFile( \"u:\\\\hl2_e3_2004\\\\src_e3_2004\\\\materialsystem\\\\stdshaders\\\\$fxc_filename\",\n\t\t\tdefineMacros,\n\t\t\tNULL, // LPD3DXINCLUDE \n\t\t\t\"main\",\n\t\t\t\"$type\",\n\t\t\t0, // DWORD Flags\n\t\t\t&pShader,\n\t\t\t&pErrorMessages,\n\t\t\tNULL // LPD3DXCONSTANTTABLE *ppConstantTable\n\t\t\t );\n";
$out .= "\t\tif( hr != D3D_OK )\n";
$out .= "\t\t{\n";
$out .= "\t\t\tconst char *pErrorMessageString = ( const char * )pErrorMessages->GetBufferPointer();\n";
$out .= "\t\t\tOutputDebugString( pErrorMessageString );\n";
$out .= "\t\t\tOutputDebugString( \"\\n\" );\n";
$out .= "\t\t\tAssert( 0 );\n";
$out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n";
$out .= "\t\t\tbyteCode.m_pRawData = blah;\n";
$out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n";
$out .= "\t\t}\n";
$out .= "\t\telse\n";
$out .= "\t\t{\n";
$out .= "\t\t\tbyteCode.m_pRawData = pShader->GetBufferPointer();\n";
$out .= "\t\t\tbyteCode.m_nSizeInBytes = pShader->GetBufferSize();\n";
$out .= "\t\t}\n";
$out .= "\t\treturn byteCode;\n";
return $out;
}
#print "--------\n";
if ( $g_x360 )
{
$fxctmp = "fxctmp9_360_tmp";
}
else
{
$fxctmp = "fxctmp9_tmp";
}
if( !stat $fxctmp )
{
mkdir $fxctmp, 0777 || die $!;
}
# suck in an input file (using includes)
#print "$fxc_filename...";
@fxc = ReadInputFile( $fxc_filename );
# READ THE TOP OF THE FILE TO FIND SHADER COMBOS
foreach $line ( @fxc )
{
$line="" if ($g_x360 && ($line=~/\[PC\]/)); # line marked as [PC] when building for x360
$line="" if (($g_x360 == 0) && ($line=~/\[XBOX\]/)); # line marked as [XBOX] when building for pc
if ( $fxc_basename =~ m/_ps(\d+\w?)$/i )
{
my $psver = $1;
$line="" if (($line =~/\[ps\d+\w?\]/i) && ($line!~/\[ps$psver\]/i)); # line marked for a version of compiler and not what we build
}
if ( $fxc_basename =~ m/_vs(\d+\w?)$/i )
{
my $vsver = $1;
$line="" if (($line =~/\[vs\d+\w?\]/i) && ($line!~/\[vs$vsver\]/i)); # line marked for a version of compiler and not what we build
}
my $init_expr;
$init_expr = $1 if ( $line=~/\[\=([^\]]+)\]/); # parse default init expression for combos
$line=~s/\[[^\[\]]*\]//; # cut out all occurrences of
# square brackets and whatever is
# inside all these modifications
# to the line are seen later when
# processing skips and centroids
next if( $line =~ m/^\s*$/ );
if( $line =~ m/^\s*\/\/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
{
local( $name, $min, $max );
$name = $1;
$min = $2;
$max = $3;
# print STDERR "STATIC: \"$name\" \"$min..$max\"\n";
push @staticDefineNames, $name;
push @staticDefineMin, $min;
push @staticDefineMax, $max;
$staticDefineInit{$name}=$init_expr;
}
elsif( $line =~ m/^\s*\/\/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
{
local( $name, $min, $max );
$name = $1;
$min = $2;
$max = $3;
# print STDERR "DYNAMIC: \"$name\" \"$min..$max\"\n";
push @dynamicDefineNames, $name;
push @dynamicDefineMin, $min;
push @dynamicDefineMax, $max;
}
}
# READ THE WHOLE FILE AND FIND SKIP STATEMENTS
foreach $line ( @fxc )
{
if( $line =~ m/^\s*\/\/\s*SKIP\s*\s*\:\s*(.*)$/ )
{
# print $1 . "\n";
$perlskipcode .= "(" . $1 . ")||";
push @perlskipcodeindividual, $1;
}
}
if( defined $perlskipcode )
{
$perlskipcode .= "0";
$perlskipcode =~ s/\n//g;
}
else
{
$perlskipcode = "0";
}
# READ THE WHOLE FILE AND FIND CENTROID STATEMENTS
foreach $line ( @fxc )
{
if( $line =~ m/^\s*\/\/\s*CENTROID\s*\:\s*TEXCOORD(\d+)\s*$/ )
{
$centroidEnable{$1} = 1;
# print "CENTROID: $1\n";
}
}
if( $spewCombos )
{
push @outputHeader, "#include \"windows.h\"\n";
}
#push @outputHeader, "\#include \"shaderlib\\baseshader.h\"\n";
#push @outputHeader, "IShaderDynamicAPI *CBaseShader::s_pShaderAPI;\n";
# Go ahead an compute the mask of samplers that need to be centroid sampled
$centroidMask = 0;
foreach $centroidRegNum ( keys( %centroidEnable ) )
{
# print "THING: $samplerName $centroidRegNum\n";
$centroidMask += 1 << $centroidRegNum;
}
#printf "0x%x\n", $centroidMask;
$numCombos = &CalcNumCombos();
#print "$numCombos combos\n";
if( $g_produceCompiledVcs && !$dynamic_compile )
{
open FOUT, ">>filelistgen.txt" || die "can't open filelistgen.txt";
print FOUT "**** generated by fxc_prep.pl ****\n";
print FOUT "#BEGIN " . $fxc_basename . "\n";
print FOUT "$fxc_filename" . "\n";
print FOUT "#DEFINES-D:\n";
for( $i = 0; $i < scalar( @dynamicDefineNames ); \$i++ )
{
print FOUT "$dynamicDefineNames[$i]=";
print FOUT $dynamicDefineMin[$i];
print FOUT "..";
print FOUT $dynamicDefineMax[$i];
print FOUT "\n";
}
print FOUT "#DEFINES-S:\n";
for( $i = 0; $i < scalar( @staticDefineNames ); \$i++ )
{
print FOUT "$staticDefineNames[$i]=";
print FOUT $staticDefineMin[$i];
print FOUT "..";
print FOUT $staticDefineMax[$i];
print FOUT "\n";
}
print FOUT "#SKIP:\n";
print FOUT "$perlskipcode\n";
print FOUT "#COMMAND:\n";
# first line
print FOUT "fxc.exe ";
print FOUT "/DTOTALSHADERCOMBOS=$numCombos ";
print FOUT "/DCENTROIDMASK=$centroidMask ";
print FOUT "/DNUMDYNAMICCOMBOS=" . &CalcNumDynamicCombos() . " ";
print FOUT "/DFLAGS=0x0 "; # Nothing here for now.
print FOUT "\n";
#defines go here
# second line
print FOUT &RenameMain( $fxc_filename, $i );
print FOUT "/T" . &GetShaderType( $fxc_filename ) . " ";
print FOUT "/DSHADER_MODEL_" . &ToUpper( &GetShaderType( $fxc_filename ) ) . "=1 ";
if( $nvidia )
{
print FOUT "/DNV3X=1 "; # enable NV3X codepath
}
if ( $g_x360 )
{
print FOUT "/D_X360=1 "; # shaders can identify X360 centric code
# print FOUT "/Xbe:2- "; # use the less-broken old back end
}
if( $debug )
{
print FOUT "/Od "; # disable optimizations
print FOUT "/Zi "; # enable debug info
}
# print FOUT "/Zi "; # enable debug info
print FOUT "/nologo ";
# print FOUT "/Fhtmpshader.h ";
print FOUT "/Foshader.o ";
print FOUT "$fxc_filename";
print FOUT ">output.txt 2>&1";
print FOUT "\n";
#end of command line
print FOUT "#END\n";
print FOUT "**** end ****\n";
close FOUT;
}
if ( $g_produceCppClasses )
{
# Write out the C++ helper class for picking shader combos
&WriteStaticHelperClasses();
&WriteDynamicHelperClasses();
my $incfilename = "$fxctmp\\$fxc_basename" . ".inc";
&WriteFile( $incfilename, join( "", @outputHeader ) );
}
if( $generateListingFile )
{
my $listFileName = "$fxctmp/$fxc_basename" . ".lst";
print "writing $listFileName\n";
if( !open FILE, ">$listFileName" )
{
die;
}
print FILE @listingOutput;
close FILE;
}
@endTimes = times;
$endTime = time;
#printf "Elapsed user time: %.2f seconds!\n", $endTimes[0] - $startTimes[0];
#printf "Elapsed system time: %.2f seconds!\n", $endTimes[1] - $startTimes[1];
#printf "Elapsed child user time: %.2f seconds!\n", $endTimes[2] - $startTimes[2];
#printf "Elapsed child system time: %.2f seconds!\n", $endTimes[3] - $startTimes[3];
#printf "Elapsed total time: %.2f seconds!\n", $endTime - $startTime;

333
devtools/bin/psh_prep.pl Normal file
View File

@ -0,0 +1,333 @@
use String::CRC32;
BEGIN {use File::Basename; push @INC, dirname($0); }
require "valve_perl_helpers.pl";
sub BuildDefineOptions
{
local( $output );
local( $combo ) = shift;
local( $i );
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
local( $val ) = ( $combo % ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) ) + $dynamicDefineMin[$i];
$output .= "/D$dynamicDefineNames[$i]=$val ";
$combo = $combo / ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 );
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
local( $val ) = ( $combo % ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) ) + $staticDefineMin[$i];
$output .= "/D$staticDefineNames[$i]=$val ";
$combo = $combo / ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 );
}
return $output;
}
sub CalcNumCombos
{
local( $i, $numCombos );
$numCombos = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
{
$numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
}
return $numCombos;
}
sub CalcNumDynamicCombos
{
local( $i, $numCombos );
$numCombos = 1;
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
{
$numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
}
return $numCombos;
}
$g_dx9 = 1;
while( 1 )
{
$psh_filename = shift;
if( $psh_filename =~ m/-source/ )
{
$g_SourceDir = shift;
}
elsif( $psh_filename =~ m/-x360/ )
{
$g_x360 = 1;
}
else
{
last;
}
}
$psh_filename =~ s/-----.*$//;
# Get the shader binary version number from a header file.
open FILE, "<$g_SourceDir\\public\\materialsystem\\shader_vcs_version.h" || die;
while( $line = <FILE> )
{
if( $line =~ m/^\#define\s+SHADER_VCS_VERSION_NUMBER\s+(\d+)\s*$/ )
{
$shaderVersion = $1;
last;
}
}
if( !defined $shaderVersion )
{
die "couldn't get shader version from shader_vcs_version.h";
}
close FILE;
local( @staticDefineNames );
local( @staticDefineMin );
local( @staticDefineMax );
local( @dynamicDefineNames );
local( @dynamicDefineMin );
local( @dynamicDefineMax );
# Parse the combos.
open PSH, "<$psh_filename";
while( <PSH> )
{
last if( !m,^;, );
s,^;\s*,,;
if( m/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
{
local( $name, $min, $max );
$name = $1;
$min = $2;
$max = $3;
# print "\"STATIC: $name\" \"$min..$max\"\n";
if (/\[(.*)\]/)
{
$platforms=$1;
next if ( ($g_x360) && (!($platforms=~/XBOX/i)) );
next if ( (!$g_x360) && (!($platforms=~/PC/i)) );
}
push @staticDefineNames, $name;
push @staticDefineMin, $min;
push @staticDefineMax, $max;
}
elsif( m/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
{
local( $name, $min, $max );
$name = $1;
$min = $2;
$max = $3;
# print "\"DYNAMIC: $name\" \"$min..$max\"\n";
if (/\[(.*)\]/)
{
$platforms=$1;
next if ( ($g_x360) && (!($platforms=~/XBOX/i)) );
next if ( (!$g_x360) && (!($platforms=~/PC/i)) );
}
push @dynamicDefineNames, $name;
push @dynamicDefineMin, $min;
push @dynamicDefineMax, $max;
}
}
close PSH;
$numCombos = &CalcNumCombos();
$numDynamicCombos = &CalcNumDynamicCombos();
print "$psh_filename\n";
#print "$numCombos combos\n";
#print "$numDynamicCombos dynamic combos\n";
if( $g_x360 )
{
$pshtmp = "pshtmp9_360";
}
elsif( $g_dx9 )
{
$pshtmp = "pshtmp9";
}
else
{
$pshtmp = "pshtmp8";
}
$basename = $psh_filename;
$basename =~ s/\.psh$//i;
for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ )
{
my $tempFilename = "shader$shaderCombo.o";
unlink $tempFilename;
if( $g_x360 )
{
$cmd = "$g_SourceDir\\x360xdk\\bin\\win32\\psa /D_X360=1 /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL";
}
else
{
$cmd = "$g_SourceDir\\dx9sdk\\utilities\\psa /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL";
}
if( !stat $pshtmp )
{
mkdir $pshtmp, 0777 || die $!;
}
# print $cmd . "\n";
system $cmd || die $!;
# Make sure a file got generated because sometimes the die above won't happen on compile errors.
my $filesize = (stat $tempFilename)[7];
if ( !$filesize )
{
die "Error compiling shader$shaderCombo.o";
}
push @outputHeader, @hdr;
}
$basename =~ s/\.fxc//gi;
push @outputHeader, "static PrecompiledShaderByteCode_t " . $basename . "_pixel_shaders[" . $numCombos . "] = \n";
push @outputHeader, "{\n";
local( $j );
for( $j = 0; $j < $numCombos; $j++ )
{
local( $thing ) = "pixelShader_" . $basename . "_" . $j;
push @outputHeader, "\t{ " . "$thing, sizeof( $thing ) },\n";
}
push @outputHeader, "};\n";
push @outputHeader, "struct $basename" . "PixelShader_t : public PrecompiledShader_t\n";
push @outputHeader, "{\n";
push @outputHeader, "\t$basename" . "PixelShader_t()\n";
push @outputHeader, "\t{\n";
push @outputHeader, "\t\tm_nFlags = 0;\n";
push @outputHeader, "\t\tm_pByteCode = " . $basename . "_pixel_shaders;\n";
push @outputHeader, "\t\tm_nShaderCount = $numCombos;\n";
#push @outputHeader, "\t\tm_nDynamicCombos = m_nShaderCount;\n";
push @outputHeader, "\t\t// NOTE!!! psh_prep.pl shaders are always static combos!\n";
push @outputHeader, "\t\tm_nDynamicCombos = 1;\n";
push @outputHeader, "\t\tm_pName = \"$basename\";\n";
if( $basename =~ /vs\d\d/ ) # hack
{
push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_VERTEX_SHADER, this );\n";
}
else
{
push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_PIXEL_SHADER, this );\n";
}
push @outputHeader, "\t}\n";
push @outputHeader, "\tvirtual const PrecompiledShaderByteCode_t &GetByteCode( int shaderID )\n";
push @outputHeader, "\t{\n";
push @outputHeader, "\t\treturn m_pByteCode[shaderID];\n";
push @outputHeader, "\t}\n";
push @outputHeader, "};\n";
push @outputHeader, "static $basename" . "PixelShader_t $basename" . "_PixelShaderInstance;\n";
&MakeDirHier( "shaders/psh" );
my $vcsName = "";
if( $g_x360 )
{
$vcsName = $basename . ".360.vcs";
}
else
{
$vcsName = $basename . ".vcs";
}
open COMPILEDSHADER, ">shaders/psh/$vcsName" || die;
binmode( COMPILEDSHADER );
#
# Write out the part of the header that we know. . we'll write the rest after writing the object code.
#
#print $numCombos . "\n";
# Pack arguments
my $sInt = "i";
my $uInt = "I";
if ( $g_x360 )
{
# Change arguments to "big endian long"
$sInt = "N";
$uInt = "N";
}
open PSH, "<$psh_filename";
my $crc = crc32( *PSH );
close PSH;
#print STDERR "crc for $psh_filename: $crc\n";
# version
print COMPILEDSHADER pack $sInt, 4;
# totalCombos
print COMPILEDSHADER pack $sInt, $numCombos;
# dynamic combos
print COMPILEDSHADER pack $sInt, $numDynamicCombos;
# flags
print COMPILEDSHADER pack $uInt, 0x0; # nothing here for now.
# centroid mask
print COMPILEDSHADER pack $uInt, 0;
# reference size for diffs
print COMPILEDSHADER pack $uInt, 0;
# crc32 of the source code
print COMPILEDSHADER pack $uInt, $crc;
my $beginningOfDir = tell COMPILEDSHADER;
# Write out a blank directionary. . we'll fill it in later.
for( $i = 0; $i < $numCombos; $i++ )
{
# offset from beginning of file.
print COMPILEDSHADER pack $sInt, 0;
# size
print COMPILEDSHADER pack $sInt, 0;
}
my $startByteCode = tell COMPILEDSHADER;
my @byteCodeStart;
my @byteCodeSize;
# Write out the shader object code.
for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ )
{
my $filename = "shader$shaderCombo\.o";
my $filesize = (stat $filename)[7];
$byteCodeStart[$shaderCombo] = tell COMPILEDSHADER;
$byteCodeSize[$shaderCombo] = $filesize;
open SHADERBYTECODE, "<$filename";
binmode SHADERBYTECODE;
my $bin;
my $numread = read SHADERBYTECODE, $bin, $filesize;
# print "filename: $filename numread: $numread filesize: $filesize\n";
close SHADERBYTECODE;
unlink $filename;
print COMPILEDSHADER $bin;
}
# Seek back to the directory and write it out.
seek COMPILEDSHADER, $beginningOfDir, 0;
for( $i = 0; $i < $numCombos; $i++ )
{
# offset from beginning of file.
print COMPILEDSHADER pack $sInt, $byteCodeStart[$i];
# size
print COMPILEDSHADER pack $sInt, $byteCodeSize[$i];
}
close COMPILEDSHADER;

View File

@ -0,0 +1,305 @@
use String::CRC32;
BEGIN {use File::Basename; push @INC, dirname($0); }
require "valve_perl_helpers.pl";
$dynamic_compile = defined $ENV{"dynamic_shaders"} && $ENV{"dynamic_shaders"} != 0;
$depnum = 0;
$baseSourceDir = ".";
my %dep;
sub GetAsmShaderDependencies_R
{
local( $shadername ) = shift;
local( *SHADER );
open SHADER, "<$shadername";
while( <SHADER> )
{
if( m/^\s*\#\s*include\s+\"(.*)\"/ )
{
# make sure it isn't in there already.
if( !defined( $dep{$1} ) )
{
$dep{$1} = 1;
GetAsmShaderDependencies_R( $1 );
}
}
}
close SHADER;
}
sub GetAsmShaderDependencies
{
local( $shadername ) = shift;
undef %dep;
GetAsmShaderDependencies_R( $shadername );
# local( $i );
# foreach $i ( keys( %dep ) )
# {
# print "$shadername depends on $i\n";
# }
return keys( %dep );
}
sub GetShaderType
{
my $shadername = shift;
my $shadertype;
if( $shadername =~ m/\.vsh/i )
{
$shadertype = "vsh";
}
elsif( $shadername =~ m/\.psh/i )
{
$shadertype = "psh";
}
elsif( $shadername =~ m/\.fxc/i )
{
$shadertype = "fxc";
}
else
{
die;
}
return $shadertype;
}
sub GetShaderSrc
{
my $shadername = shift;
if ( $shadername =~ m/^(.*)-----/i )
{
return $1;
}
else
{
return $shadername;
}
}
sub GetShaderBase
{
my $shadername = shift;
if ( $shadername =~ m/-----(.*)$/i )
{
return $1;
}
else
{
my $shadertype = &GetShaderType( $shadername );
$shadername =~ s/\.$shadertype//i;
return $shadername;
}
}
sub DoAsmShader
{
my $argstring = shift;
my $shadername = &GetShaderSrc( $argstring );
my $shaderbase = &GetShaderBase( $argstring );
my $shadertype = &GetShaderType( $argstring );
my $incfile = "";
if( $shadertype eq "fxc" || $shadertype eq "vsh" )
{
$incfile = $shadertype . "tmp9" . $g_tmpfolder . "\\$shaderbase.inc ";
}
my $vcsfile = $shaderbase . $g_vcsext;
my $bWillCompileVcs = 1;
if( ( $shadertype eq "fxc") && $dynamic_compile )
{
$bWillCompileVcs = 0;
}
if( $shadercrcpass{$argstring} )
{
$bWillCompileVcs = 0;
}
if( $bWillCompileVcs )
{
&output_makefile_line( $incfile . "shaders\\$shadertype\\$vcsfile: $shadername @dep\n") ;
}
else
{
# psh files don't need a rule at this point since they don't have inc files and we aren't compiling a vcs.
if( $shadertype eq "fxc" || $shadertype eq "vsh" )
{
&output_makefile_line( $incfile . ": $shadername @dep\n") ;
}
}
my $x360switch = "";
my $moreswitches = "";
if( !$bWillCompileVcs && $shadertype eq "fxc" )
{
$moreswitches .= "-novcs ";
}
if( $g_x360 )
{
$x360switch = "-x360";
if( $bWillCompileVcs && ( $shaderbase =~ m/_ps20$/i ) )
{
$moreswitches .= "-novcs ";
$bWillCompileVcs = 0;
}
}
# if we are psh and we are compiling the vcs, we don't need this rule.
if( !( $shadertype eq "psh" && !$bWillCompileVcs ) )
{
&output_makefile_line( "\tperl $g_SourceDir\\devtools\\bin\\" . $shadertype . "_prep.pl $moreswitches $x360switch -source \"$g_SourceDir\" $argstring\n") ;
}
if( $bWillCompileVcs )
{
&output_makefile_line( "\techo $shadername>> filestocopy.txt\n") ;
my $dep;
foreach $dep( @dep )
{
&output_makefile_line( "\techo $dep>> filestocopy.txt\n") ;
}
}
&output_makefile_line( "\n") ;
}
if( scalar( @ARGV ) == 0 )
{
die "Usage updateshaders.pl shaderprojectbasename\n\tie: updateshaders.pl stdshaders_dx6\n";
}
$g_x360 = 0;
$g_tmpfolder = "_tmp";
$g_vcsext = ".vcs";
while( 1 )
{
$inputbase = shift;
if( $inputbase =~ m/-source/ )
{
$g_SourceDir = shift;
}
elsif( $inputbase =~ m/-x360/ )
{
$g_x360 = 1;
$g_tmpfolder = "_360_tmp";
$g_vcsext = ".360.vcs";
}
elsif( $inputbase =~ m/-execute/ )
{
$g_execute = 1;
}
elsif( $inputbase =~ m/-nv3x/ )
{
$nv3x = 1;
}
else
{
last;
}
}
my @srcfiles = &LoadShaderListFile( $inputbase );
open MAKEFILE, ">makefile\.$inputbase";
open COPYFILE, ">makefile\.$inputbase\.copy";
open INCLIST, ">inclist.txt";
open VCSLIST, ">vcslist.txt";
# make a default dependency that depends on all of the shaders.
&output_makefile_line( "default: ") ;
foreach $shader ( @srcfiles )
{
my $shadertype = &GetShaderType( $shader );
my $shaderbase = &GetShaderBase( $shader );
my $shadersrc = &GetShaderSrc( $shader );
if( $shadertype eq "fxc" || $shadertype eq "vsh" )
{
# We only generate inc files for fxc and vsh files.
my $incFileName = "$shadertype" . "tmp9" . $g_tmpfolder . "\\" . $shaderbase . "\.inc";
&output_makefile_line( " $incFileName" );
&output_inclist_line( "$incFileName\n" );
}
my $vcsfile = $shaderbase . $g_vcsext;
my $compilevcs = 1;
if( $shadertype eq "fxc" && $dynamic_compile )
{
$compilevcs = 0;
}
if( $g_x360 && ( $shaderbase =~ m/_ps20$/i ) )
{
$compilevcs = 0;
}
if( $compilevcs )
{
my $vcsFileName = "..\\..\\..\\game\\hl2\\shaders\\$shadertype\\$shaderbase" . $g_vcsext;
# We want to check for perforce operations even if the crc matches in the event that a file has been manually reverted and needs to be checked out again.
&output_vcslist_line( "$vcsFileName\n" );
$shadercrcpass{$shader} = &CheckCRCAgainstTarget( $shadersrc, $vcsFileName, 0 );
if( $shadercrcpass{$shader} )
{
$compilevcs = 0;
}
}
if( $compilevcs )
{
&output_makefile_line( " shaders\\$shadertype\\$vcsfile" );
# emit a list of vcs files to copy to the target since we want to build them.
&output_copyfile_line( GetShaderSrc($shader) . "-----" . GetShaderBase($shader) . "\n" );
}
}
&output_makefile_line( "\n\n") ;
# Insert all of our vertex shaders and depencencies
$lastshader = "";
foreach $shader ( @srcfiles )
{
my $currentshader = &GetShaderSrc( $shader );
if ( $lastshader ne $currentshader )
{
$lastshader = $currentshader;
@dep = &GetAsmShaderDependencies( $lastshader );
}
&DoAsmShader( $shader );
}
close VCSLIST;
close INCLIST;
close COPYFILE;
close MAKEFILE;
# nuke the copyfile if it is zero length
if( ( stat "makefile\.$inputbase\.copy" )[7] == 0 )
{
unlink "makefile\.$inputbase\.copy";
}
sub output_makefile_line
{
local ($_)=@_;
print MAKEFILE $_;
}
sub output_copyfile_line
{
local ($_)=@_;
print COPYFILE $_;
}
sub output_vcslist_line
{
local ($_)=@_;
print VCSLIST $_;
}
sub output_inclist_line
{
local ($_)=@_;
print INCLIST $_;
}

1106
devtools/bin/vsh_prep.pl Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Acts exactly like "AnimatedTexture", but ONLY if the texture
// it's working on matches the desired texture to work on.
//
// This assumes that some other proxy will be switching out the textures.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "materialsystem/IMaterialProxy.h"
#include "materialsystem/IMaterialVar.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/ITexture.h"
#include "BaseAnimatedTextureProxy.h"
#include "utlstring.h"
#include <KeyValues.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
class CAnimateSpecificTexture : public CBaseAnimatedTextureProxy
{
private:
CUtlString m_OnlyAnimateOnTexture;
public:
virtual float GetAnimationStartTime( void* pBaseEntity ) { return 0; }
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pC_BaseEntity );
virtual void Release( void ) { delete this; }
};
bool CAnimateSpecificTexture::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
char const* pszAnimateOnTexture = pKeyValues->GetString( "onlyAnimateOnTexture" );
if( !pszAnimateOnTexture )
return false;
m_OnlyAnimateOnTexture.Set( pszAnimateOnTexture );
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
}
void CAnimateSpecificTexture::OnBind( void *pC_BaseEntity )
{
if( FStrEq( m_AnimatedTextureVar->GetTextureValue()->GetName(), m_OnlyAnimateOnTexture ) )
{
CBaseAnimatedTextureProxy::OnBind( pC_BaseEntity );
}
//else do nothing
}
EXPOSE_INTERFACE( CAnimateSpecificTexture, IMaterialProxy, "AnimateSpecificTexture" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,65 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_ENVPROJECTEDTEXTURE_H
#define C_ENVPROJECTEDTEXTURE_H
#ifdef _WIN32
#pragma once
#endif
#include "c_baseentity.h"
#include "basetypes.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class C_EnvProjectedTexture : public C_BaseEntity
{
DECLARE_CLASS( C_EnvProjectedTexture, C_BaseEntity );
public:
DECLARE_CLIENTCLASS();
C_EnvProjectedTexture();
~C_EnvProjectedTexture();
virtual void OnDataChanged( DataUpdateType_t updateType );
void ShutDownLightHandle( void );
virtual void Simulate();
void UpdateLight( bool bForceUpdate );
bool ShadowsEnabled();
float GetFOV();
private:
ClientShadowHandle_t m_LightHandle;
EHANDLE m_hTargetEntity;
bool m_bState;
float m_flLightFOV;
bool m_bEnableShadows;
bool m_bLightOnlyTarget;
bool m_bLightWorld;
bool m_bCameraSpace;
color32 m_cLightColor;
float m_flAmbient;
char m_SpotlightTextureName[ MAX_PATH ];
int m_nSpotlightTextureFrame;
int m_nShadowQuality;
bool m_bCurrentShadow;
public:
C_EnvProjectedTexture *m_pNext;
};
C_EnvProjectedTexture* GetEnvProjectedTextureList();
#endif // C_ENVPROJECTEDTEXTURE_H

View File

@ -0,0 +1,798 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Material Modify control entity.
//
//=============================================================================//
#include "cbase.h"
#include "ProxyEntity.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialVar.h"
#include "materialsystem/ITexture.h"
#include "iviewrender.h"
#include "texture_group_names.h"
#include "BaseAnimatedTextureProxy.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define MATERIAL_MODIFY_STRING_SIZE 255
#define MATERIAL_MODIFY_ANIMATION_UNSET -1
// Must match MaterialModifyControl.cpp
enum MaterialModifyMode_t
{
MATERIAL_MODIFY_MODE_NONE = 0,
MATERIAL_MODIFY_MODE_SETVAR = 1,
MATERIAL_MODIFY_MODE_ANIM_SEQUENCE = 2,
MATERIAL_MODIFY_MODE_FLOAT_LERP = 3,
};
// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
ConVar debug_materialmodifycontrol_client( "debug_materialmodifycontrol_client", "0" );
struct materialanimcommands_t
{
int iFrameStart;
int iFrameEnd;
bool bWrap;
float flFrameRate;
};
struct materialfloatlerpcommands_t
{
int flStartValue;
int flEndValue;
float flTransitionTime;
};
//------------------------------------------------------------------------------
// FIXME: This really should inherit from something more lightweight
//------------------------------------------------------------------------------
class C_MaterialModifyControl : public C_BaseEntity
{
public:
DECLARE_CLASS( C_MaterialModifyControl, C_BaseEntity );
C_MaterialModifyControl();
void OnPreDataChanged( DataUpdateType_t updateType );
void OnDataChanged( DataUpdateType_t updateType );
bool ShouldDraw();
IMaterial *GetMaterial( void ) { return m_pMaterial; }
const char *GetMaterialVariableName( void ) { return m_szMaterialVar; }
const char *GetMaterialVariableValue( void ) { return m_szMaterialVarValue; }
DECLARE_CLIENTCLASS();
// Animated texture and Float Lerp usage
bool HasNewAnimationCommands( void ) { return m_bHasNewAnimationCommands; }
void ClearAnimationCommands( void ) { m_bHasNewAnimationCommands = false; }
// Animated texture usage
void GetAnimationCommands( materialanimcommands_t *pCommands );
// FloatLerp usage
void GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands );
void SetAnimationStartTime( float flTime )
{
m_flAnimationStartTime = flTime;
}
float GetAnimationStartTime( void ) const
{
return m_flAnimationStartTime;
}
MaterialModifyMode_t GetModifyMode( void ) const
{
return ( MaterialModifyMode_t)m_nModifyMode;
}
private:
char m_szMaterialName[MATERIAL_MODIFY_STRING_SIZE];
char m_szMaterialVar[MATERIAL_MODIFY_STRING_SIZE];
char m_szMaterialVarValue[MATERIAL_MODIFY_STRING_SIZE];
IMaterial *m_pMaterial;
bool m_bHasNewAnimationCommands;
// Animation commands from the server
int m_iFrameStart;
int m_iFrameEnd;
bool m_bWrap;
float m_flFramerate;
bool m_bNewAnimCommandsSemaphore;
bool m_bOldAnimCommandsSemaphore;
// Float lerp commands from the server
float m_flFloatLerpStartValue;
float m_flFloatLerpEndValue;
float m_flFloatLerpTransitionTime;
bool m_bFloatLerpWrap;
float m_flAnimationStartTime;
int m_nModifyMode;
};
IMPLEMENT_CLIENTCLASS_DT(C_MaterialModifyControl, DT_MaterialModifyControl, CMaterialModifyControl)
RecvPropString( RECVINFO( m_szMaterialName ) ),
RecvPropString( RECVINFO( m_szMaterialVar ) ),
RecvPropString( RECVINFO( m_szMaterialVarValue ) ),
RecvPropInt( RECVINFO(m_iFrameStart) ),
RecvPropInt( RECVINFO(m_iFrameEnd) ),
RecvPropInt( RECVINFO(m_bWrap) ),
RecvPropFloat( RECVINFO(m_flFramerate) ),
RecvPropInt( RECVINFO(m_bNewAnimCommandsSemaphore) ),
RecvPropFloat( RECVINFO(m_flFloatLerpStartValue) ),
RecvPropFloat( RECVINFO(m_flFloatLerpEndValue) ),
RecvPropFloat( RECVINFO(m_flFloatLerpTransitionTime) ),
RecvPropInt( RECVINFO(m_bFloatLerpWrap) ),
RecvPropInt( RECVINFO(m_nModifyMode) ),
END_RECV_TABLE()
//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
C_MaterialModifyControl::C_MaterialModifyControl()
{
m_pMaterial = NULL;
m_bOldAnimCommandsSemaphore = false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_MaterialModifyControl::OnPreDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnPreDataChanged( updateType );
m_bOldAnimCommandsSemaphore = m_bNewAnimCommandsSemaphore;
}
//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void C_MaterialModifyControl::OnDataChanged( DataUpdateType_t updateType )
{
if( updateType == DATA_UPDATE_CREATED )
{
m_pMaterial = materials->FindMaterial( m_szMaterialName, TEXTURE_GROUP_OTHER );
// Clear out our variables
m_bHasNewAnimationCommands = true;
}
// Detect changes in the anim commands
if ( m_bNewAnimCommandsSemaphore != m_bOldAnimCommandsSemaphore )
{
m_bHasNewAnimationCommands = true;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_MaterialModifyControl::GetAnimationCommands( materialanimcommands_t *pCommands )
{
pCommands->iFrameStart = m_iFrameStart;
pCommands->iFrameEnd = m_iFrameEnd;
pCommands->bWrap = m_bWrap;
pCommands->flFrameRate = m_flFramerate;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_MaterialModifyControl::GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands )
{
pCommands->flStartValue = m_flFloatLerpStartValue;
pCommands->flEndValue = m_flFloatLerpEndValue;
pCommands->flTransitionTime = m_flFloatLerpTransitionTime;
}
//------------------------------------------------------------------------------
// Purpose: We don't draw.
//------------------------------------------------------------------------------
bool C_MaterialModifyControl::ShouldDraw()
{
return false;
}
//=============================================================================
//
// THE MATERIALMODIFYPROXY ITSELF
//
class CMaterialModifyProxy : public CBaseAnimatedTextureProxy
{
public:
CMaterialModifyProxy();
virtual ~CMaterialModifyProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pEntity );
virtual IMaterial *GetMaterial();
private:
void OnBindSetVar( C_MaterialModifyControl *pControl );
void OnBindAnimatedTexture( C_MaterialModifyControl *pControl );
void OnBindFloatLerp( C_MaterialModifyControl *pControl );
float GetAnimationStartTime( void* pArg );
void AnimationWrapped( void* pArg );
IMaterial *m_pMaterial;
// texture animation stuff
int m_iFrameStart;
int m_iFrameEnd;
bool m_bReachedEnd;
bool m_bCustomWrap;
float m_flCustomFramerate;
// float lerp stuff
IMaterialVar *m_pMaterialVar;
int m_flStartValue;
int m_flEndValue;
float m_flStartTime;
float m_flTransitionTime;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CMaterialModifyProxy::CMaterialModifyProxy()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CMaterialModifyProxy::~CMaterialModifyProxy()
{
}
bool CMaterialModifyProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
// set var stuff
m_pMaterial = pMaterial;
// float lerp stuff
m_flStartValue = MATERIAL_MODIFY_ANIMATION_UNSET;
m_flEndValue = MATERIAL_MODIFY_ANIMATION_UNSET;
// animated stuff
// m_pMaterial = pMaterial;
// m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
// m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
// m_bReachedEnd = false;
// return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
return true;
}
void CMaterialModifyProxy::OnBind( void *pEntity )
{
// Get the modified material vars from the entity input
IClientRenderable *pRend = (IClientRenderable *)pEntity;
if ( pRend )
{
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if ( pBaseEntity )
{
if( debug_materialmodifycontrol_client.GetBool() )
{
// DevMsg( 1, "%s\n", pBaseEntity->GetDebugName() );
}
int numChildren = 0;
bool gotOne = false;
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
{
numChildren++;
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
if ( !pControl )
continue;
if( debug_materialmodifycontrol_client.GetBool() )
{
// DevMsg( 1, "pControl: 0x%p\n", pControl );
}
switch( pControl->GetModifyMode() )
{
case MATERIAL_MODIFY_MODE_NONE:
break;
case MATERIAL_MODIFY_MODE_SETVAR:
gotOne = true;
OnBindSetVar( pControl );
break;
case MATERIAL_MODIFY_MODE_ANIM_SEQUENCE:
OnBindAnimatedTexture( pControl );
break;
case MATERIAL_MODIFY_MODE_FLOAT_LERP:
OnBindFloatLerp( pControl );
break;
default:
Assert( 0 );
break;
}
}
if( gotOne )
{
// DevMsg( 1, "numChildren: %d\n", numChildren );
}
}
}
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
IMaterial *CMaterialModifyProxy::GetMaterial()
{
return m_pMaterial;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMaterialModifyProxy::OnBindSetVar( C_MaterialModifyControl *pControl )
{
IMaterial *pMaterial = pControl->GetMaterial();
if( !pMaterial )
{
Assert( 0 );
return;
}
if ( pMaterial != m_pMaterial )
{
// Warning( "\t%s!=%s\n", pMaterial->GetName(), m_pMaterial->GetName() );
return;
}
bool bFound;
IMaterialVar *pMaterialVar = pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
if ( !bFound )
return;
if( Q_strcmp( pControl->GetMaterialVariableValue(), "" ) )
{
// const char *pMaterialName = m_pMaterial->GetName();
// const char *pMaterialVarName = pMaterialVar->GetName();
// const char *pMaterialVarValue = pControl->GetMaterialVariableValue();
// if( debug_materialmodifycontrol_client.GetBool()
// && Q_stristr( m_pMaterial->GetName(), "faceandhair" )
// && Q_stristr( pMaterialVar->GetName(), "self" )
// )
// {
// static int count = 0;
// DevMsg( 1, "CMaterialModifyProxy::OnBindSetVar \"%s\" %s=%s %d pControl=0x%p\n",
// m_pMaterial->GetName(), pMaterialVar->GetName(), pControl->GetMaterialVariableValue(), count++, pControl );
// }
pMaterialVar->SetValueAutodetectType( pControl->GetMaterialVariableValue() );
}
}
//-----------------------------------------------------------------------------
// Does the dirty deed
//-----------------------------------------------------------------------------
void CMaterialModifyProxy::OnBindAnimatedTexture( C_MaterialModifyControl *pControl )
{
assert ( m_AnimatedTextureVar );
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
return;
ITexture *pTexture;
pTexture = m_AnimatedTextureVar->GetTextureValue();
if ( !pControl )
return;
if ( pControl->HasNewAnimationCommands() )
{
// Read the data from the modify entity
materialanimcommands_t sCommands;
pControl->GetAnimationCommands( &sCommands );
m_iFrameStart = sCommands.iFrameStart;
m_iFrameEnd = sCommands.iFrameEnd;
m_bCustomWrap = sCommands.bWrap;
m_flCustomFramerate = sCommands.flFrameRate;
m_bReachedEnd = false;
m_flStartTime = gpGlobals->curtime;
pControl->ClearAnimationCommands();
}
// Init all the vars based on whether we're using the base material settings,
// or the custom ones from the entity input.
int numFrames;
bool bWrapAnimation;
float flFrameRate;
int iLastFrame;
// Do we have a custom frame section from the server?
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
{
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
{
m_iFrameEnd = pTexture->GetNumAnimationFrames();
}
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
bWrapAnimation = m_bCustomWrap;
flFrameRate = m_flCustomFramerate;
iLastFrame = (m_iFrameEnd - 1);
}
else
{
numFrames = pTexture->GetNumAnimationFrames();
bWrapAnimation = m_WrapAnimation;
flFrameRate = m_FrameRate;
iLastFrame = (numFrames - 1);
}
// Have we already reached the end? If so, stay there.
if ( m_bReachedEnd && !bWrapAnimation )
{
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
return;
}
// NOTE: Must not use relative time based methods here
// because the bind proxy can be called many times per frame.
// Prevent multiple Wrap callbacks to be sent for no wrap mode
float startTime;
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
{
startTime = m_flStartTime;
}
else
{
startTime = GetAnimationStartTime(pControl);
}
float deltaTime = gpGlobals->curtime - startTime;
float prevTime = deltaTime - gpGlobals->frametime;
// Clamp..
if (deltaTime < 0.0f)
deltaTime = 0.0f;
if (prevTime < 0.0f)
prevTime = 0.0f;
float frame = flFrameRate * deltaTime;
float prevFrame = flFrameRate * prevTime;
int intFrame = ((int)frame) % numFrames;
int intPrevFrame = ((int)prevFrame) % numFrames;
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
{
intFrame += m_iFrameStart;
intPrevFrame += m_iFrameStart;
}
// Report wrap situation...
if (intPrevFrame > intFrame)
{
m_bReachedEnd = true;
if (bWrapAnimation)
{
AnimationWrapped( pControl );
}
else
{
// Only sent the wrapped message once.
// when we're in non-wrapping mode
if (prevFrame < numFrames)
AnimationWrapped( pControl );
intFrame = numFrames - 1;
}
}
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float CMaterialModifyProxy::GetAnimationStartTime( void* pArg )
{
IClientRenderable *pRend = (IClientRenderable *)pArg;
if (!pRend)
return 0.0f;
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if (pEntity)
{
return pEntity->GetTextureAnimationStartTime();
}
return 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMaterialModifyProxy::AnimationWrapped( void* pArg )
{
IClientRenderable *pRend = (IClientRenderable *)pArg;
if (!pRend)
return;
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if (pEntity)
{
pEntity->TextureAnimationWrapped();
}
}
//-----------------------------------------------------------------------------
// Does the dirty deed
//-----------------------------------------------------------------------------
void CMaterialModifyProxy::OnBindFloatLerp( C_MaterialModifyControl *pControl )
{
if ( !pControl )
return;
if ( pControl->HasNewAnimationCommands() )
{
pControl->SetAnimationStartTime( gpGlobals->curtime );
pControl->ClearAnimationCommands();
}
// Read the data from the modify entity
materialfloatlerpcommands_t sCommands;
pControl->GetFloatLerpCommands( &sCommands );
m_flStartValue = sCommands.flStartValue;
m_flEndValue = sCommands.flEndValue;
m_flTransitionTime = sCommands.flTransitionTime;
m_flStartTime = pControl->GetAnimationStartTime();
bool bFound;
m_pMaterialVar = m_pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
if( bFound )
{
float currentValue;
if( m_flTransitionTime > 0.0f )
{
currentValue = m_flStartValue + ( m_flEndValue - m_flStartValue ) * clamp( ( ( gpGlobals->curtime - m_flStartTime ) / m_flTransitionTime ), 0.0f, 1.0f );
}
else
{
currentValue = m_flEndValue;
}
if( debug_materialmodifycontrol_client.GetBool() && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) && Q_stristr( m_pMaterialVar->GetName(), "warp" ) )
{
static int count = 0;
DevMsg( 1, "CMaterialFloatLerpProxy::OnBind \"%s\" %s=%f %d\n", m_pMaterial->GetName(), m_pMaterialVar->GetName(), currentValue, count++ );
}
m_pMaterialVar->SetFloatValue( currentValue );
}
}
//=============================================================================
//
// MATERIALMODIFYANIMATED PROXY
//
class CMaterialModifyAnimatedProxy : public CBaseAnimatedTextureProxy
{
public:
CMaterialModifyAnimatedProxy() {};
virtual ~CMaterialModifyAnimatedProxy() {};
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pEntity );
virtual float GetAnimationStartTime( void* pBaseEntity );
virtual void AnimationWrapped( void* pC_BaseEntity );
private:
IMaterial *m_pMaterial;
int m_iFrameStart;
int m_iFrameEnd;
bool m_bReachedEnd;
float m_flStartTime;
bool m_bCustomWrap;
float m_flCustomFramerate;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CMaterialModifyAnimatedProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
m_pMaterial = pMaterial;
m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
m_bReachedEnd = false;
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
}
//-----------------------------------------------------------------------------
// Does the dirty deed
//-----------------------------------------------------------------------------
void CMaterialModifyAnimatedProxy::OnBind( void *pEntity )
{
assert ( m_AnimatedTextureVar );
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
return;
ITexture *pTexture;
pTexture = m_AnimatedTextureVar->GetTextureValue();
// Get the modified material vars from the entity input
IClientRenderable *pRend = (IClientRenderable *)pEntity;
if ( pRend )
{
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if ( pBaseEntity )
{
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
{
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
if ( !pControl )
continue;
if ( !pControl->HasNewAnimationCommands() )
continue;
// Read the data from the modify entity
materialanimcommands_t sCommands;
pControl->GetAnimationCommands( &sCommands );
m_iFrameStart = sCommands.iFrameStart;
m_iFrameEnd = sCommands.iFrameEnd;
m_bCustomWrap = sCommands.bWrap;
m_flCustomFramerate = sCommands.flFrameRate;
m_bReachedEnd = false;
m_flStartTime = gpGlobals->curtime;
pControl->ClearAnimationCommands();
}
}
}
// Init all the vars based on whether we're using the base material settings,
// or the custom ones from the entity input.
int numFrames;
bool bWrapAnimation;
float flFrameRate;
int iLastFrame;
// Do we have a custom frame section from the server?
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
{
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
{
m_iFrameEnd = pTexture->GetNumAnimationFrames();
}
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
bWrapAnimation = m_bCustomWrap;
flFrameRate = m_flCustomFramerate;
iLastFrame = (m_iFrameEnd - 1);
}
else
{
numFrames = pTexture->GetNumAnimationFrames();
bWrapAnimation = m_WrapAnimation;
flFrameRate = m_FrameRate;
iLastFrame = (numFrames - 1);
}
// Have we already reached the end? If so, stay there.
if ( m_bReachedEnd && !bWrapAnimation )
{
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
return;
}
// NOTE: Must not use relative time based methods here
// because the bind proxy can be called many times per frame.
// Prevent multiple Wrap callbacks to be sent for no wrap mode
float startTime;
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
{
startTime = m_flStartTime;
}
else
{
startTime = GetAnimationStartTime(pEntity);
}
float deltaTime = gpGlobals->curtime - startTime;
float prevTime = deltaTime - gpGlobals->frametime;
// Clamp..
if (deltaTime < 0.0f)
deltaTime = 0.0f;
if (prevTime < 0.0f)
prevTime = 0.0f;
float frame = flFrameRate * deltaTime;
float prevFrame = flFrameRate * prevTime;
int intFrame = ((int)frame) % numFrames;
int intPrevFrame = ((int)prevFrame) % numFrames;
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
{
intFrame += m_iFrameStart;
intPrevFrame += m_iFrameStart;
}
// Report wrap situation...
if (intPrevFrame > intFrame)
{
m_bReachedEnd = true;
if (bWrapAnimation)
{
AnimationWrapped( pEntity );
}
else
{
// Only sent the wrapped message once.
// when we're in non-wrapping mode
if (prevFrame < numFrames)
AnimationWrapped( pEntity );
intFrame = numFrames - 1;
}
}
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float CMaterialModifyAnimatedProxy::GetAnimationStartTime( void* pArg )
{
IClientRenderable *pRend = (IClientRenderable *)pArg;
if (!pRend)
return 0.0f;
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if (pEntity)
{
return pEntity->GetTextureAnimationStartTime();
}
return 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMaterialModifyAnimatedProxy::AnimationWrapped( void* pArg )
{
IClientRenderable *pRend = (IClientRenderable *)pArg;
if (!pRend)
return;
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if (pEntity)
{
pEntity->TextureAnimationWrapped();
}
}
EXPOSE_INTERFACE( CMaterialModifyProxy, IMaterialProxy, "MaterialModify" IMATERIAL_PROXY_INTERFACE_VERSION );
EXPOSE_INTERFACE( CMaterialModifyAnimatedProxy, IMaterialProxy, "MaterialModifyAnimated" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,60 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Water LOD control entity.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "iviewrender.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//------------------------------------------------------------------------------
// FIXME: This really should inherit from something more lightweight
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Purpose : Water LOD control entity
//------------------------------------------------------------------------------
class C_WaterLODControl : public C_BaseEntity
{
public:
DECLARE_CLASS( C_WaterLODControl, C_BaseEntity );
DECLARE_CLIENTCLASS();
void OnDataChanged(DataUpdateType_t updateType);
bool ShouldDraw();
private:
float m_flCheapWaterStartDistance;
float m_flCheapWaterEndDistance;
};
IMPLEMENT_CLIENTCLASS_DT(C_WaterLODControl, DT_WaterLODControl, CWaterLODControl)
RecvPropFloat(RECVINFO(m_flCheapWaterStartDistance)),
RecvPropFloat(RECVINFO(m_flCheapWaterEndDistance)),
END_RECV_TABLE()
//------------------------------------------------------------------------------
// Purpose :
// Input :
// Output :
//------------------------------------------------------------------------------
void C_WaterLODControl::OnDataChanged(DataUpdateType_t updateType)
{
view->SetCheapWaterStartDistance( m_flCheapWaterStartDistance );
view->SetCheapWaterEndDistance( m_flCheapWaterEndDistance );
}
//------------------------------------------------------------------------------
// We don't draw...
//------------------------------------------------------------------------------
bool C_WaterLODControl::ShouldDraw()
{
return false;
}

View File

@ -0,0 +1,231 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Utility code.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "IEffects.h"
#include "fx.h"
#include "c_te_legacytempents.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Client-server neutral effects interface
//-----------------------------------------------------------------------------
class CEffectsClient : public IEffects
{
public:
CEffectsClient();
virtual ~CEffectsClient();
// Members of the IEffect interface
virtual void Beam( const Vector &Start, const Vector &End, int nModelIndex,
int nHaloIndex, unsigned char frameStart, unsigned char frameRate,
float flLife, unsigned char width, unsigned char endWidth, unsigned char fadeLength,
unsigned char noise, unsigned char red, unsigned char green,
unsigned char blue, unsigned char brightness, unsigned char speed);
virtual void Smoke( const Vector &origin, int modelIndex, float scale, float framerate );
virtual void Sparks( const Vector &position, int nMagnitude = 1, int nTrailLength = 1, const Vector *pvecDir = NULL );
virtual void Dust( const Vector &pos, const Vector &dir, float size, float speed );
virtual void MuzzleFlash( const Vector &origin, const QAngle &angles, float fScale, int type );
virtual void MetalSparks( const Vector &position, const Vector &direction );
virtual void EnergySplash( const Vector &position, const Vector &direction, bool bExplosive = false );
virtual void Ricochet( const Vector &position, const Vector &direction );
// FIXME: Should these methods remain in this interface? Or go in some
// other client-server neutral interface?
virtual float Time();
virtual bool IsServer();
virtual void SuppressEffectsSounds( bool bSuppress );
private:
//-----------------------------------------------------------------------------
// Purpose: Returning true means don't even call TE func
// Input : filter -
// *suppress_host -
// Output : static bool
//-----------------------------------------------------------------------------
bool SuppressTE( C_RecipientFilter& filter )
{
if ( !CanPredict() )
return true;
if ( !filter.GetRecipientCount() )
{
// Suppress it
return true;
}
// There's at least one recipient
return false;
}
bool m_bSuppressSound;
};
//-----------------------------------------------------------------------------
// Client-server neutral effects interface accessor
//-----------------------------------------------------------------------------
static CEffectsClient s_EffectClient;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CEffectsClient, IEffects, IEFFECTS_INTERFACE_VERSION, s_EffectClient);
IEffects *g_pEffects = &s_EffectClient;
ConVar r_decals( "r_decals", "2048" );
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
CEffectsClient::CEffectsClient()
{
m_bSuppressSound = false;
}
CEffectsClient::~CEffectsClient()
{
}
//-----------------------------------------------------------------------------
// Suppress sound on effects
//-----------------------------------------------------------------------------
void CEffectsClient::SuppressEffectsSounds( bool bSuppress )
{
m_bSuppressSound = bSuppress;
}
//-----------------------------------------------------------------------------
// Generates a beam
//-----------------------------------------------------------------------------
void CEffectsClient::Beam( const Vector &vecStartPoint, const Vector &vecEndPoint,
int nModelIndex, int nHaloIndex, unsigned char frameStart, unsigned char nFrameRate,
float flLife, unsigned char nWidth, unsigned char nEndWidth, unsigned char nFadeLength,
unsigned char noise, unsigned char r, unsigned char g,
unsigned char b, unsigned char brightness, unsigned char nSpeed)
{
Assert(0);
// CBroadcastRecipientFilter filter;
// if ( !SuppressTE( filter ) )
// {
// beams->CreateBeamPoints( vecStartPoint, vecEndPoint, nModelIndex, nHaloIndex,
// m_fHaloScale,
// flLife, 0.1 * nWidth, 0.1 * nEndWidth, nFadeLength, 0.01 * nAmplitude, a, 0.1 * nSpeed,
// m_nStartFrame, 0.1 * nFrameRate, r, g, b );
// }
}
//-----------------------------------------------------------------------------
// Generates various tempent effects
//-----------------------------------------------------------------------------
void CEffectsClient::Smoke( const Vector &vecOrigin, int modelIndex, float scale, float framerate )
{
CPVSFilter filter( vecOrigin );
if ( !SuppressTE( filter ) )
{
int iColor = random->RandomInt(20,35);
color32 color;
color.r = iColor;
color.g = iColor;
color.b = iColor;
color.a = iColor;
QAngle angles;
VectorAngles( Vector(0,0,1), angles );
FX_Smoke( vecOrigin, angles, scale * 0.1f, 4, (unsigned char *)&color, 255 );
}
}
void CEffectsClient::Sparks( const Vector &position, int nMagnitude, int nTrailLength, const Vector *pVecDir )
{
CPVSFilter filter( position );
if ( !SuppressTE( filter ) )
{
FX_ElectricSpark( position, nMagnitude, nTrailLength, pVecDir );
}
}
void CEffectsClient::Dust( const Vector &pos, const Vector &dir, float size, float speed )
{
CPVSFilter filter( pos );
if ( !SuppressTE( filter ) )
{
FX_Dust( pos, dir, size, speed );
}
}
void CEffectsClient::MuzzleFlash( const Vector &vecOrigin, const QAngle &vecAngles, float flScale, int iType )
{
CPVSFilter filter( vecOrigin );
if ( !SuppressTE( filter ) )
{
switch( iType )
{
case MUZZLEFLASH_TYPE_DEFAULT:
FX_MuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
break;
case MUZZLEFLASH_TYPE_GUNSHIP:
FX_GunshipMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
break;
case MUZZLEFLASH_TYPE_STRIDER:
FX_StriderMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
break;
default:
Msg("No case for Muzzleflash type: %d\n", iType );
break;
}
}
}
void CEffectsClient::MetalSparks( const Vector &position, const Vector &direction )
{
CPVSFilter filter( position );
if ( !SuppressTE( filter ) )
{
FX_MetalSpark( position, direction, direction );
}
}
void CEffectsClient::EnergySplash( const Vector &position, const Vector &direction, bool bExplosive )
{
CPVSFilter filter( position );
if ( !SuppressTE( filter ) )
{
FX_EnergySplash( position, direction, bExplosive );
}
}
void CEffectsClient::Ricochet( const Vector &position, const Vector &direction )
{
CPVSFilter filter( position );
if ( !SuppressTE( filter ) )
{
FX_MetalSpark( position, direction, direction );
if ( !m_bSuppressSound )
{
FX_RicochetSound( position );
}
}
}
// FIXME: Should these methods remain in this interface? Or go in some
// other client-server neutral interface?
float CEffectsClient::Time()
{
return gpGlobals->curtime;
}
bool CEffectsClient::IsServer()
{
return false;
}

View File

@ -0,0 +1,63 @@
//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "FunctionProxy.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
//-----------------------------------------------------------------------------
// Returns the player health (from 0 to 1)
//-----------------------------------------------------------------------------
class CProxyIsNPC : public CResultProxy
{
public:
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
void OnBind( void *pC_BaseEntity );
private:
CFloatInput m_Factor;
};
bool CProxyIsNPC::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
if (!CResultProxy::Init( pMaterial, pKeyValues ))
return false;
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
return false;
return true;
}
void CProxyIsNPC::OnBind( void *pC_BaseEntity )
{
if ( !pC_BaseEntity )
return;
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
if ( pEntity && pEntity->IsNPC() )
{
SetFloatResult( m_Factor.GetFloat() );
}
else
{
SetFloatResult( 0.0f );
}
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
EXPOSE_INTERFACE( CProxyIsNPC, IMaterialProxy, "IsNPC" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,60 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "materialsystem/IMaterialProxy.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialVar.h"
// $monitorTextureVar
class CMonitorMaterialProxy : public IMaterialProxy
{
public:
CMonitorMaterialProxy();
virtual ~CMonitorMaterialProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pC_BaseEntity );
virtual void Release( void ) { delete this; }
private:
IMaterialVar *m_pMonitorTextureVar;
};
CMonitorMaterialProxy::CMonitorMaterialProxy()
{
m_pMonitorTextureVar = NULL;
}
CMonitorMaterialProxy::~CMonitorMaterialProxy()
{
m_pMonitorTextureVar = NULL;
}
bool CMonitorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
char const* pMonitorTextureVarName = pKeyValues->getString( "$monitorTextureVar" );
if( !pMonitorTextureVarName )
return false;
bool foundVar;
m_pMonitorTextureVar = pMaterial->FindVar( pMonitorTextureVarName, &foundVar, false );
if( !foundVar )
{
m_pMonitorTextureVar = NULL;
return false;
}
return true;
}
void CMonitorMaterialProxy::OnBind( void *pC_BaseEntity )
{
if( !m_pMonitorTextureVar )
{
return;
}
}
EXPOSE_INTERFACE( CMonitorMaterialProxy, IMaterialProxy, "Monitor" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,59 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "FunctionProxy.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
//-----------------------------------------------------------------------------
// Returns the player health (from 0 to 1)
//-----------------------------------------------------------------------------
class CProxyHealth : public CResultProxy
{
public:
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
void OnBind( void *pC_BaseEntity );
private:
CFloatInput m_Factor;
};
bool CProxyHealth::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
if (!CResultProxy::Init( pMaterial, pKeyValues ))
return false;
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
return false;
return true;
}
void CProxyHealth::OnBind( void *pC_BaseEntity )
{
if (!pC_BaseEntity)
return;
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
Assert( m_pResult );
SetFloatResult( pEntity->HealthFraction() * m_Factor.GetFloat() );
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
EXPOSE_INTERFACE( CProxyHealth, IMaterialProxy, "Health" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,316 @@
#include "cbase.h"
#include "keyvalues.h"
#include "cdll_client_int.h"
#include "view_scene.h"
#include "viewrender.h"
#include "tier0/icommandline.h"
#include "materialsystem/IMesh.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialSystemHardwareConfig.h"
#include "materialsystem/IMaterialVar.h"
#include "ScreenSpaceEffects.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//------------------------------------------------------------------------------
// CScreenSpaceEffectRegistration code
// Used to register and effect with the IScreenSpaceEffectManager
//------------------------------------------------------------------------------
CScreenSpaceEffectRegistration *CScreenSpaceEffectRegistration::s_pHead = NULL;
CScreenSpaceEffectRegistration::CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect )
{
m_pEffectName = pName;
m_pEffect = pEffect;
m_pNext = s_pHead;
s_pHead = this;
}
//------------------------------------------------------------------------------
// CScreenSpaceEffectManager - Implementation of IScreenSpaceEffectManager
//------------------------------------------------------------------------------
class CScreenSpaceEffectManager : public IScreenSpaceEffectManager
{
public:
virtual void InitScreenSpaceEffects( );
virtual void ShutdownScreenSpaceEffects( );
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName );
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params );
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params );
virtual void EnableScreenSpaceEffect( const char *pEffectName );
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
virtual void DisableScreenSpaceEffect( const char *pEffectName );
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
virtual void DisableAllScreenSpaceEffects( );
virtual void RenderEffects( int x, int y, int w, int h );
};
CScreenSpaceEffectManager g_ScreenSpaceEffectManager;
IScreenSpaceEffectManager *g_pScreenSpaceEffects = &g_ScreenSpaceEffectManager;
//---------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::InitScreenSpaceEffects - Initialise all registered effects
//---------------------------------------------------------------------------------------
void CScreenSpaceEffectManager::InitScreenSpaceEffects( )
{
if ( CommandLine()->FindParm( "-filmgrain" ) )
{
GetScreenSpaceEffect( "filmgrain" )->Enable( true );
}
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
{
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
if( pEffect )
{
bool bIsEnabled = pEffect->IsEnabled( );
pEffect->Init( );
pEffect->Enable( bIsEnabled );
}
}
}
//----------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::ShutdownScreenSpaceEffects - Shutdown all registered effects
//----------------------------------------------------------------------------------------
void CScreenSpaceEffectManager::ShutdownScreenSpaceEffects( )
{
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
{
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
if( pEffect )
{
pEffect->Shutdown( );
}
}
}
//---------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::GetScreenSpaceEffect - Returns a point to the named effect
//---------------------------------------------------------------------------------------
IScreenSpaceEffect *CScreenSpaceEffectManager::GetScreenSpaceEffect( const char *pEffectName )
{
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
{
if( !Q_stricmp( pReg->m_pEffectName, pEffectName ) )
{
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
return pEffect;
}
}
Warning( "Could not find screen space effect %s\n", pEffectName );
return NULL;
}
//---------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::SetScreenSpaceEffectParams
// - Assign parameters to the specified effect
//---------------------------------------------------------------------------------------
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params )
{
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
if( pEffect )
SetScreenSpaceEffectParams( pEffect, params );
}
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params )
{
if( pEffect )
pEffect->SetParameters( params );
}
//---------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::EnableScreenSpaceEffect
// - Enables the specified effect
//---------------------------------------------------------------------------------------
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( const char *pEffectName )
{
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
if( pEffect )
EnableScreenSpaceEffect( pEffect );
}
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
{
if( pEffect )
pEffect->Enable( true );
}
//---------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::DisableScreenSpaceEffect
// - Disables the specified effect
//---------------------------------------------------------------------------------------
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( const char *pEffectName )
{
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
if( pEffect )
DisableScreenSpaceEffect( pEffect );
}
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
{
if( pEffect )
pEffect->Enable( false );
}
//---------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::DisableAllScreenSpaceEffects
// - Disables all registered screen space effects
//---------------------------------------------------------------------------------------
void CScreenSpaceEffectManager::DisableAllScreenSpaceEffects( )
{
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
{
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
if( pEffect )
{
pEffect->Enable( false );
}
}
}
//---------------------------------------------------------------------------------------
// CScreenSpaceEffectManager::RenderEffects
// - Renders all registered screen space effects
//---------------------------------------------------------------------------------------
void CScreenSpaceEffectManager::RenderEffects( int x, int y, int w, int h )
{
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
{
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
if( pEffect )
{
pEffect->Render( x, y, w, h );
}
}
}
//------------------------------------------------------------------------------
// Example post-processing effect
//------------------------------------------------------------------------------
class CExampleEffect : public IScreenSpaceEffect
{
public:
CExampleEffect( );
~CExampleEffect( );
void Init( );
void Shutdown( );
void SetParameters( KeyValues *params );
void Render( int x, int y, int w, int h );
void Enable( bool bEnable );
bool IsEnabled( );
private:
bool m_bEnable;
CMaterialReference m_Material;
};
ADD_SCREENSPACE_EFFECT( CExampleEffect, exampleeffect );
//------------------------------------------------------------------------------
// CExampleEffect constructor
//------------------------------------------------------------------------------
CExampleEffect::CExampleEffect( )
{
m_bEnable = false;
}
//------------------------------------------------------------------------------
// CExampleEffect destructor
//------------------------------------------------------------------------------
CExampleEffect::~CExampleEffect( )
{
}
//------------------------------------------------------------------------------
// CExampleEffect init
//------------------------------------------------------------------------------
void CExampleEffect::Init( )
{
// This is just example code, init your effect material here
//m_Material.Init( "engine/exampleeffect", TEXTURE_GROUP_OTHER );
m_bEnable = false;
}
//------------------------------------------------------------------------------
// CExampleEffect shutdown
//------------------------------------------------------------------------------
void CExampleEffect::Shutdown( )
{
m_Material.Shutdown();
}
//------------------------------------------------------------------------------
// CExampleEffect enable
//------------------------------------------------------------------------------
void CExampleEffect::Enable( bool bEnable )
{
// This is just example code, don't enable it
// m_bEnable = bEnable;
}
bool CExampleEffect::IsEnabled( )
{
return m_bEnable;
}
//------------------------------------------------------------------------------
// CExampleEffect SetParameters
//------------------------------------------------------------------------------
void CExampleEffect::SetParameters( KeyValues *params )
{
if( params->GetDataType( "example_param" ) == KeyValues::TYPE_STRING )
{
// ...
}
}
//------------------------------------------------------------------------------
// CExampleEffect render
//------------------------------------------------------------------------------
void CExampleEffect::Render( int x, int y, int w, int h )
{
if ( !IsEnabled() )
return;
// Render Effect
Rect_t actualRect;
UpdateScreenEffectTexture( 0, x, y, w, h, false, &actualRect );
ITexture *pTexture = GetFullFrameFrameBufferTexture( 0 );
CMatRenderContextPtr pRenderContext( materials );
pRenderContext->DrawScreenSpaceRectangle( m_Material, x, y, w, h,
actualRect.x, actualRect.y, actualRect.x+actualRect.width-1, actualRect.y+actualRect.height-1,
pTexture->GetActualWidth(), pTexture->GetActualHeight() );
}

View File

@ -0,0 +1,88 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=====================================================================================//
#ifndef SCREENSPACEEFFECTS_H
#define SCREENSPACEEFFECTS_H
#ifdef _WIN32
#pragma once
#endif
class KeyValues;
//------------------------------------------------------------------------------
// Simple base class for screen space post-processing effects
//------------------------------------------------------------------------------
abstract_class IScreenSpaceEffect
{
public:
virtual void Init( ) = 0;
virtual void Shutdown( ) = 0;
virtual void SetParameters( KeyValues *params ) = 0;
virtual void Render( int x, int y, int w, int h ) = 0;
virtual void Enable( bool bEnable ) = 0;
virtual bool IsEnabled( ) = 0;
};
//------------------------------------------------------------------------------
// Interface class for managing screen space post-processing effects
//------------------------------------------------------------------------------
abstract_class IScreenSpaceEffectManager
{
public:
virtual void InitScreenSpaceEffects( ) = 0;
virtual void ShutdownScreenSpaceEffects( ) = 0;
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName ) = 0;
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params ) = 0;
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params ) = 0;
virtual void EnableScreenSpaceEffect( const char *pEffectName ) = 0;
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
virtual void DisableScreenSpaceEffect( const char *pEffectName ) = 0;
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
virtual void DisableAllScreenSpaceEffects( ) = 0;
virtual void RenderEffects( int x, int y, int w, int h ) = 0;
};
extern IScreenSpaceEffectManager *g_pScreenSpaceEffects;
//-------------------------------------------------------------------------------------
// Registration class for adding screen space effects to the IScreenSpaceEffectManager
//-------------------------------------------------------------------------------------
class CScreenSpaceEffectRegistration
{
public:
CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect );
const char *m_pEffectName;
IScreenSpaceEffect *m_pEffect;
CScreenSpaceEffectRegistration *m_pNext;
static CScreenSpaceEffectRegistration *s_pHead;
};
#define ADD_SCREENSPACE_EFFECT( CEffect, pEffectName ) CEffect pEffectName##_effect; \
CScreenSpaceEffectRegistration pEffectName##_reg( #pEffectName, &pEffectName##_effect );
#endif

View File

@ -0,0 +1,172 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This is a panel which is rendered image on top of an entity
//
// $Revision: $
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "teambitmapimage.h"
#include <KeyValues.h>
#include "vgui_BitmapImage.h"
#include "PanelMetaClassMgr.h"
#include "vguimatsurface/IMatSystemSurface.h"
#include <vgui_controls/Panel.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// A multiplexer bitmap that chooses a bitmap based on team
//-----------------------------------------------------------------------------
CTeamBitmapImage::CTeamBitmapImage() : m_Alpha(1.0f)
{
memset( m_ppImage, 0, BITMAP_COUNT * sizeof(BitmapImage*) );
m_pEntity = NULL;
m_bRelativeTeams = 0;
}
CTeamBitmapImage::~CTeamBitmapImage()
{
int i;
for ( i = 0; i < BITMAP_COUNT; ++i )
{
if (m_ppImage[i])
delete m_ppImage[i];
}
}
//-----------------------------------------------------------------------------
// initialization
//-----------------------------------------------------------------------------
bool CTeamBitmapImage::Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity )
{
static char *pRelativeTeamNames[BITMAP_COUNT] =
{
"NoTeam",
"MyTeam",
"EnemyTeam",
};
static char *pAbsoluteTeamNames[BITMAP_COUNT] =
{
"Team0",
"Team1",
"Team2",
};
m_pEntity = pEntity;
m_bRelativeTeams = (pInitData->GetInt( "relativeteam" ) != 0);
char **ppTeamNames = m_bRelativeTeams ? pRelativeTeamNames : pAbsoluteTeamNames;
int i;
for ( i = 0 ; i < BITMAP_COUNT; ++i )
{
// Default to null
m_ppImage[i] = NULL;
// Look for team section
KeyValues *pTeamKV = pInitData->FindKey( ppTeamNames[i] );
if ( !pTeamKV )
continue;
char const* pClassImage = pTeamKV->GetString( "material" );
if ( !pClassImage || !pClassImage[ 0 ] )
return false;
// modulation color
Color color;
if (!ParseRGBA( pTeamKV, "color", color ))
color.SetColor( 255, 255, 255, 255 );
// hook in the bitmap
m_ppImage[i] = new BitmapImage( pParent->GetVPanel(), pClassImage );
m_ppImage[i]->SetColor( color );
}
return true;
}
//-----------------------------------------------------------------------------
// Alpha modulate...
//-----------------------------------------------------------------------------
void CTeamBitmapImage::SetAlpha( float alpha )
{
m_Alpha = clamp( alpha, 0.0f, 1.0f );
}
//-----------------------------------------------------------------------------
// draw
//-----------------------------------------------------------------------------
void CTeamBitmapImage::Paint( float yaw /*= 0.0f*/ )
{
if (m_Alpha == 0.0f)
return;
int team = 0;
if (m_bRelativeTeams)
{
if (GetEntity())
{
if (GetEntity()->GetTeamNumber() != 0)
{
team = GetEntity()->InLocalTeam() ? 1 : 2;
}
}
}
else
{
if (GetEntity())
team = GetEntity()->GetTeamNumber();
}
// Paint the image for the current team
if (m_ppImage[team])
{
// Modulate the color based on the alpha....
Color color = m_ppImage[team]->GetColor();
int alpha = color[3];
color[3] = (alpha * m_Alpha);
m_ppImage[team]->SetColor( color );
if ( yaw != 0.0f )
{
g_pMatSystemSurface->DisableClipping( true );
m_ppImage[team]->DoPaint( m_ppImage[team]->GetRenderSizePanel(), yaw );
g_pMatSystemSurface->DisableClipping( false );
}
else
{
// Paint
m_ppImage[team]->Paint();
}
// restore previous color
color[3] = alpha;
m_ppImage[team]->SetColor( color );
}
}
//-----------------------------------------------------------------------------
// Helper method to initialize a team image from KeyValues data..
//-----------------------------------------------------------------------------
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName, vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pTeamImage )
{
KeyValues *pTeamImageSection = pInitData;
if (pSectionName)
{
pTeamImageSection = pInitData->FindKey( pSectionName );
if ( !pTeamImageSection )
return false;
}
return pTeamImage->Init( pParent, pTeamImageSection, pEntity );
}

View File

@ -0,0 +1,80 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This is a panel which is rendered image on top of an entity
//
// $Revision: $
// $NoKeywords: $
//=============================================================================//
#ifndef TEAMBITMAPIMAGE_H
#define TEAMBITMAPIMAGE_H
#ifdef _WIN32
#pragma once
#endif
//#include "tf_shareddefs.h"
#include <vgui/VGUI.h>
namespace vgui
{
class Panel;
}
class BitmapImage;
class C_BaseEntity;
class KeyValues;
//-----------------------------------------------------------------------------
// A multiplexer bitmap that chooses a bitmap based on team
//-----------------------------------------------------------------------------
class CTeamBitmapImage
{
public:
// construction, destruction
CTeamBitmapImage();
~CTeamBitmapImage();
// initialization
bool Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity );
// Alpha override...
void SetAlpha( float alpha );
// Paint the sucka. Paint it the size of the parent panel
void Paint( float yaw = 0.0f );
protected:
// Wrapper so we can implement this with EHANDLES some day
C_BaseEntity *GetEntity() { return m_pEntity; }
private:
enum
{
// NOTE: Was MAX_TF_TEAMS not 4, but I don't like the dependency here.
BITMAP_COUNT = 4 + 1
};
BitmapImage *m_ppImage[ BITMAP_COUNT ];
C_BaseEntity *m_pEntity;
float m_Alpha;
bool m_bRelativeTeams;
};
//-----------------------------------------------------------------------------
// Helper method to initialize a team image from KeyValues data..
// KeyValues contains the bitmap data. pSectionName, if it exists,
// indicates which subsection of pInitData should be looked at to get at the
// image data. The final argument is the bitmap image to initialize.
// The function returns true if it succeeded.
//
// NOTE: This function looks for the key values 'material' and 'color'
// and uses them to set up the material + modulation color of the image
//-----------------------------------------------------------------------------
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName,
vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pBitmapImage );
#endif // TEAMBITMAPIMAGE_H

View File

@ -0,0 +1,83 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This is a panel which is rendered image on top of an entity
//
// $Revision: $
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "ViewConeImage.h"
#include <KeyValues.h>
#include <vgui_controls/Panel.h>
#include "vguimatsurface/IMatSystemSurface.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// initialization
//-----------------------------------------------------------------------------
bool CViewConeImage::Init( vgui::Panel *pParent, KeyValues* pInitData )
{
Assert( pParent );
// Load viewcone material
if (!m_Image.Init( pParent->GetVPanel(), pInitData ))
return false;
// Position the view cone...
int viewconesize = pInitData->GetInt( "size", 32 );
m_Image.SetRenderSize( viewconesize, viewconesize );
int cx, cy;
pParent->GetSize( cx, cy );
m_Image.SetPos( (cx - viewconesize) / 2, (cy - viewconesize) / 2 );
return true;
}
//-----------------------------------------------------------------------------
// Paint the sucka
//-----------------------------------------------------------------------------
void CViewConeImage::Paint( float yaw )
{
g_pMatSystemSurface->DisableClipping( true );
m_Image.DoPaint( NULL, yaw );
g_pMatSystemSurface->DisableClipping( false );
}
void CViewConeImage::SetColor( int r, int g, int b )
{
m_Image.SetColor( Color( r, g, b, 255 ) );
}
//-----------------------------------------------------------------------------
// Helper method to initialize a view cone image from KeyValues data..
// KeyValues contains the bitmap data, pSectionName, if it exists,
// indicates which subsection of pInitData should be looked at to get at the
// image data. The final argument is the bitmap image to initialize.
// The function returns true if it succeeded.
//
// NOTE: This function looks for the key values 'material' and 'color'
// and uses them to set up the material + modulation color of the image
//-----------------------------------------------------------------------------
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
vgui::Panel *pParent, CViewConeImage* pViewConeImage )
{
KeyValues *pViewConeImageSection;
if (pSectionName)
{
pViewConeImageSection = pInitData->FindKey( pSectionName );
if ( !pViewConeImageSection )
return false;
}
else
{
pViewConeImageSection = pInitData;
}
return pViewConeImage->Init( pParent, pViewConeImageSection );
}

View File

@ -0,0 +1,56 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This is a panel which draws a viewcone
//
// $Revision: $
// $NoKeywords: $
//=============================================================================//
#ifndef VIEWCONEIMAGE_H
#define VIEWCONEIMAGE_H
#include "shareddefs.h"
#include "VGUI_BitmapImage.h"
namespace vgui
{
class Panel;
}
class C_BaseEntity;
class KeyValues;
//-----------------------------------------------------------------------------
// A bitmap that renders a view cone based on angles
//-----------------------------------------------------------------------------
class CViewConeImage
{
public:
// initialization
bool Init( vgui::Panel *pParent, KeyValues* pInitData );
// Paint the sucka
void Paint( float yaw );
void SetColor( int r, int g, int b );
private:
BitmapImage m_Image;
};
//-----------------------------------------------------------------------------
// Helper method to initialize a view cone image from KeyValues data..
// KeyValues contains the bitmap data, pSectionName, if it exists,
// indicates which subsection of pInitData should be looked at to get at the
// image data. The final argument is the bitmap image to initialize.
// The function returns true if it succeeded.
//
// NOTE: This function looks for the key values 'material' and 'color'
// and uses them to set up the material + modulation color of the image
//-----------------------------------------------------------------------------
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
vgui::Panel *pParent, CViewConeImage* pViewConeImage );
#endif // VIEWCONEIMAGE_H

View File

@ -0,0 +1,83 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "materialsystem/IMaterialProxy.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialVar.h"
#include "iviewrender.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
// no inputs, assumes that the results go into $CHEAPWATERSTARTDISTANCE and $CHEAPWATERENDDISTANCE
class CWaterLODMaterialProxy : public IMaterialProxy
{
public:
CWaterLODMaterialProxy();
virtual ~CWaterLODMaterialProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pC_BaseEntity );
virtual void Release( void ) { delete this; }
virtual IMaterial *GetMaterial();
private:
IMaterialVar *m_pCheapWaterStartDistanceVar;
IMaterialVar *m_pCheapWaterEndDistanceVar;
};
CWaterLODMaterialProxy::CWaterLODMaterialProxy()
{
m_pCheapWaterStartDistanceVar = NULL;
m_pCheapWaterEndDistanceVar = NULL;
}
CWaterLODMaterialProxy::~CWaterLODMaterialProxy()
{
}
bool CWaterLODMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
bool foundVar;
m_pCheapWaterStartDistanceVar = pMaterial->FindVar( "$CHEAPWATERSTARTDISTANCE", &foundVar, false );
if( !foundVar )
return false;
m_pCheapWaterEndDistanceVar = pMaterial->FindVar( "$CHEAPWATERENDDISTANCE", &foundVar, false );
if( !foundVar )
return false;
return true;
}
void CWaterLODMaterialProxy::OnBind( void *pC_BaseEntity )
{
if( !m_pCheapWaterStartDistanceVar || !m_pCheapWaterEndDistanceVar )
{
return;
}
float start, end;
view->GetWaterLODParams( start, end );
m_pCheapWaterStartDistanceVar->SetFloatValue( start );
m_pCheapWaterEndDistanceVar->SetFloatValue( end );
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
IMaterial *CWaterLODMaterialProxy::GetMaterial()
{
return m_pCheapWaterStartDistanceVar->GetOwningMaterial();
}
EXPOSE_INTERFACE( CWaterLODMaterialProxy, IMaterialProxy, "WaterLOD" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,78 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "materialsystem/IMaterialProxy.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialVar.h"
#include "c_world.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
class CWorldDimsProxy : public IMaterialProxy
{
public:
CWorldDimsProxy();
virtual ~CWorldDimsProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pC_BaseEntity );
virtual void Release( void ) { delete this; }
virtual IMaterial *GetMaterial();
public:
IMaterialVar *m_pMinsVar;
IMaterialVar *m_pMaxsVar;
};
CWorldDimsProxy::CWorldDimsProxy()
{
m_pMinsVar = m_pMaxsVar = NULL;
}
CWorldDimsProxy::~CWorldDimsProxy()
{
}
bool CWorldDimsProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
m_pMinsVar = pMaterial->FindVar( "$world_mins", NULL, false );
m_pMaxsVar = pMaterial->FindVar( "$world_maxs", NULL, false );
return true;
}
void CWorldDimsProxy::OnBind( void *pC_BaseEntity )
{
if ( m_pMinsVar && m_pMaxsVar )
{
C_World *pWorld = GetClientWorldEntity();
if ( pWorld )
{
m_pMinsVar->SetVecValue( (const float*)&pWorld->m_WorldMins, 3 );
m_pMaxsVar->SetVecValue( (const float*)&pWorld->m_WorldMaxs, 3 );
}
}
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
IMaterial *CWorldDimsProxy::GetMaterial()
{
return m_pMinsVar->GetOwningMaterial();
}
EXPOSE_INTERFACE( CWorldDimsProxy, IMaterialProxy, "WorldDims" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,271 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "cbase.h"
#include "hud.h"
#include "hud_macros.h"
#include "hudelement.h"
#include "iclientmode.h"
#include "ienginevgui.h"
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <vgui/IVGUI.h>
#include <vgui_controls/EditablePanel.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/ImagePanel.h>
#include "achievement_notification_panel.h"
#include "steam/steam_api.h"
#include "iachievementmgr.h"
#include "fmtstr.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
#define ACHIEVEMENT_NOTIFICATION_DURATION 10.0f
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
DECLARE_HUDELEMENT_DEPTH( CAchievementNotificationPanel, 100 );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CAchievementNotificationPanel::CAchievementNotificationPanel( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "AchievementNotificationPanel" )
{
Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );
m_flHideTime = 0;
m_pPanelBackground = new EditablePanel( this, "Notification_Background" );
m_pIcon = new ImagePanel( this, "Notification_Icon" );
m_pLabelHeading = new Label( this, "HeadingLabel", "" );
m_pLabelTitle = new Label( this, "TitleLabel", "" );
m_pIcon->SetShouldScaleImage( true );
vgui::ivgui()->AddTickSignal( GetVPanel() );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::Init()
{
ListenForGameEvent( "achievement_event" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::ApplySchemeSettings( IScheme *pScheme )
{
// load control settings...
LoadControlSettings( "resource/UI/AchievementNotification.res" );
BaseClass::ApplySchemeSettings( pScheme );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::PerformLayout( void )
{
BaseClass::PerformLayout();
// Set background color of various elements. Need to do this in code, if we do it in res file it gets slammed by the
// scheme. (Incl. label background: some products don't have label background colors set in their scheme and helpfully slam it to white.)
SetBgColor( Color( 0, 0, 0, 0 ) );
m_pLabelHeading->SetBgColor( Color( 0, 0, 0, 0 ) );
m_pLabelTitle->SetBgColor( Color( 0, 0, 0, 0 ) );
m_pPanelBackground->SetBgColor( Color( 62,70,55, 200 ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::FireGameEvent( IGameEvent * event )
{
const char *name = event->GetName();
if ( 0 == Q_strcmp( name, "achievement_event" ) )
{
const char *pchName = event->GetString( "achievement_name" );
int iCur = event->GetInt( "cur_val" );
int iMax = event->GetInt( "max_val" );
wchar_t szLocalizedName[256]=L"";
if ( IsPC() )
{
// shouldn't ever get achievement progress if steam not running and user logged in, but check just in case
if ( !steamapicontext->SteamUserStats() )
{
Msg( "Steam not running, achievement progress notification not displayed\n" );
}
// use Steam to show achievement progress UI
CGameID gameID( engine->GetAppID() );
steamapicontext->SteamUserStats()->IndicateAchievementProgress( gameID, pchName, iCur, iMax );
}
else
{
// on X360 we need to show our own achievement progress UI
const wchar_t *pchLocalizedName = ACHIEVEMENT_LOCALIZED_NAME_FROM_STR( pchName );
Assert( pchLocalizedName );
if ( !pchLocalizedName || !pchLocalizedName[0] )
return;
Q_wcsncpy( szLocalizedName, pchLocalizedName, sizeof( szLocalizedName ) );
// this is achievement progress, compose the message of form: "<name> (<#>/<max>)"
wchar_t szFmt[128]=L"";
wchar_t szText[512]=L"";
wchar_t szNumFound[16]=L"";
wchar_t szNumTotal[16]=L"";
_snwprintf( szNumFound, ARRAYSIZE( szNumFound ), L"%i", iCur );
_snwprintf( szNumTotal, ARRAYSIZE( szNumTotal ), L"%i", iMax );
const wchar_t *pchFmt = g_pVGuiLocalize->Find( "#GameUI_Achievement_Progress_Fmt" );
if ( !pchFmt || !pchFmt[0] )
return;
Q_wcsncpy( szFmt, pchFmt, sizeof( szFmt ) );
g_pVGuiLocalize->ConstructString( szText, sizeof( szText ), szFmt, 3, szLocalizedName, szNumFound, szNumTotal );
AddNotification( pchName, g_pVGuiLocalize->Find( "#GameUI_Achievement_Progress" ), szText );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Called on each tick
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::OnTick( void )
{
if ( ( m_flHideTime > 0 ) && ( m_flHideTime < gpGlobals->curtime ) )
{
m_flHideTime = 0;
ShowNextNotification();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CAchievementNotificationPanel::ShouldDraw( void )
{
return ( ( m_flHideTime > 0 ) && ( m_flHideTime > gpGlobals->curtime ) && CHudElement::ShouldDraw() );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::AddNotification( const char *szIconBaseName, const wchar_t *pHeading, const wchar_t *pTitle )
{
// put this notification in our queue
int iQueueItem = m_queueNotification.AddToTail();
Notification_t &notification = m_queueNotification[iQueueItem];
Q_strncpy( notification.szIconBaseName, szIconBaseName, ARRAYSIZE( notification.szIconBaseName ) );
Q_wcsncpy( notification.szHeading, pHeading, sizeof( notification.szHeading ) );
Q_wcsncpy( notification.szTitle, pTitle, sizeof( notification.szTitle ) );
// if we are not currently displaying a notification, go ahead and show this one
if ( 0 == m_flHideTime )
{
ShowNextNotification();
}
}
//-----------------------------------------------------------------------------
// Purpose: Shows next notification in queue if there is one
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::ShowNextNotification()
{
// see if we have anything to do
if ( 0 == m_queueNotification.Count() )
{
m_flHideTime = 0;
return;
}
Notification_t &notification = m_queueNotification[ m_queueNotification.Head() ];
m_flHideTime = gpGlobals->curtime + ACHIEVEMENT_NOTIFICATION_DURATION;
// set the text and icon in the dialog
SetDialogVariable( "heading", notification.szHeading );
SetDialogVariable( "title", notification.szTitle );
const char *pchIconBaseName = notification.szIconBaseName;
if ( pchIconBaseName && pchIconBaseName[0] )
{
m_pIcon->SetImage( CFmtStr( "achievements/%s.vmt", pchIconBaseName ) );
}
// resize the panel so it always looks good
// get fonts
HFont hFontHeading = m_pLabelHeading->GetFont();
HFont hFontTitle = m_pLabelTitle->GetFont();
// determine how wide the text strings are
int iHeadingWidth = UTIL_ComputeStringWidth( hFontHeading, notification.szHeading );
int iTitleWidth = UTIL_ComputeStringWidth( hFontTitle, notification.szTitle );
// use the widest string
int iTextWidth = max( iHeadingWidth, iTitleWidth );
// don't let it be insanely wide
iTextWidth = min( iTextWidth, XRES( 300 ) );
int iIconWidth = m_pIcon->GetWide();
int iSpacing = XRES( 10 );
int iPanelWidth = iSpacing + iIconWidth + iSpacing + iTextWidth + iSpacing;
int iPanelX = GetWide() - iPanelWidth;
int iIconX = iPanelX + iSpacing;
int iTextX = iIconX + iIconWidth + iSpacing;
// resize all the elements
SetXAndWide( m_pPanelBackground, iPanelX, iPanelWidth );
SetXAndWide( m_pIcon, iIconX, iIconWidth );
SetXAndWide( m_pLabelHeading, iTextX, iTextWidth );
SetXAndWide( m_pLabelTitle, iTextX, iTextWidth );
m_queueNotification.Remove( m_queueNotification.Head() );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAchievementNotificationPanel::SetXAndWide( Panel *pPanel, int x, int wide )
{
int xCur, yCur;
pPanel->GetPos( xCur, yCur );
pPanel->SetPos( x, yCur );
pPanel->SetWide( wide );
}
CON_COMMAND_F( achievement_notification_test, "Test the hud notification UI", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY )
{
static int iCount=0;
CAchievementNotificationPanel *pPanel = GET_HUDELEMENT( CAchievementNotificationPanel );
if ( pPanel )
{
pPanel->AddNotification( "HL2_KILL_ODESSAGUNSHIP", L"Achievement Progress", ( 0 == ( iCount % 2 ) ? L"Test Notification Message A (1/10)" :
L"Test Message B" ) );
}
#if 0
IGameEvent *event = gameeventmanager->CreateEvent( "achievement_event" );
if ( event )
{
const char *szTestStr[] = { "TF_GET_HEADSHOTS", "TF_PLAY_GAME_EVERYMAP", "TF_PLAY_GAME_EVERYCLASS", "TF_GET_HEALPOINTS" };
event->SetString( "achievement_name", szTestStr[iCount%ARRAYSIZE(szTestStr)] );
event->SetInt( "cur_val", ( iCount%9 ) + 1 );
event->SetInt( "max_val", 10 );
gameeventmanager->FireEvent( event );
}
#endif
iCount++;
}

View File

@ -0,0 +1,57 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ACHIEVEMENT_NOTIFICATION_PANEL_H
#define ACHIEVEMENT_NOTIFICATION_PANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/EditablePanel.h>
#include "hudelement.h"
using namespace vgui;
class CAchievementNotificationPanel : public CHudElement, public EditablePanel
{
DECLARE_CLASS_SIMPLE( CAchievementNotificationPanel, EditablePanel );
public:
CAchievementNotificationPanel( const char *pElementName );
virtual void Init();
virtual void ApplySchemeSettings( IScheme *scheme );
virtual bool ShouldDraw( void );
virtual void PerformLayout( void );
virtual void LevelInit( void ) { m_flHideTime = 0; }
virtual void FireGameEvent( IGameEvent * event );
virtual void OnTick( void );
void AddNotification( const char *szIconBaseName, const wchar_t *pHeading, const wchar_t *pTitle );
private:
void ShowNextNotification();
void SetXAndWide( Panel *pPanel, int x, int wide );
float m_flHideTime;
Label *m_pLabelHeading;
Label *m_pLabelTitle;
EditablePanel *m_pPanelBackground;
ImagePanel *m_pIcon;
struct Notification_t
{
char szIconBaseName[255];
wchar_t szHeading[255];
wchar_t szTitle[255];
};
CUtlLinkedList<Notification_t> m_queueNotification;
};
#endif // ACHIEVEMENT_NOTIFICATION_PANEL_H

View File

@ -0,0 +1,62 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "ProxyEntity.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialVar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// $sineVar : name of variable that controls the alpha level (float)
class CAlphaMaterialProxy : public CEntityMaterialProxy
{
public:
CAlphaMaterialProxy();
virtual ~CAlphaMaterialProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( C_BaseEntity *pEntity );
virtual IMaterial *GetMaterial();
private:
IMaterialVar *m_AlphaVar;
};
CAlphaMaterialProxy::CAlphaMaterialProxy()
{
m_AlphaVar = NULL;
}
CAlphaMaterialProxy::~CAlphaMaterialProxy()
{
}
bool CAlphaMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
bool foundVar;
m_AlphaVar = pMaterial->FindVar( "$alpha", &foundVar, false );
return foundVar;
}
void CAlphaMaterialProxy::OnBind( C_BaseEntity *pEnt )
{
if (m_AlphaVar)
{
m_AlphaVar->SetFloatValue( pEnt->m_clrRender->a );
}
}
IMaterial *CAlphaMaterialProxy::GetMaterial()
{
if ( !m_AlphaVar )
return NULL;
return m_AlphaVar->GetOwningMaterial();
}
EXPOSE_INTERFACE( CAlphaMaterialProxy, IMaterialProxy, "Alpha" IMATERIAL_PROXY_INTERFACE_VERSION );

View File

@ -0,0 +1,51 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "BaseAnimatedTextureProxy.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
class CAnimatedEntityTextureProxy : public CBaseAnimatedTextureProxy
{
public:
CAnimatedEntityTextureProxy() {}
virtual ~CAnimatedEntityTextureProxy() {}
virtual float GetAnimationStartTime( void* pBaseEntity );
virtual void AnimationWrapped( void* pC_BaseEntity );
};
EXPOSE_INTERFACE( CAnimatedEntityTextureProxy, IMaterialProxy, "AnimatedEntityTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
float CAnimatedEntityTextureProxy::GetAnimationStartTime( void* pArg )
{
IClientRenderable *pRend = (IClientRenderable *)pArg;
if (!pRend)
return 0.0f;
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if (pEntity)
{
return pEntity->GetTextureAnimationStartTime();
}
return 0.0f;
}
void CAnimatedEntityTextureProxy::AnimationWrapped( void* pArg )
{
IClientRenderable *pRend = (IClientRenderable *)pArg;
if (!pRend)
return;
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
if (pEntity)
{
pEntity->TextureAnimationWrapped();
}
}

View File

@ -0,0 +1,56 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "BaseAnimatedTextureProxy.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
class CAnimatedOffsetTextureProxy : public CBaseAnimatedTextureProxy
{
public:
CAnimatedOffsetTextureProxy() : m_flFrameOffset( 0.0f ) {}
virtual ~CAnimatedOffsetTextureProxy() {}
virtual float GetAnimationStartTime( void* pBaseEntity );
virtual void OnBind( void *pBaseEntity );
protected:
float m_flFrameOffset;
};
EXPOSE_INTERFACE( CAnimatedOffsetTextureProxy, IMaterialProxy, "AnimatedOffsetTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
//-----------------------------------------------------------------------------
// Purpose:
// Input : pArg -
// Output : float
//-----------------------------------------------------------------------------
float CAnimatedOffsetTextureProxy::GetAnimationStartTime( void* pArg )
{
return m_flFrameOffset;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pBaseEntity -
//-----------------------------------------------------------------------------
void CAnimatedOffsetTextureProxy::OnBind( void *pBaseEntity )
{
C_BaseEntity* pEntity = (C_BaseEntity*)pBaseEntity;
if ( pEntity )
{
m_flFrameOffset = pEntity->GetTextureAnimationStartTime();
}
// Call into the base class
CBaseAnimatedTextureProxy::OnBind( pBaseEntity );
}

View File

@ -0,0 +1,29 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "BaseAnimatedTextureProxy.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
class CAnimatedTextureProxy : public CBaseAnimatedTextureProxy
{
public:
CAnimatedTextureProxy() {}
virtual ~CAnimatedTextureProxy() {}
virtual float GetAnimationStartTime( void* pBaseEntity );
};
EXPOSE_INTERFACE( CAnimatedTextureProxy, IMaterialProxy, "AnimatedTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
#pragma warning (disable : 4100)
float CAnimatedTextureProxy::GetAnimationStartTime( void* pBaseEntity )
{
return 0;
}

View File

@ -0,0 +1,173 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef ANIMATIONLAYER_H
#define ANIMATIONLAYER_H
#ifdef _WIN32
#pragma once
#endif
#include "rangecheckedvar.h"
#include "lerp_functions.h"
class C_AnimationLayer
{
public:
// This allows the datatables to access private members.
ALLOW_DATATABLES_PRIVATE_ACCESS();
C_AnimationLayer();
void Reset();
void SetOrder( int order );
public:
bool IsActive( void );
CRangeCheckedVar<int, -1, 65535, 0> m_nSequence;
CRangeCheckedVar<float, -2, 2, 0> m_flPrevCycle;
CRangeCheckedVar<float, -5, 5, 0> m_flWeight;
int m_nOrder;
// used for automatic crossfades between sequence changes
CRangeCheckedVar<float, -50, 50, 1> m_flPlaybackRate;
CRangeCheckedVar<float, -2, 2, 0> m_flCycle;
float GetFadeout( float flCurTime );
float m_flLayerAnimtime;
float m_flLayerFadeOuttime;
};
#ifdef CLIENT_DLL
#define CAnimationLayer C_AnimationLayer
#endif
inline C_AnimationLayer::C_AnimationLayer()
{
Reset();
}
inline void C_AnimationLayer::Reset()
{
m_nSequence = 0;
m_flPrevCycle = 0;
m_flWeight = 0;
m_flPlaybackRate = 0;
m_flCycle = 0;
m_flLayerAnimtime = 0;
m_flLayerFadeOuttime = 0;
}
inline void C_AnimationLayer::SetOrder( int order )
{
m_nOrder = order;
}
inline float C_AnimationLayer::GetFadeout( float flCurTime )
{
float s;
if (m_flLayerFadeOuttime <= 0.0f)
{
s = 0;
}
else
{
// blend in over 0.2 seconds
s = 1.0 - (flCurTime - m_flLayerAnimtime) / m_flLayerFadeOuttime;
if (s > 0 && s <= 1.0)
{
// do a nice spline curve
s = 3 * s * s - 2 * s * s * s;
}
else if ( s > 1.0f )
{
// Shouldn't happen, but maybe curtime is behind animtime?
s = 1.0f;
}
}
return s;
}
inline C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer& from, C_AnimationLayer& to )
{
C_AnimationLayer output;
output.m_nSequence = to.m_nSequence;
output.m_flCycle = LoopingLerp( flPercent, (float)from.m_flCycle, (float)to.m_flCycle );
output.m_flPrevCycle = to.m_flPrevCycle;
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
output.m_nOrder = to.m_nOrder;
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
return output;
}
inline C_AnimationLayer Lerp( float flPercent, const C_AnimationLayer& from, const C_AnimationLayer& to )
{
C_AnimationLayer output;
output.m_nSequence = to.m_nSequence;
output.m_flCycle = Lerp( flPercent, from.m_flCycle, to.m_flCycle );
output.m_flPrevCycle = to.m_flPrevCycle;
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
output.m_nOrder = to.m_nOrder;
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
return output;
}
inline C_AnimationLayer LoopingLerp_Hermite( float flPercent, C_AnimationLayer& prev, C_AnimationLayer& from, C_AnimationLayer& to )
{
C_AnimationLayer output;
output.m_nSequence = to.m_nSequence;
output.m_flCycle = LoopingLerp_Hermite( flPercent, (float)prev.m_flCycle, (float)from.m_flCycle, (float)to.m_flCycle );
output.m_flPrevCycle = to.m_flPrevCycle;
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
output.m_nOrder = to.m_nOrder;
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
return output;
}
// YWB: Specialization for interpolating euler angles via quaternions...
inline C_AnimationLayer Lerp_Hermite( float flPercent, const C_AnimationLayer& prev, const C_AnimationLayer& from, const C_AnimationLayer& to )
{
C_AnimationLayer output;
output.m_nSequence = to.m_nSequence;
output.m_flCycle = Lerp_Hermite( flPercent, prev.m_flCycle, from.m_flCycle, to.m_flCycle );
output.m_flPrevCycle = to.m_flPrevCycle;
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
output.m_nOrder = to.m_nOrder;
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
return output;
}
inline void Lerp_Clamp( C_AnimationLayer &val )
{
Lerp_Clamp( val.m_nSequence );
Lerp_Clamp( val.m_flCycle );
Lerp_Clamp( val.m_flPrevCycle );
Lerp_Clamp( val.m_flWeight );
Lerp_Clamp( val.m_nOrder );
Lerp_Clamp( val.m_flLayerAnimtime );
Lerp_Clamp( val.m_flLayerFadeOuttime );
}
#endif // ANIMATIONLAYER_H

View File

@ -0,0 +1,138 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "BaseAnimatedTextureProxy.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialVar.h"
#include "materialsystem/ITexture.h"
#include "tier1/KeyValues.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
//-----------------------------------------------------------------------------
// Constructor, destructor:
//-----------------------------------------------------------------------------
CBaseAnimatedTextureProxy::CBaseAnimatedTextureProxy()
{
Cleanup();
}
CBaseAnimatedTextureProxy::~CBaseAnimatedTextureProxy()
{
Cleanup();
}
//-----------------------------------------------------------------------------
// Initialization, shutdown
//-----------------------------------------------------------------------------
bool CBaseAnimatedTextureProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
char const* pAnimatedTextureVarName = pKeyValues->GetString( "animatedTextureVar" );
if( !pAnimatedTextureVarName )
return false;
bool foundVar;
m_AnimatedTextureVar = pMaterial->FindVar( pAnimatedTextureVarName, &foundVar, false );
if( !foundVar )
return false;
char const* pAnimatedTextureFrameNumVarName = pKeyValues->GetString( "animatedTextureFrameNumVar" );
if( !pAnimatedTextureFrameNumVarName )
return false;
m_AnimatedTextureFrameNumVar = pMaterial->FindVar( pAnimatedTextureFrameNumVarName, &foundVar, false );
if( !foundVar )
return false;
m_FrameRate = pKeyValues->GetFloat( "animatedTextureFrameRate", 15 );
m_WrapAnimation = !pKeyValues->GetInt( "animationNoWrap", 0 );
return true;
}
void CBaseAnimatedTextureProxy::Cleanup()
{
m_AnimatedTextureVar = NULL;
m_AnimatedTextureFrameNumVar = NULL;
}
//-----------------------------------------------------------------------------
// Does the dirty deed
//-----------------------------------------------------------------------------
void CBaseAnimatedTextureProxy::OnBind( void *pEntity )
{
Assert ( m_AnimatedTextureVar );
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
{
return;
}
ITexture *pTexture;
pTexture = m_AnimatedTextureVar->GetTextureValue();
int numFrames = pTexture->GetNumAnimationFrames();
if ( numFrames <= 0 )
{
Assert( !"0 frames in material calling animated texture proxy" );
return;
}
// NOTE: Must not use relative time based methods here
// because the bind proxy can be called many times per frame.
// Prevent multiple Wrap callbacks to be sent for no wrap mode
float startTime = GetAnimationStartTime(pEntity);
float deltaTime = gpGlobals->curtime - startTime;
float prevTime = deltaTime - gpGlobals->frametime;
// Clamp..
if (deltaTime < 0.0f)
deltaTime = 0.0f;
if (prevTime < 0.0f)
prevTime = 0.0f;
float frame = m_FrameRate * deltaTime;
float prevFrame = m_FrameRate * prevTime;
int intFrame = ((int)frame) % numFrames;
int intPrevFrame = ((int)prevFrame) % numFrames;
// Report wrap situation...
if (intPrevFrame > intFrame)
{
if (m_WrapAnimation)
{
AnimationWrapped( pEntity );
}
else
{
// Only sent the wrapped message once.
// when we're in non-wrapping mode
if (prevFrame < numFrames)
AnimationWrapped( pEntity );
intFrame = numFrames - 1;
}
}
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
IMaterial *CBaseAnimatedTextureProxy::GetMaterial()
{
return m_AnimatedTextureVar->GetOwningMaterial();
}

View File

@ -0,0 +1,47 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BASEANIMATEDTEXTUREPROXY
#define BASEANIMATEDTEXTUREPROXY
#include "materialsystem/IMaterialProxy.h"
class IMaterial;
class IMaterialVar;
#pragma warning (disable : 4100)
class CBaseAnimatedTextureProxy : public IMaterialProxy
{
public:
CBaseAnimatedTextureProxy();
virtual ~CBaseAnimatedTextureProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pC_BaseEntity );
virtual void Release( void ) { delete this; }
virtual IMaterial *GetMaterial();
protected:
// derived classes must implement this; it returns the time
// that the animation began
virtual float GetAnimationStartTime( void* pBaseEntity ) = 0;
// Derived classes may implement this if they choose;
// this method is called whenever the animation wraps...
virtual void AnimationWrapped( void* pBaseEntity ) {}
protected:
void Cleanup();
IMaterialVar *m_AnimatedTextureVar;
IMaterialVar *m_AnimatedTextureFrameNumVar;
float m_FrameRate;
bool m_WrapAnimation;
};
#endif // BASEANIMATEDTEXTUREPROXY

View File

@ -0,0 +1,77 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Implementation for CBaseClientRenderTargets class.
// Provides Init functions for common render textures used by the engine.
// Mod makers can inherit from this class, and call the Create functions for
// only the render textures the want for their mod.
//=============================================================================//
#include "cbase.h"
#include "baseclientrendertargets.h" // header
#include "materialsystem/imaterialsystemhardwareconfig.h" // Hardware config checks
ITexture* CBaseClientRenderTargets::CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem, int iSize )
{
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
"_rt_WaterReflection",
iSize, iSize, RT_SIZE_PICMIP,
pMaterialSystem->GetBackBufferFormat(),
MATERIAL_RT_DEPTH_SHARED,
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
CREATERENDERTARGETFLAGS_HDR );
}
ITexture* CBaseClientRenderTargets::CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem, int iSize )
{
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
"_rt_WaterRefraction",
iSize, iSize, RT_SIZE_PICMIP,
// This is different than reflection because it has to have alpha for fog factor.
IMAGE_FORMAT_RGBA8888,
MATERIAL_RT_DEPTH_SHARED,
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
CREATERENDERTARGETFLAGS_HDR );
}
ITexture* CBaseClientRenderTargets::CreateCameraTexture( IMaterialSystem* pMaterialSystem, int iSize )
{
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
"_rt_Camera",
iSize, iSize, RT_SIZE_DEFAULT,
pMaterialSystem->GetBackBufferFormat(),
MATERIAL_RT_DEPTH_SHARED,
0,
CREATERENDERTARGETFLAGS_HDR );
}
//-----------------------------------------------------------------------------
// Purpose: Called by the engine in material system init and shutdown.
// Clients should override this in their inherited version, but the base
// is to init all standard render targets for use.
// Input : pMaterialSystem - the engine's material system (our singleton is not yet inited at the time this is called)
// pHardwareConfig - the user hardware config, useful for conditional render target setup
//-----------------------------------------------------------------------------
void CBaseClientRenderTargets::InitClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig, int iWaterTextureSize, int iCameraTextureSize )
{
// Water effects
m_WaterReflectionTexture.Init( CreateWaterReflectionTexture( pMaterialSystem, iWaterTextureSize ) );
m_WaterRefractionTexture.Init( CreateWaterRefractionTexture( pMaterialSystem, iWaterTextureSize ) );
// Monitors
m_CameraTexture.Init( CreateCameraTexture( pMaterialSystem, iCameraTextureSize ) );
}
//-----------------------------------------------------------------------------
// Purpose: Shut down each CTextureReference we created in InitClientRenderTargets.
// Called by the engine in material system shutdown.
// Input : -
//-----------------------------------------------------------------------------
void CBaseClientRenderTargets::ShutdownClientRenderTargets()
{
// Water effects
m_WaterReflectionTexture.Shutdown();
m_WaterRefractionTexture.Shutdown();
// Monitors
m_CameraTexture.Shutdown();
}

View File

@ -0,0 +1,61 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Has init functions for all the standard render targets used by most games.
// Mods who wish to make their own render targets can inherit from this class
// and in the 'InitClientRenderTargets' interface called by the engine, set up
// their own render targets as well as calling the init functions for various
// common render targets provided by this class.
//
// Note: Unless the client defines a singleton interface by inheriting from
// this class and exposing the singleton instance, these init and shutdown
// functions WILL NOT be called by the engine.
//
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef CLIENTRENDERTARTETS_H_
#define CLIENTRENDERTARTETS_H_
#ifdef _WIN32
#pragma once
#endif
#include "game/client/iclientrendertargets.h" // base class with interfaces called by the engine
#include "materialsystem\imaterialsystem.h" // for material system classes and interfaces
// Externs
class IMaterialSystem;
class IMaterialSystemHardwareConfig;
class CBaseClientRenderTargets : public IClientRenderTargets
{
// no networked vars
DECLARE_CLASS_GAMEROOT( CBaseClientRenderTargets, IClientRenderTargets );
public:
// Interface called by engine during material system startup.
virtual void InitClientRenderTargets ( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig, int iWaterTextureSize = 1024, int iCameraTextureSize = 256 );
// Shutdown all custom render targets here.
virtual void ShutdownClientRenderTargets ( void );
protected:
// Standard render textures used by most mods-- Classes inheriting from
// this can choose to init these or not depending on their needs.
// For reflective and refracting water
CTextureReference m_WaterReflectionTexture;
CTextureReference m_WaterRefractionTexture;
// Used for monitors
CTextureReference m_CameraTexture;
// Init functions for the common render targets
ITexture* CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
ITexture* CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
ITexture* CreateCameraTexture( IMaterialSystem* pMaterialSystem, int iSize = 256 );
};
#endif // CLIENTRENDERTARTETS_H_

View File

@ -0,0 +1,94 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Base presence implementation for PC
//
//=====================================================================================//
#include "cbase.h"
#include "basepresence.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// Default global singleton. Mods should override this.
static CBasePresence s_basePresence;
IPresence *presence = NULL;
//-----------------------------------------------------------------------------
// Steam version of Rich Presence is a WIP, so PC implementation is stubbed for now.
//-----------------------------------------------------------------------------
bool CBasePresence::Init( void )
{
if ( !presence )
{
// Mod didn't override, default to base implementation
presence = &s_basePresence;
}
return true;
}
void CBasePresence::Shutdown( void )
{
// TODO: Implement for PC
}
void CBasePresence::Update( float frametime )
{
// TODO: Implement for PC
}
void CBasePresence::UserSetContext( unsigned int nUserIndex, unsigned int nContextId, unsigned int nContextValue, bool bAsync )
{
// TODO: Implement for PC
}
void CBasePresence::UserSetProperty( unsigned int nUserIndex, unsigned int nPropertyId, unsigned int nBytes, const void *pvValue, bool bAsync )
{
// TODO: Implement for PC
}
void CBasePresence::SetupGameProperties( CUtlVector< XUSER_CONTEXT > &contexts, CUtlVector< XUSER_PROPERTY > &properties )
{
// TODO: Implement for PC
}
unsigned int CBasePresence::GetPresenceID( const char *pIDName )
{
return 0;
}
const char *CBasePresence::GetPropertyIdString( const uint id )
{
return NULL;
}
void CBasePresence::GetPropertyDisplayString( uint id, uint value, char *pOutput, int nBytes )
{
}
void CBasePresence::StartStatsReporting( HANDLE handle, bool bArbitrated )
{
}
void CBasePresence::SetStat( uint iPropertyId, int iPropertyValue, int dataType )
{
}
void CBasePresence::UploadStats()
{
}
//---------------------------------------------------------
// Debug support
//---------------------------------------------------------
void CBasePresence::DebugUserSetContext( const CCommand &args )
{
if ( args.ArgC() == 3 )
{
UserSetContext( 0, atoi( args.Arg( 1 ) ), atoi( args.Arg( 2 ) ) );
}
else
{
Warning( "user_context <context id> <context value>\n" );
}
}
void CBasePresence::DebugUserSetProperty( const CCommand &args )
{
if ( args.ArgC() == 3 )
{
UserSetProperty( 0, strtoul( args.Arg( 1 ), NULL, 0 ), sizeof(int), args.Arg( 2 ) );
}
else
{
Warning( "user_property <property id> <property value>\n" );
}
}

View File

@ -0,0 +1,55 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose: Base implementation of the IPresence interface
//
//=============================================================================
#ifndef BASEPRESENCE_H
#define BASEPRESENCE_H
#ifdef _WIN32
#pragma once
#endif
#include "ipresence.h"
#include "igamesystem.h"
//-----------------------------------------------------------------------------
// Purpose: Common implementation for setting user contexts and properties.
// Each client should inherit from this to implement mod-specific presence info.
//-----------------------------------------------------------------------------
class CBasePresence : public IPresence, public CAutoGameSystemPerFrame
{
public:
// CBaseGameSystemPerFrame overrides
virtual bool Init( void );
virtual void Shutdown( void );
virtual void Update( float frametime );
virtual char const *Name( void ) { return "presence"; }
// IPresence Interface
virtual void UserSetContext( unsigned int nUserIndex, unsigned int nContextId, unsigned int nContextValue, bool bAsync = false );
virtual void UserSetProperty( unsigned int nUserIndex, unsigned int nPropertyId, unsigned int nBytes, const void *pvValue, bool bAsync = false );
virtual void SetupGameProperties( CUtlVector< XUSER_CONTEXT > &contexts, CUtlVector< XUSER_PROPERTY > &properties );
virtual uint GetPresenceID( const char *pIdName );
virtual void GetPropertyDisplayString( uint id, uint value, char *pOutput, int nBytes );
virtual const char *GetPropertyIdString( const uint id );
// Stats reporting
virtual void StartStatsReporting( HANDLE handle, bool bArbitrated );
virtual void SetStat( uint iPropertyId, int iPropertyValue, int dataType );
virtual void UploadStats();
protected:
bool m_bArbitrated;
bool m_bReportingStats;
HANDLE m_hSession;
CUtlVector< XUSER_PROPERTY > m_PlayerStats;
//---------------------------------------------------------
// Debug support
//---------------------------------------------------------
CON_COMMAND_MEMBER_F( CBasePresence, "user_context", DebugUserSetContext, "Set a Rich Presence Context: user_context <context id> <context value>", 0 )
CON_COMMAND_MEMBER_F( CBasePresence, "user_property", DebugUserSetProperty, "Set a Rich Presence Property: user_property <property id>", 0 )
};
#endif // BASEPRESENCE_H

View File

@ -0,0 +1,167 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Base rich presence implementation for Xbox360
//
//=====================================================================================//
#include "cbase.h"
#include "basepresence.h"
#include "cdll_client_int.h"
#include "ixboxsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// Default global instance. Mods should override this.
static CBasePresence s_basePresence;
IPresence *presence = NULL;
//-----------------------------------------------------------------------------
// Purpose: Init
//-----------------------------------------------------------------------------
bool CBasePresence::Init( void )
{
if ( !presence )
{
// Mod didn't override, default to base implementation
presence = &s_basePresence;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Shutdown
//-----------------------------------------------------------------------------
void CBasePresence::Shutdown( void )
{
// Do nothing
}
//-----------------------------------------------------------------------------
// Purpose: Per-frame update
//-----------------------------------------------------------------------------
void CBasePresence::Update( float frametime )
{
// Do nothing
}
//-----------------------------------------------------------------------------
// Contexts are strings that describe the current state of the game.
//-----------------------------------------------------------------------------
void CBasePresence::UserSetContext( unsigned int nUserIndex, unsigned int nContextId, unsigned int nContextValue, bool bAsync )
{
if ( !xboxsystem->UserSetContext( nUserIndex, nContextId, nContextValue, bAsync ) )
{
Warning( "CBasePresence: UserSetContext failed.\n" );
}
}
//-----------------------------------------------------------------------------
// Properties are (usually) numeric values that can be insterted into context strings.
//-----------------------------------------------------------------------------
void CBasePresence::UserSetProperty( unsigned int nUserIndex, unsigned int nPropertyId, unsigned int nBytes, const void *pvValue, bool bAsync )
{
if ( !xboxsystem->UserSetProperty( nUserIndex, nPropertyId, nBytes, pvValue, bAsync ) )
{
Warning( "CBasePresence: UserSetProperty failed.\n" );
}
}
//-----------------------------------------------------------------------------
// Get game session properties from matchmaking.
//-----------------------------------------------------------------------------
void CBasePresence::SetupGameProperties( CUtlVector< XUSER_CONTEXT > &contexts, CUtlVector< XUSER_PROPERTY > &properties )
{
Assert( 0 );
}
//-----------------------------------------------------------------------------
// Convert a string to a presence ID.
//-----------------------------------------------------------------------------
uint CBasePresence::GetPresenceID( const char *pIdName )
{
Assert( 0 );
return 0;
}
//-----------------------------------------------------------------------------
// Convert a presence ID to a string.
//-----------------------------------------------------------------------------
const char *CBasePresence::GetPropertyIdString( const uint id )
{
Assert( 0 );
return NULL;
}
//-----------------------------------------------------------------------------
// Get display string for a game property.
//-----------------------------------------------------------------------------
void CBasePresence::GetPropertyDisplayString( uint id, uint value, char *pOutput, int nBytes )
{
Assert( 0 );
}
//-----------------------------------------------------------------------------
// Set up for reporting stats to Live.
//-----------------------------------------------------------------------------
void CBasePresence::StartStatsReporting( HANDLE handle, bool bArbitrated )
{
m_bArbitrated = bArbitrated;
m_hSession = handle;
m_bReportingStats = true;
m_PlayerStats.RemoveAll();
}
//-----------------------------------------------------------------------------
// Set a specific stat property.
//-----------------------------------------------------------------------------
void CBasePresence::SetStat( uint iPropertyId, int iPropertyValue, int dataType )
{
if ( m_bReportingStats )
{
XUSER_PROPERTY prop;
prop.dwPropertyId = iPropertyId;
prop.value.nData = iPropertyValue;
prop.value.type = dataType;
m_PlayerStats.AddToTail( prop );
}
}
//-----------------------------------------------------------------------------
// Upload the stats to Live.
//-----------------------------------------------------------------------------
void CBasePresence::UploadStats()
{
Assert( 0 );
}
//---------------------------------------------------------
// Debug support
//---------------------------------------------------------
void CBasePresence::DebugUserSetContext( const CCommand &args )
{
if ( args.ArgC() == 3 )
{
UserSetContext( XBX_GetPrimaryUserId(), atoi( args.Arg( 1 ) ), atoi( args.Arg( 2 ) ) );
}
else
{
Warning( "user_context <context id> <context value>\n" );
}
}
void CBasePresence::DebugUserSetProperty( const CCommand &args )
{
if ( args.ArgC() == 3 )
{
int value = atoi( args.Arg( 2 ) );
UserSetProperty( XBX_GetPrimaryUserId(), strtoul( args.Arg( 1 ), NULL, 0 ), sizeof(int), &value );
}
else
{
Warning( "user_property <property id> <property value>\n" );
}
}

1530
game/client/beamdraw.cpp Normal file

File diff suppressed because it is too large Load Diff

173
game/client/beamdraw.h Normal file
View File

@ -0,0 +1,173 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#if !defined( BEAMDRAW_H )
#define BEAMDRAW_H
#ifdef _WIN32
#pragma once
#endif
#include "materialsystem/imaterial.h"
#include "materialsystem/imesh.h"
#include "mathlib/vector.h"
#include "tier2/beamsegdraw.h"
#include "c_pixel_visibility.h"
#define NOISE_DIVISIONS 128
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct model_t;
struct BeamTrail_t;
//-----------------------------------------------------------------------------
// Purpose: Beams fill out this data structure
// This is also used for rendering
//-----------------------------------------------------------------------------
class Beam_t : public CDefaultClientRenderable
{
public:
Beam_t();
// Methods of IClientRenderable
virtual const Vector& GetRenderOrigin( void );
virtual const QAngle& GetRenderAngles( void );
virtual const matrix3x4_t &RenderableToWorldTransform();
virtual void GetRenderBounds( Vector& mins, Vector& maxs );
virtual bool ShouldDraw( void );
virtual bool IsTransparent( void );
virtual int DrawModel( int flags );
virtual void ComputeFxBlend( );
virtual int GetFxBlend( );
// Resets the beam state
void Reset();
// Method to computing the bounding box
void ComputeBounds();
// Bounding box...
Vector m_Mins;
Vector m_Maxs;
pixelvis_handle_t *m_queryHandleHalo;
float m_haloProxySize;
// Data is below..
// Next beam in list
Beam_t* next;
// Type of beam
int type;
int flags;
// Control points for the beam
int numAttachments;
Vector attachment[MAX_BEAM_ENTS];
Vector delta;
// 0 .. 1 over lifetime of beam
float t;
float freq;
// Time when beam should die
float die;
float width;
float endWidth;
float fadeLength;
float amplitude;
float life;
// Color
float r, g, b;
float brightness;
// Speed
float speed;
// Animation
float frameRate;
float frame;
int segments;
// Attachment entities for the beam
EHANDLE entity[MAX_BEAM_ENTS];
int attachmentIndex[MAX_BEAM_ENTS];
// Model info
int modelIndex;
int haloIndex;
float haloScale;
int frameCount;
float rgNoise[NOISE_DIVISIONS+1];
// Popcorn trail for beam follows to use
BeamTrail_t* trail;
// for TE_BEAMRINGPOINT
float start_radius;
float end_radius;
// for FBEAM_ONLYNOISEONCE
bool m_bCalculatedNoise;
float m_flHDRColorScale;
#ifdef PORTAL
bool m_bDrawInMainRender;
bool m_bDrawInPortalRender;
#endif //#ifdef PORTAL
};
int ScreenTransform( const Vector& point, Vector& screen );
void DrawSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
float frame, int rendermode, const Vector& source, const Vector& delta,
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
void DrawTeslaSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
float frame, int rendermode, const Vector& source, const Vector& delta,
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
void DrawSplineSegs( int noise_divisions, float *prgNoise,
const model_t* beammodel, const model_t* halomodel, float flHaloScale,
float frame, int rendermode, int numAttachments, Vector* attachment,
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
void DrawHalo(IMaterial* pMaterial, const Vector& source, float scale, float const* color, float flHDRColorScale = 1.0f );
void BeamDrawHalo( const model_t* spritemodel, float frame, int rendermode, const Vector& source,
float scale, float* color, float flHDRColorScale = 1.0f );
void DrawDisk( int noise_divisions, float *prgNoise, const model_t* spritemodel,
float frame, int rendermode, const Vector& source, const Vector& delta,
float width, float scale, float freq, float speed,
int segments, float* color, float flHDRColorScale = 1.0f );
void DrawCylinder( int noise_divisions, float *prgNoise, const model_t* spritemodel,
float frame, int rendermode, const Vector& source,
const Vector& delta, float width, float scale, float freq,
float speed, int segments, float* color, float flHDRColorScale = 1.0f );
void DrawRing( int noise_divisions, float *prgNoise, void (*pfnNoise)( float *noise, int divs, float scale ),
const model_t* spritemodel, float frame, int rendermode,
const Vector& source, const Vector& delta, float width, float amplitude,
float freq, float speed, int segments, float* color, float flHDRColorScale = 1.0f );
void DrawBeamFollow( const model_t* spritemodel, BeamTrail_t* pHead, int frame, int rendermode, Vector& delta,
Vector& screen, Vector& screenLast, float die, const Vector& source,
int flags, float width, float amplitude, float freq, float* color, float flHDRColorScale = 1.0f );
void DrawBeamQuadratic( const Vector &start, const Vector &control, const Vector &end, float width, const Vector &color, float scrollOffset, float flHDRColorScale = 1.0f );
class CEngineSprite *Draw_SetSpriteTexture( const model_t *pSpriteModel, int frame, int rendermode );
//-----------------------------------------------------------------------------
// Assumes the material has already been bound
//-----------------------------------------------------------------------------
void DrawSprite( const Vector &vecOrigin, float flWidth, float flHeight, color32 color );
#endif // BEAMDRAW_H

View File

@ -0,0 +1,164 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "bone_merge_cache.h"
#include "bone_setup.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// CBoneMergeCache
//-----------------------------------------------------------------------------
CBoneMergeCache::CBoneMergeCache()
{
m_pOwner = NULL;
m_pFollow = NULL;
m_pFollowHdr = NULL;
m_pOwnerHdr = NULL;
m_nFollowBoneSetupMask = 0;
}
void CBoneMergeCache::Init( C_BaseAnimating *pOwner )
{
m_pOwner = pOwner;
m_pFollow = NULL;
m_pFollowHdr = NULL;
m_pOwnerHdr = NULL;
m_nFollowBoneSetupMask = 0;
}
void CBoneMergeCache::UpdateCache()
{
if ( !m_pOwner )
return;
CStudioHdr *pOwnerHdr = m_pOwner->GetModelPtr();
if ( !pOwnerHdr )
return;
C_BaseAnimating *pTestFollow = m_pOwner->FindFollowedEntity();
CStudioHdr *pTestHdr = (pTestFollow ? pTestFollow->GetModelPtr() : NULL);
if ( pTestFollow != m_pFollow || pTestHdr != m_pFollowHdr || pOwnerHdr != m_pOwnerHdr )
{
m_MergedBones.Purge();
m_BoneMergeBits.Purge();
// Update the cache.
if ( pTestFollow && pTestHdr && pOwnerHdr )
{
m_pFollow = pTestFollow;
m_pFollowHdr = pTestHdr;
m_pOwnerHdr = pOwnerHdr;
m_BoneMergeBits.SetSize( pOwnerHdr->numbones() / 8 + 1 );
memset( m_BoneMergeBits.Base(), 0, m_BoneMergeBits.Count() );
mstudiobone_t *pOwnerBones = m_pOwnerHdr->pBone( 0 );
m_nFollowBoneSetupMask = BONE_USED_BY_BONE_MERGE;
for ( int i = 0; i < m_pOwnerHdr->numbones(); i++ )
{
int parentBoneIndex = Studio_BoneIndexByName( m_pFollowHdr, pOwnerBones[i].pszName() );
if ( parentBoneIndex < 0 )
continue;
// Add a merged bone here.
CMergedBone mergedBone;
mergedBone.m_iMyBone = i;
mergedBone.m_iParentBone = parentBoneIndex;
m_MergedBones.AddToTail( mergedBone );
m_BoneMergeBits[i>>3] |= ( 1 << ( i & 7 ) );
if ( ( m_pFollowHdr->boneFlags( parentBoneIndex ) & BONE_USED_BY_BONE_MERGE ) == 0 )
{
m_nFollowBoneSetupMask = BONE_USED_BY_ANYTHING;
Warning("Performance warning: Merge with '%s'. Mark bone '%s' in model '%s' as being used by bone merge in the .qc!\n",
pOwnerHdr->pszName(), m_pFollowHdr->pBone( parentBoneIndex )->pszName(), m_pFollowHdr->pszName() );
}
}
// No merged bones found? Slam the mask to 0
if ( !m_MergedBones.Count() )
{
m_nFollowBoneSetupMask = 0;
}
}
else
{
m_pFollow = NULL;
m_pFollowHdr = NULL;
m_pOwnerHdr = NULL;
m_nFollowBoneSetupMask = 0;
}
}
}
void CBoneMergeCache::MergeMatchingBones( int boneMask )
{
UpdateCache();
// If this is set, then all the other cache data is set.
if ( !m_pOwnerHdr || m_MergedBones.Count() == 0 )
return;
// Have the entity we're following setup its bones.
m_pFollow->SetupBones( NULL, -1, m_nFollowBoneSetupMask, gpGlobals->curtime );
// Now copy the bone matrices.
for ( int i=0; i < m_MergedBones.Count(); i++ )
{
int iOwnerBone = m_MergedBones[i].m_iMyBone;
int iParentBone = m_MergedBones[i].m_iParentBone;
// Only update bones reference by the bone mask.
if ( !( m_pOwnerHdr->boneFlags( iOwnerBone ) & boneMask ) )
continue;
MatrixCopy( m_pFollow->GetBone( iParentBone ), m_pOwner->GetBoneForWrite( iOwnerBone ) );
}
}
bool CBoneMergeCache::GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles )
{
UpdateCache();
// If this is set, then all the other cache data is set.
if ( !m_pOwnerHdr || m_MergedBones.Count() == 0 )
return false;
// We want the abs origin such that if we put the entity there, the first merged bone
// will be aligned. This way the entity will be culled in the correct position.
//
// ie: mEntity * mBoneLocal = mFollowBone
// so: mEntity = mFollowBone * Inverse( mBoneLocal )
//
// Note: the code below doesn't take animation into account. If the attached entity animates
// all over the place, then this won't get the right results.
// Get mFollowBone.
m_pFollow->SetupBones( NULL, -1, m_nFollowBoneSetupMask, gpGlobals->curtime );
const matrix3x4_t &mFollowBone = m_pFollow->GetBone( m_MergedBones[0].m_iParentBone );
// Get Inverse( mBoneLocal )
matrix3x4_t mBoneLocal, mBoneLocalInv;
SetupSingleBoneMatrix( m_pOwnerHdr, m_pOwner->GetSequence(), 0, m_MergedBones[0].m_iMyBone, mBoneLocal );
MatrixInvert( mBoneLocal, mBoneLocalInv );
// Now calculate mEntity = mFollowBone * Inverse( mBoneLocal )
matrix3x4_t mEntity;
ConcatTransforms( mFollowBone, mBoneLocalInv, mEntity );
MatrixAngles( mEntity, *pAbsAngles, *pAbsOrigin );
return true;
}

View File

@ -0,0 +1,79 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef BONE_MERGE_CACHE_H
#define BONE_MERGE_CACHE_H
#ifdef _WIN32
#pragma once
#endif
class C_BaseAnimating;
class CStudioHdr;
#include "mathlib/vector.h"
class CBoneMergeCache
{
public:
CBoneMergeCache();
void Init( C_BaseAnimating *pOwner );
// Updates the lookups that let it merge bones quickly.
void UpdateCache();
// This copies the transform from all bones in the followed entity that have
// names that match our bones.
void MergeMatchingBones( int boneMask );
// Returns true if the specified bone is one that gets merged in MergeMatchingBones.
int CBoneMergeCache::IsBoneMerged( int iBone ) const;
// Gets the origin for the first merge bone on the parent.
bool GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles );
private:
// This is the entity that we're keeping the cache updated for.
C_BaseAnimating *m_pOwner;
// All the cache data is based off these. When they change, the cache data is regenerated.
// These are either all valid pointers or all NULL.
C_BaseAnimating *m_pFollow;
CStudioHdr *m_pFollowHdr;
CStudioHdr *m_pOwnerHdr;
// This is the mask we need to use to set up bones on the followed entity to do the bone merge
int m_nFollowBoneSetupMask;
// Cache data.
class CMergedBone
{
public:
unsigned short m_iMyBone;
unsigned short m_iParentBone;
};
CUtlVector<CMergedBone> m_MergedBones;
CUtlVector<unsigned char> m_BoneMergeBits; // One bit for each bone. The bit is set if the bone gets merged.
};
inline int CBoneMergeCache::IsBoneMerged( int iBone ) const
{
if ( m_pOwnerHdr )
return m_BoneMergeBits[iBone >> 3] & ( 1 << ( iBone & 7 ) );
else
return 0;
}
#endif // BONE_MERGE_CACHE_H

View File

@ -0,0 +1,70 @@
//========== Copyright © 2006, Valve Corporation, All rights reserved. ========
//
// Purpose:
//
//=============================================================================
#ifndef BONETOWORLDARRAY_H
#define BONETOWORLDARRAY_H
#include "tier0/tslist.h"
#if defined( _WIN32 )
#pragma once
#endif
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
template <int NUM_ARRAYS>
class CBoneToWorldArrays
{
public:
enum
{
ALIGNMENT = 128,
};
CBoneToWorldArrays()
{
const int SIZE_ARRAY = AlignValue( sizeof(matrix3x4_t) * MAXSTUDIOBONES, ALIGNMENT );
m_pBase = (matrix3x4_t *)_aligned_malloc( SIZE_ARRAY * NUM_ARRAYS, ALIGNMENT );
for ( int i = 0; i < NUM_ARRAYS; i++ )
{
matrix3x4_t *pArray = (matrix3x4_t *)((byte *)m_pBase + SIZE_ARRAY * i);
Assert( (size_t)pArray % ALIGNMENT == 0 );
Free( pArray );
}
}
~CBoneToWorldArrays()
{
_aligned_free( m_pBase );
}
int NumArrays()
{
return NUM_ARRAYS;
}
matrix3x4_t *Alloc( bool bBlock = true )
{
TSLNodeBase_t *p;
while ( ( p = m_Free.Pop() ) == NULL && bBlock )
{
ThreadPause();
}
return (matrix3x4_t *)p;
}
void Free( matrix3x4_t *p )
{
m_Free.Push( (TSLNodeBase_t *) p );
}
private:
CTSListBase m_Free;
matrix3x4_t *m_pBase;
};
#endif // BONETOWORLDARRAY_H

View File

@ -0,0 +1,169 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#if 0
class C_AI_BaseHumanoid : public C_AI_BaseNPC
{
public:
DECLARE_CLASS( C_AI_BaseHumanoid, C_AI_BaseNPC );
DECLARE_CLIENTCLASS();
C_AI_BaseHumanoid();
// model specific
virtual bool Interpolate( float currentTime );
virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
float m_recanimtime[3];
AnimationLayer_t m_Layer[4][3];
};
C_AI_BaseHumanoid::C_AI_BaseHumanoid()
{
memset(m_recanimtime, 0, sizeof(m_recanimtime));
memset(m_Layer, 0, sizeof(m_Layer));
}
BEGIN_RECV_TABLE_NOBASE(AnimationLayer_t, DT_Animationlayer)
RecvPropInt(RECVINFO_NAME(nSequence,sequence)),
RecvPropFloat(RECVINFO_NAME(flCycle,cycle)),
RecvPropFloat(RECVINFO_NAME(flPlaybackrate,playbackrate)),
RecvPropFloat(RECVINFO_NAME(flWeight,weight))
END_RECV_TABLE()
IMPLEMENT_CLIENTCLASS_DT(C_AI_BaseHumanoid, DT_BaseHumanoid, CAI_BaseHumanoid)
/*
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[0][2],m_Layer0),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[1][2],m_Layer1),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[2][2],m_Layer2),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[3][2],m_Layer3),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
*/
RecvPropInt(RECVINFO_NAME(m_Layer[0][2].nSequence,sequence0)),
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flCycle,cycle0)),
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flPlaybackrate,playbackrate0)),
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flWeight,weight0)),
RecvPropInt(RECVINFO_NAME(m_Layer[1][2].nSequence,sequence1)),
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flCycle,cycle1)),
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flPlaybackrate,playbackrate1)),
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flWeight,weight1)),
RecvPropInt(RECVINFO_NAME(m_Layer[2][2].nSequence,sequence2)),
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flCycle,cycle2)),
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flPlaybackrate,playbackrate2)),
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flWeight,weight2)),
RecvPropInt(RECVINFO_NAME(m_Layer[3][2].nSequence,sequence3)),
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flCycle,cycle3)),
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flPlaybackrate,playbackrate3)),
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flWeight,weight3))
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_AI_BaseHumanoid::StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask )
{
VPROF( "C_AI_BaseHumanoid::StandardBlendingRules" );
BaseClass::StandardBlendingRules( pStudioHdr, pos, q, currentTime, boneMask );
if ( !hdr )
{
return;
}
#if 0
float poseparam[MAXSTUDIOPOSEPARAM];
if ( GetSequence() >= hdr->numseq )
{
SetSequence( 0 );
}
// interpolate pose parameters
for (int i = 0; i < hdr->numposeparameters; i++)
{
poseparam[ i ] = m_flPoseParameter[i];
}
// build root animation
float fCycle = GetCycle();
CalcPose( hdr, NULL, pos, q, GetSequence(), fCycle, poseparam );
// debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, "%30s %6.2f : %6.2f", hdr->pSeqdesc( GetSequence() )->pszLabel( ), fCycle, 1.0 );
MaintainSequenceTransitions( hdr, fCycle, poseparam, pos, q, boneMask );
#if 1
for (i = 0; i < 4; i++)
{
if (m_Layer[i][2].nSequence != m_Layer[i][1].nSequence)
{
if (m_Layer[i][2].flWeight > 0.5) m_Layer[i][1].flWeight = 1.0; else m_Layer[i][1].flWeight = 0;
}
}
#endif
#if 1
for (i = 0; i < 4; i++)
{
Vector pos2[MAXSTUDIOBONES];
Quaternion q2[MAXSTUDIOBONES];
float fWeight = m_Layer[i][1].flWeight * (1 - dadt) + m_Layer[i][2].flWeight * dadt;
/*
debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -i - 1, 0,
"%2d %6.2f %6.2f : %2d %6.2f %6.2f : %2d %6.2f %6.2f",
m_Layer[i][0].nSequence, m_Layer[i][0].flCycle, m_Layer[i][0].flWeight,
m_Layer[i][1].nSequence, m_Layer[i][1].flCycle, m_Layer[i][1].flWeight,
m_Layer[i][2].nSequence, m_Layer[i][2].flCycle, m_Layer[i][2].flWeight );
*/
if (fWeight > 0)
{
mstudioseqdesc_t *pseqdesc = hdr->pSeqdesc( m_Layer[i][2].nSequence );
float fCycle = m_Layer[i][2].flCycle;
// UNDONE: Do IK here.
CalcPose( hdr, NULL, pos2, q2, m_Layer[i][2].nSequence, fCycle, poseparam );
if (fWeight > 1)
fWeight = 1;
SlerpBones( hdr, q, pos, pseqdesc, q2, pos2, fWeight );
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", pseqdesc->pszLabel(), fCycle, fWeight );
}
else
{
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", " ", 0, 0 );
}
}
#endif
CIKContext auto_ik;
auto_ik.Init( hdr, GetRenderAngles(), GetRenderOrigin(), gpGlobals->curtime );
CalcAutoplaySequences( hdr, &auto_ik, pos, q, poseparam, boneMask, currentTime );
float controllers[MAXSTUDIOBONECTRLS];
GetBoneControllers(controllers);
CalcBoneAdj( hdr, pos, q, controllers );
#endif
}
#endif

View File

@ -0,0 +1,174 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "c_AI_BaseNPC.h"
#include "engine/IVDebugOverlay.h"
#if defined( HL2_DLL ) || defined( HL2_EPISODIC )
#include "c_basehlplayer.h"
#endif
#include "death_pose.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define PING_MAX_TIME 2.0
IMPLEMENT_CLIENTCLASS_DT( C_AI_BaseNPC, DT_AI_BaseNPC, CAI_BaseNPC )
RecvPropInt( RECVINFO( m_lifeState ) ),
RecvPropBool( RECVINFO( m_bPerformAvoidance ) ),
RecvPropBool( RECVINFO( m_bIsMoving ) ),
RecvPropBool( RECVINFO( m_bFadeCorpse ) ),
RecvPropInt( RECVINFO ( m_iDeathPose) ),
RecvPropInt( RECVINFO( m_iDeathFrame) ),
RecvPropInt( RECVINFO( m_iSpeedModRadius ) ),
RecvPropInt( RECVINFO( m_iSpeedModSpeed ) ),
RecvPropInt( RECVINFO( m_bSpeedModActive ) ),
RecvPropBool( RECVINFO( m_bImportanRagdoll ) ),
RecvPropFloat( RECVINFO( m_flTimePingEffect ) ),
END_RECV_TABLE()
extern ConVar cl_npc_speedmod_intime;
bool NPC_IsImportantNPC( C_BaseAnimating *pAnimating )
{
C_AI_BaseNPC *pBaseNPC = dynamic_cast < C_AI_BaseNPC* > ( pAnimating );
if ( pBaseNPC == NULL )
return false;
return pBaseNPC->ImportantRagdoll();
}
C_AI_BaseNPC::C_AI_BaseNPC()
{
}
//-----------------------------------------------------------------------------
// Makes ragdolls ignore npcclip brushes
//-----------------------------------------------------------------------------
unsigned int C_AI_BaseNPC::PhysicsSolidMaskForEntity( void ) const
{
// This allows ragdolls to move through npcclip brushes
if ( !IsRagdoll() )
{
return MASK_NPCSOLID;
}
return MASK_SOLID;
}
void C_AI_BaseNPC::ClientThink( void )
{
BaseClass::ClientThink();
#ifdef HL2_DLL
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
if ( ShouldModifyPlayerSpeed() == true )
{
if ( pPlayer )
{
float flDist = (GetAbsOrigin() - pPlayer->GetAbsOrigin()).LengthSqr();
if ( flDist <= GetSpeedModifyRadius() )
{
if ( pPlayer->m_hClosestNPC )
{
if ( pPlayer->m_hClosestNPC != this )
{
float flDistOther = (pPlayer->m_hClosestNPC->GetAbsOrigin() - pPlayer->GetAbsOrigin()).Length();
//If I'm closer than the other NPC then replace it with myself.
if ( flDist < flDistOther )
{
pPlayer->m_hClosestNPC = this;
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
}
}
}
else
{
pPlayer->m_hClosestNPC = this;
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
}
}
}
}
#endif // HL2_DLL
#ifdef HL2_EPISODIC
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
if ( pPlayer && m_flTimePingEffect > gpGlobals->curtime )
{
float fPingEffectTime = m_flTimePingEffect - gpGlobals->curtime;
if ( fPingEffectTime > 0.0f )
{
Vector vRight, vUp;
Vector vMins, vMaxs;
float fFade;
if( fPingEffectTime <= 1.0f )
{
fFade = 1.0f - (1.0f - fPingEffectTime);
}
else
{
fFade = 1.0f;
}
GetRenderBounds( vMins, vMaxs );
AngleVectors (pPlayer->GetAbsAngles(), NULL, &vRight, &vUp );
Vector p1 = GetAbsOrigin() + vRight * vMins.x + vUp * vMins.z;
Vector p2 = GetAbsOrigin() + vRight * vMaxs.x + vUp * vMins.z;
Vector p3 = GetAbsOrigin() + vUp * vMaxs.z;
int r = 0 * fFade;
int g = 255 * fFade;
int b = 0 * fFade;
debugoverlay->AddLineOverlay( p1, p2, r, g, b, true, 0.05f );
debugoverlay->AddLineOverlay( p2, p3, r, g, b, true, 0.05f );
debugoverlay->AddLineOverlay( p3, p1, r, g, b, true, 0.05f );
}
}
#endif
}
void C_AI_BaseNPC::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );
if ( ( ShouldModifyPlayerSpeed() == true ) || ( m_flTimePingEffect > gpGlobals->curtime ) )
{
SetNextClientThink( CLIENT_THINK_ALWAYS );
}
}
void C_AI_BaseNPC::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt )
{
ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt );
GetRagdollCurSequenceWithDeathPose( this, pDeltaBones1, gpGlobals->curtime, m_iDeathPose, m_iDeathFrame );
float ragdollCreateTime = PhysGetSyncCreateTime();
if ( ragdollCreateTime != gpGlobals->curtime )
{
// The next simulation frame begins before the end of this frame
// so initialize the ragdoll at that time so that it will reach the current
// position at curtime. Otherwise the ragdoll will simulate forward from curtime
// and pop into the future a bit at this point of transition
ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime );
}
else
{
SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime );
}
}

View File

@ -0,0 +1,61 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_AI_BASENPC_H
#define C_AI_BASENPC_H
#ifdef _WIN32
#pragma once
#endif
#include "c_basecombatcharacter.h"
// NOTE: MOved all controller code into c_basestudiomodel
class C_AI_BaseNPC : public C_BaseCombatCharacter
{
DECLARE_CLASS( C_AI_BaseNPC, C_BaseCombatCharacter );
public:
DECLARE_CLIENTCLASS();
C_AI_BaseNPC();
virtual unsigned int PhysicsSolidMaskForEntity( void ) const;
virtual bool IsNPC( void ) { return true; }
bool IsMoving( void ){ return m_bIsMoving; }
bool ShouldAvoidObstacle( void ){ return m_bPerformAvoidance; }
virtual bool AddRagdollToFadeQueue( void ) { return m_bFadeCorpse; }
virtual void GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt );
int GetDeathPose( void ) { return m_iDeathPose; }
bool ShouldModifyPlayerSpeed( void ) { return m_bSpeedModActive; }
int GetSpeedModifyRadius( void ) { return m_iSpeedModRadius; }
int GetSpeedModifySpeed( void ) { return m_iSpeedModSpeed; }
void ClientThink( void );
void OnDataChanged( DataUpdateType_t type );
bool ImportantRagdoll( void ) { return m_bImportanRagdoll; }
private:
C_AI_BaseNPC( const C_AI_BaseNPC & ); // not defined, not accessible
float m_flTimePingEffect;
int m_iDeathPose;
int m_iDeathFrame;
int m_iSpeedModRadius;
int m_iSpeedModSpeed;
bool m_bPerformAvoidance;
bool m_bIsMoving;
bool m_bFadeCorpse;
bool m_bSpeedModActive;
bool m_bImportanRagdoll;
};
#endif // C_AI_BASENPC_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,742 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $NoKeywords: $
//=============================================================================//
#ifndef C_BASEANIMATING_H
#define C_BASEANIMATING_H
#ifdef _WIN32
#pragma once
#endif
#include "c_baseentity.h"
#include "studio.h"
#include "UtlVector.h"
#include "ragdoll.h"
#include "mouthinfo.h"
// Shared activities
#include "ai_activity.h"
#include "animationlayer.h"
#include "sequence_transitioner.h"
#include "bone_accessor.h"
#include "bone_merge_cache.h"
#include "ragdoll_shared.h"
#include "tier0/threadtools.h"
#include "datacache/idatacache.h"
#define LIPSYNC_POSEPARAM_NAME "mouth"
#define NUM_HITBOX_FIRES 10
/*
class C_BaseClientShader
{
virtual void RenderMaterial( C_BaseEntity *pEntity, int count, const vec4_t *verts, const vec4_t *normals, const vec2_t *texcoords, vec4_t *lightvalues );
};
*/
class IRagdoll;
class CIKContext;
class CIKState;
class ConVar;
class C_RopeKeyframe;
class CBoneBitList;
class CBoneList;
class KeyValues;
class CJiggleBones;
FORWARD_DECLARE_HANDLE( memhandle_t );
typedef unsigned short MDLHandle_t;
extern ConVar vcollide_wireframe;
struct ClientModelRenderInfo_t : public ModelRenderInfo_t
{
// Added space for lighting origin override. Just allocated space, need to set base pointer
matrix3x4_t lightingOffset;
// Added space for model to world matrix. Just allocated space, need to set base pointer
matrix3x4_t modelToWorld;
};
struct RagdollInfo_t
{
bool m_bActive;
float m_flSaveTime;
int m_nNumBones;
Vector m_rgBonePos[MAXSTUDIOBONES];
Quaternion m_rgBoneQuaternion[MAXSTUDIOBONES];
};
class CAttachmentData
{
public:
matrix3x4_t m_AttachmentToWorld;
QAngle m_angRotation;
Vector m_vOriginVelocity;
int m_nLastFramecount : 31;
int m_bAnglesComputed : 1;
};
typedef unsigned int ClientSideAnimationListHandle_t;
#define INVALID_CLIENTSIDEANIMATION_LIST_HANDLE (ClientSideAnimationListHandle_t)~0
class C_BaseAnimating : public C_BaseEntity
{
public:
DECLARE_CLASS( C_BaseAnimating, C_BaseEntity );
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
DECLARE_INTERPOLATION();
enum
{
NUM_POSEPAREMETERS = 24,
NUM_BONECTRLS = 4
};
C_BaseAnimating();
~C_BaseAnimating();
virtual C_BaseAnimating* GetBaseAnimating() { return this; }
bool UsesPowerOfTwoFrameBufferTexture( void );
virtual bool Interpolate( float currentTime );
virtual void Simulate();
virtual void Release();
float GetAnimTimeInterval( void ) const;
virtual unsigned char GetClientSideFade( void );
// Get bone controller values.
virtual void GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS]);
virtual float SetBoneController ( int iController, float flValue );
LocalFlexController_t GetNumFlexControllers( void );
const char *GetFlexDescFacs( int iFlexDesc );
const char *GetFlexControllerName( LocalFlexController_t iFlexController );
const char *GetFlexControllerType( LocalFlexController_t iFlexController );
virtual void GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pAbsOrigin, QAngle *pAbsAngles );
// Computes a box that surrounds all hitboxes
bool ComputeHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
bool ComputeEntitySpaceHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
// Gets the hitbox-to-world transforms, returns false if there was a problem
bool HitboxToWorldTransforms( matrix3x4_t *pHitboxToWorld[MAXSTUDIOBONES] );
// base model functionality
float ClampCycle( float cycle, bool isLooping );
virtual void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] );
virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform );
virtual int VPhysicsGetObjectList( IPhysicsObject **pList, int listMax );
// model specific
virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime );
virtual void UpdateIKLocks( float currentTime );
virtual void CalculateIKLocks( float currentTime );
virtual int DrawModel( int flags );
virtual int InternalDrawModel( int flags );
virtual bool OnInternalDrawModel( ClientModelRenderInfo_t *pInfo );
virtual bool OnPostInternalDrawModel( ClientModelRenderInfo_t *pInfo );
void DoInternalDrawModel( ClientModelRenderInfo_t *pInfo, DrawModelState_t *pState, matrix3x4_t *pBoneToWorldArray = NULL );
//
virtual CMouthInfo *GetMouth();
virtual void ControlMouth( CStudioHdr *pStudioHdr );
// override in sub-classes
virtual void DoAnimationEvents( CStudioHdr *pStudio );
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
virtual void FireObsoleteEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
// Parses and distributes muzzle flash events
virtual bool DispatchMuzzleEffect( const char *options, bool isFirstPerson );
// virtual void AllocateMaterials( void );
// virtual void FreeMaterials( void );
virtual CStudioHdr *OnNewModel( void );
CStudioHdr *GetModelPtr() const;
void InvalidateMdlCache();
virtual void SetPredictable( bool state );
void UseClientSideAnimation();
// C_BaseClientShader **p_ClientShaders;
virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
void UnragdollBlend( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime );
void MaintainSequenceTransitions( CStudioHdr *hdr, float flCycle, float flPoseParameter[], Vector pos[], Quaternion q[], int boneMask );
virtual void AccumulateLayers( CStudioHdr *hdr, Vector pos[], Quaternion q[], float poseparam[], float currentTime, int boneMask );
// Attachments
int LookupAttachment( const char *pAttachmentName );
int LookupRandomAttachment( const char *pAttachmentNameSubstring );
int LookupPoseParameter( CStudioHdr *pStudioHdr, const char *szName );
inline int LookupPoseParameter( const char *szName ) { return LookupPoseParameter(GetModelPtr(), szName); }
float SetPoseParameter( CStudioHdr *pStudioHdr, const char *szName, float flValue );
inline float SetPoseParameter( const char *szName, float flValue ) { return SetPoseParameter( GetModelPtr(), szName, flValue ); }
float SetPoseParameter( CStudioHdr *pStudioHdr, int iParameter, float flValue );
inline float SetPoseParameter( int iParameter, float flValue ) { return SetPoseParameter( GetModelPtr(), iParameter, flValue ); }
float GetPoseParameter( int iPoseParameter );
bool GetPoseParameterRange( int iPoseParameter, float &minValue, float &maxValue );
int LookupBone( const char *szName );
void GetBonePosition( int iBone, Vector &origin, QAngle &angles );
void GetBoneTransform( int iBone, matrix3x4_t &pBoneToWorld );
//bool solveIK(float a, float b, const Vector &Foot, const Vector &Knee1, Vector &Knee2);
//void DebugIK( mstudioikchain_t *pikchain );
virtual void PreDataUpdate( DataUpdateType_t updateType );
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
virtual void OnPreDataChanged( DataUpdateType_t updateType );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void AddEntity( void );
// This can be used to force client side animation to be on. Only use if you know what you're doing!
// Normally, the server entity should set this.
void ForceClientSideAnimationOn();
void AddToClientSideAnimationList();
void RemoveFromClientSideAnimationList();
virtual bool IsSelfAnimating();
virtual void ResetLatched();
// implements these so ragdolls can handle frustum culling & leaf visibility
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
virtual const Vector& GetRenderOrigin( void );
virtual const QAngle& GetRenderAngles( void );
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
// Attachments.
bool GetAttachment( const char *szName, Vector &absOrigin );
bool GetAttachment( const char *szName, Vector &absOrigin, QAngle &absAngles );
// Inherited from C_BaseEntity
virtual bool GetAttachment( int number, Vector &origin );
virtual bool GetAttachment( int number, Vector &origin, QAngle &angles );
virtual bool GetAttachment( int number, matrix3x4_t &matrix );
virtual bool GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel );
// Returns the attachment in local space
bool GetAttachmentLocal( int iAttachment, matrix3x4_t &attachmentToLocal );
bool GetAttachmentLocal( int iAttachment, Vector &origin, QAngle &angles );
bool GetAttachmentLocal( int iAttachment, Vector &origin );
// Should this object cast render-to-texture shadows?
virtual ShadowType_t ShadowCastType();
// Should we collide?
virtual CollideType_t GetCollideType( void );
virtual bool TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
// returns true if we're currently being ragdolled
bool IsRagdoll() const;
virtual C_BaseAnimating *BecomeRagdollOnClient();
C_BaseAnimating *CreateRagdollCopy();
bool InitAsClientRagdoll( const matrix3x4_t *pDeltaBones0, const matrix3x4_t *pDeltaBones1, const matrix3x4_t *pCurrentBonePosition, float boneDt );
void IgniteRagdoll( C_BaseAnimating *pSource );
void TransferDissolveFrom( C_BaseAnimating *pSource );
virtual void SaveRagdollInfo( int numbones, const matrix3x4_t &cameraTransform, CBoneAccessor &pBoneToWorld );
virtual bool RetrieveRagdollInfo( Vector *pos, Quaternion *q );
virtual void Clear( void );
void ClearRagdoll();
void CreateUnragdollInfo( C_BaseAnimating *pRagdoll );
void ForceSetupBonesAtTime( matrix3x4_t *pBonesOut, float flTime );
virtual void GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt );
// For shadows rendering the correct body + sequence...
virtual int GetBody() { return m_nBody; }
virtual int GetSkin() { return m_nSkin; }
bool IsOnFire() { return ( (GetFlags() & FL_ONFIRE) != 0 ); }
inline float GetPlaybackRate();
inline void SetPlaybackRate( float rate );
void SetModelWidthScale( float scale );
float GetModelWidthScale() const;
int GetSequence();
void SetSequence(int nSequence);
inline void ResetSequence(int nSequence);
float GetSequenceGroundSpeed( CStudioHdr *pStudioHdr, int iSequence );
inline float GetSequenceGroundSpeed( int iSequence ) { return GetSequenceGroundSpeed(GetModelPtr(), iSequence); }
bool IsSequenceLooping( CStudioHdr *pStudioHdr, int iSequence );
inline bool IsSequenceLooping( int iSequence ) { return IsSequenceLooping(GetModelPtr(),iSequence); }
float GetSequenceMoveDist( CStudioHdr *pStudioHdr, int iSequence );
void GetSequenceLinearMotion( int iSequence, Vector *pVec );
void GetBlendedLinearVelocity( Vector *pVec );
int LookupSequence ( const char *label );
int LookupActivity( const char *label );
char const *GetSequenceName( int iSequence );
char const *GetSequenceActivityName( int iSequence );
Activity GetSequenceActivity( int iSequence );
virtual void StudioFrameAdvance(); // advance animation frame to some time in the future
// Clientside animation
virtual float FrameAdvance( float flInterval = 0.0f );
virtual float GetSequenceCycleRate( CStudioHdr *pStudioHdr, int iSequence );
virtual void UpdateClientSideAnimation();
void ClientSideAnimationChanged();
virtual unsigned int ComputeClientSideAnimationFlags();
void SetCycle( float flCycle );
float GetCycle() const;
void SetBodygroup( int iGroup, int iValue );
int GetBodygroup( int iGroup );
const char *GetBodygroupName( int iGroup );
int FindBodygroupByName( const char *name );
int GetBodygroupCount( int iGroup );
int GetNumBodyGroups( void );
class CBoneCache *GetBoneCache( CStudioHdr *pStudioHdr );
void SetHitboxSet( int setnum );
void SetHitboxSetByName( const char *setname );
int GetHitboxSet( void );
char const *GetHitboxSetName( void );
int GetHitboxSetCount( void );
void DrawClientHitboxes( float duration = 0.0f, bool monocolor = false );
C_BaseAnimating* FindFollowedEntity();
virtual bool IsActivityFinished( void ) { return m_bSequenceFinished; }
inline bool IsSequenceFinished( void );
inline bool SequenceLoops( void ) { return m_bSequenceLoops; }
// All view model attachments origins are stretched so you can place entities at them and
// they will match up with where the attachment winds up being drawn on the view model, since
// the view models are drawn with a different FOV.
//
// If you're drawing something inside of a view model's DrawModel() function, then you want the
// original attachment origin instead of the adjusted one. To get that, call this on the
// adjusted attachment origin.
virtual void UncorrectViewModelAttachment( Vector &vOrigin ) {}
// Call this if SetupBones() has already been called this frame but you need to move the
// entity and rerender.
void InvalidateBoneCache();
bool IsBoneCacheValid() const; // Returns true if the bone cache is considered good for this frame.
void GetCachedBoneMatrix( int boneIndex, matrix3x4_t &out );
// Wrappers for CBoneAccessor.
const matrix3x4_t& GetBone( int iBone ) const;
matrix3x4_t& GetBoneForWrite( int iBone );
// Used for debugging. Will produce asserts if someone tries to setup bones or
// attachments before it's allowed.
// Use the "AutoAllowBoneAccess" class to auto push/pop bone access.
// Use a distinct "tag" when pushing/popping - asserts when push/pop tags do not match.
struct AutoAllowBoneAccess
{
AutoAllowBoneAccess( bool bAllowForNormalModels, bool bAllowForViewModels );
~AutoAllowBoneAccess( void );
};
static void PushAllowBoneAccess( bool bAllowForNormalModels, bool bAllowForViewModels, char const *tagPush );
static void PopBoneAccess( char const *tagPop );
static void ThreadedBoneSetup();
static void InitBoneSetupThreadPool();
static void ShutdownBoneSetupThreadPool();
// Invalidate bone caches so all SetupBones() calls force bone transforms to be regenerated.
static void InvalidateBoneCaches();
// Purpose: My physics object has been updated, react or extract data
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
void DisableMuzzleFlash(); // Turn off the muzzle flash (ie: signal that we handled the server's event).
virtual void DoMuzzleFlash(); // Force a muzzle flash event. Note: this only QUEUES an event, so
// ProcessMuzzleFlashEvent will get called later.
bool ShouldMuzzleFlash() const; // Is the muzzle flash event on?
// This is called to do the actual muzzle flash effect.
virtual void ProcessMuzzleFlashEvent();
// Update client side animations
static void UpdateClientSideAnimations();
// Load the model's keyvalues section and create effects listed inside it
void InitModelEffects( void );
// Sometimes the server wants to update the client's cycle to get the two to run in sync (for proper hit detection)
virtual void SetServerIntendedCycle( float intended ) { intended; }
virtual float GetServerIntendedCycle( void ) { return -1.0f; }
// For prediction
int SelectWeightedSequence ( int activity );
void ResetSequenceInfo( void );
float SequenceDuration( void );
float SequenceDuration( CStudioHdr *pStudioHdr, int iSequence );
inline float SequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); }
int FindTransitionSequence( int iCurrentSequence, int iGoalSequence, int *piDir );
void RagdollMoved( void );
virtual void GetToolRecordingState( KeyValues *msg );
virtual void CleanupToolRecordingState( KeyValues *msg );
void SetReceivedSequence( void );
virtual bool ShouldResetSequenceOnNewModel( void );
virtual bool IsViewModel() const;
protected:
// View models scale their attachment positions to account for FOV. To get the unmodified
// attachment position (like if you're rendering something else during the view model's DrawModel call),
// use TransformViewModelAttachmentToWorld.
virtual void FormatViewModelAttachment( int nAttachment, matrix3x4_t &attachmentToWorld ) {}
// View models say yes to this.
bool IsBoneAccessAllowed() const;
CMouthInfo& MouthInfo();
// Models used in a ModelPanel say yes to this
virtual bool IsMenuModel() const;
// Allow studio models to tell C_BaseEntity what their m_nBody value is
virtual int GetStudioBody( void ) { return m_nBody; }
virtual bool CalcAttachments();
private:
// This method should return true if the bones have changed + SetupBones needs to be called
virtual float LastBoneChangedTime() { return FLT_MAX; }
CBoneList* RecordBones( CStudioHdr *hdr, matrix3x4_t *pBoneState );
bool PutAttachment( int number, const matrix3x4_t &attachmentToWorld );
void TermRopes();
void DelayedInitModelEffects( void );
void UpdateRelevantInterpolatedVars();
void AddBaseAnimatingInterpolatedVars();
void RemoveBaseAnimatingInterpolatedVars();
void LockStudioHdr();
void UnlockStudioHdr();
public:
CRagdoll *m_pRagdoll;
// Texture group to use
int m_nSkin;
// Object bodygroup
int m_nBody;
// Hitbox set to use (default 0)
int m_nHitboxSet;
CSequenceTransitioner m_SequenceTransitioner;
protected:
CIKContext *m_pIk;
int m_iEyeAttachment;
// Animation playback framerate
float m_flPlaybackRate;
// Decomposed ragdoll info
bool m_bStoreRagdollInfo;
RagdollInfo_t *m_pRagdollInfo;
Vector m_vecForce;
int m_nForceBone;
// Is bone cache valid
// bone transformation matrix
unsigned long m_iMostRecentModelBoneCounter;
unsigned long m_iMostRecentBoneSetupRequest;
int m_iPrevBoneMask;
int m_iAccumulatedBoneMask;
CBoneAccessor m_BoneAccessor;
CThreadFastMutex m_BoneSetupLock;
ClientSideAnimationListHandle_t m_ClientSideAnimationListHandle;
// Client-side animation
bool m_bClientSideFrameReset;
protected:
float m_fadeMinDist;
float m_fadeMaxDist;
float m_flFadeScale;
private:
float m_flGroundSpeed; // computed linear movement rate for current sequence
float m_flLastEventCheck; // cycle index of when events were last checked
bool m_bSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry
bool m_bSequenceLoops; // true if the sequence loops
// Mouth lipsync/envelope following values
CMouthInfo m_mouth;
CNetworkVar( float, m_flModelWidthScale );
// Animation blending factors
float m_flPoseParameter[MAXSTUDIOPOSEPARAM];
CInterpolatedVarArray< float, MAXSTUDIOPOSEPARAM > m_iv_flPoseParameter;
float m_flOldPoseParameters[MAXSTUDIOPOSEPARAM];
int m_nPrevSequence;
int m_nRestoreSequence;
// Ropes that got spawned when the model was created.
CUtlLinkedList<C_RopeKeyframe*,unsigned short> m_Ropes;
// event processing info
float m_flPrevEventCycle;
int m_nEventSequence;
float m_flEncodedController[MAXSTUDIOBONECTRLS];
CInterpolatedVarArray< float, MAXSTUDIOBONECTRLS > m_iv_flEncodedController;
float m_flOldEncodedController[MAXSTUDIOBONECTRLS];
// Clientside animation
bool m_bClientSideAnimation;
bool m_bLastClientSideFrameReset;
int m_nNewSequenceParity;
int m_nResetEventsParity;
int m_nPrevNewSequenceParity;
int m_nPrevResetEventsParity;
bool m_builtRagdoll;
Vector m_vecPreRagdollMins;
Vector m_vecPreRagdollMaxs;
// Current animation sequence
int m_nSequence;
bool m_bReceivedSequence;
// Current cycle location from server
protected:
float m_flCycle;
CInterpolatedVar< float > m_iv_flCycle;
float m_flOldCycle;
private:
int m_nOldSequence;
CBoneMergeCache *m_pBoneMergeCache; // This caches the strcmp lookups that it has to do
// when merg
CUtlVector< matrix3x4_t > m_CachedBoneData; // never access this directly. Use m_BoneAccessor.
memhandle_t m_hitboxBoneCacheHandle;
float m_flLastBoneSetupTime;
CJiggleBones *m_pJiggleBones;
// Calculated attachment points
CUtlVector<CAttachmentData> m_Attachments;
void SetupBones_AttachmentHelper( CStudioHdr *pStudioHdr );
EHANDLE m_hLightingOrigin;
EHANDLE m_hLightingOriginRelative;
// These are compared against each other to determine if the entity should muzzle flash.
CNetworkVar( unsigned char, m_nMuzzleFlashParity );
unsigned char m_nOldMuzzleFlashParity;
bool m_bInitModelEffects;
private:
mutable CStudioHdr *m_pStudioHdr;
mutable MDLHandle_t m_hStudioHdr;
CThreadFastMutex m_StudioHdrInitLock;
};
enum
{
RAGDOLL_FRICTION_OFF = -2,
RAGDOLL_FRICTION_NONE,
RAGDOLL_FRICTION_IN,
RAGDOLL_FRICTION_HOLD,
RAGDOLL_FRICTION_OUT,
};
class C_ClientRagdoll : public C_BaseAnimating, public IPVSNotify
{
public:
C_ClientRagdoll( bool bRestoring = true );
DECLARE_CLASS( C_ClientRagdoll, C_BaseAnimating );
DECLARE_DATADESC();
// inherited from IPVSNotify
virtual void OnPVSStatusChanged( bool bInPVS );
virtual void Release( void );
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
virtual void ImpactTrace( trace_t *pTrace, int iDamageType, char *pCustomImpactName );
void ClientThink( void );
void ReleaseRagdoll( void ) { m_bReleaseRagdoll = true; }
bool ShouldSavePhysics( void ) { return true; }
virtual void OnSave();
virtual void OnRestore();
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | FCAP_SAVE_NON_NETWORKABLE; }
virtual IPVSNotify* GetPVSNotifyInterface() { return this; }
void HandleAnimatedFriction( void );
virtual void SUB_Remove( void );
void FadeOut( void );
virtual float LastBoneChangedTime();
bool m_bFadeOut;
bool m_bImportant;
float m_flEffectTime;
private:
int m_iCurrentFriction;
int m_iMinFriction;
int m_iMaxFriction;
float m_flFrictionModTime;
float m_flFrictionTime;
int m_iFrictionAnimState;
bool m_bReleaseRagdoll;
bool m_bFadingOut;
float m_flScaleEnd[NUM_HITBOX_FIRES];
float m_flScaleTimeStart[NUM_HITBOX_FIRES];
float m_flScaleTimeEnd[NUM_HITBOX_FIRES];
};
//-----------------------------------------------------------------------------
// Purpose: Serves the 90% case of calling SetSequence / ResetSequenceInfo.
//-----------------------------------------------------------------------------
inline void C_BaseAnimating::ResetSequence(int nSequence)
{
SetSequence( nSequence );
ResetSequenceInfo();
}
inline float C_BaseAnimating::GetPlaybackRate()
{
return m_flPlaybackRate;
}
inline void C_BaseAnimating::SetPlaybackRate( float rate )
{
m_flPlaybackRate = rate;
}
inline const matrix3x4_t& C_BaseAnimating::GetBone( int iBone ) const
{
return m_BoneAccessor.GetBone( iBone );
}
inline matrix3x4_t& C_BaseAnimating::GetBoneForWrite( int iBone )
{
return m_BoneAccessor.GetBoneForWrite( iBone );
}
inline bool C_BaseAnimating::ShouldMuzzleFlash() const
{
return m_nOldMuzzleFlashParity != m_nMuzzleFlashParity;
}
inline float C_BaseAnimating::GetCycle() const
{
return m_flCycle;
}
//-----------------------------------------------------------------------------
// Purpose: return a pointer to an updated studiomdl cache cache
//-----------------------------------------------------------------------------
inline CStudioHdr *C_BaseAnimating::GetModelPtr() const
{
#ifdef _DEBUG
// GetModelPtr() is often called before OnNewModel() so go ahead and set it up first chance.
static IDataCacheSection *pModelCache = datacache->FindSection( "ModelData" );
AssertOnce( pModelCache->IsFrameLocking() );
#endif
if ( !m_pStudioHdr && GetModel() )
{
const_cast<C_BaseAnimating *>(this)->LockStudioHdr();
}
return ( m_pStudioHdr && m_pStudioHdr->IsValid() ) ? m_pStudioHdr : NULL;
}
inline void C_BaseAnimating::InvalidateMdlCache()
{
UnlockStudioHdr();
if ( m_pStudioHdr != NULL )
{
delete m_pStudioHdr;
m_pStudioHdr = NULL;
}
}
//-----------------------------------------------------------------------------
// Sequence access
//-----------------------------------------------------------------------------
inline int C_BaseAnimating::GetSequence()
{
return m_nSequence;
}
inline bool C_BaseAnimating::IsSequenceFinished( void )
{
return m_bSequenceFinished;
}
inline float C_BaseAnimating::SequenceDuration( void )
{
return SequenceDuration( GetSequence() );
}
//-----------------------------------------------------------------------------
// Mouth
//-----------------------------------------------------------------------------
inline CMouthInfo& C_BaseAnimating::MouthInfo()
{
return m_mouth;
}
// FIXME: move these to somewhere that makes sense
void GetColumn( matrix3x4_t& src, int column, Vector &dest );
void SetColumn( Vector &src, int column, matrix3x4_t& dest );
EXTERN_RECV_TABLE(DT_BaseAnimating);
extern void DevMsgRT( char const* pMsg, ... );
#endif // C_BASEANIMATING_H

View File

@ -0,0 +1,566 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "c_baseanimatingoverlay.h"
#include "bone_setup.h"
#include "tier0/vprof.h"
#include "engine/IVDebugOverlay.h"
#include "datacache/imdlcache.h"
#include "eventlist.h"
#include "dt_utlvector_recv.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern ConVar r_sequence_debug;
C_BaseAnimatingOverlay::C_BaseAnimatingOverlay()
{
// FIXME: where does this initialization go now?
//for ( int i=0; i < MAX_OVERLAYS; i++ )
//{
// memset( &m_Layer[i], 0, sizeof(m_Layer[0]) );
// m_Layer[i].m_nOrder = MAX_OVERLAYS;
//}
// FIXME: where does this initialization go now?
// AddVar( m_Layer, &m_iv_AnimOverlay, LATCH_ANIMATION_VAR );
}
#undef CBaseAnimatingOverlay
BEGIN_RECV_TABLE_NOBASE(CAnimationLayer, DT_Animationlayer)
RecvPropInt( RECVINFO_NAME(m_nSequence, m_nSequence)),
RecvPropFloat( RECVINFO_NAME(m_flCycle, m_flCycle)),
RecvPropFloat( RECVINFO_NAME(m_flPrevCycle, m_flPrevCycle)),
RecvPropFloat( RECVINFO_NAME(m_flWeight, m_flWeight)),
RecvPropInt( RECVINFO_NAME(m_nOrder, m_nOrder))
END_RECV_TABLE()
const char *s_m_iv_AnimOverlayNames[C_BaseAnimatingOverlay::MAX_OVERLAYS] =
{
"C_BaseAnimatingOverlay::m_iv_AnimOverlay00",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay01",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay02",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay03",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay04",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay05",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay06",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay07",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay08",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay09",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay10",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay11",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay12",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay13",
"C_BaseAnimatingOverlay::m_iv_AnimOverlay14"
};
void ResizeAnimationLayerCallback( void *pStruct, int offsetToUtlVector, int len )
{
C_BaseAnimatingOverlay *pEnt = (C_BaseAnimatingOverlay*)pStruct;
CUtlVector < C_AnimationLayer > *pVec = &pEnt->m_AnimOverlay;
CUtlVector< CInterpolatedVar< C_AnimationLayer > > *pVecIV = &pEnt->m_iv_AnimOverlay;
Assert( (char*)pVec - (char*)pEnt == offsetToUtlVector );
Assert( pVec->Count() == pVecIV->Count() );
Assert( pVec->Count() <= C_BaseAnimatingOverlay::MAX_OVERLAYS );
int diff = len - pVec->Count();
if ( diff == 0 )
return;
// remove all entries
for ( int i=0; i < pVec->Count(); i++ )
{
pEnt->RemoveVar( &pVec->Element( i ) );
}
// adjust vector sizes
if ( diff > 0 )
{
pVec->AddMultipleToTail( diff );
pVecIV->AddMultipleToTail( diff );
}
else
{
pVec->RemoveMultiple( len, -diff );
pVecIV->RemoveMultiple( len, -diff );
}
// Rebind all the variables in the ent's list.
for ( int i=0; i < len; i++ )
{
IInterpolatedVar *pWatcher = &pVecIV->Element( i );
pWatcher->SetDebugName( s_m_iv_AnimOverlayNames[i] );
pEnt->AddVar( &pVec->Element( i ), pWatcher, LATCH_ANIMATION_VAR, true );
}
// FIXME: need to set historical values of nOrder in pVecIV to MAX_OVERLAY
}
BEGIN_RECV_TABLE_NOBASE( C_BaseAnimatingOverlay, DT_OverlayVars )
RecvPropUtlVector(
RECVINFO_UTLVECTOR_SIZEFN( m_AnimOverlay, ResizeAnimationLayerCallback ),
C_BaseAnimatingOverlay::MAX_OVERLAYS,
RecvPropDataTable(NULL, 0, 0, &REFERENCE_RECV_TABLE( DT_Animationlayer ) ) )
END_RECV_TABLE()
IMPLEMENT_CLIENTCLASS_DT( C_BaseAnimatingOverlay, DT_BaseAnimatingOverlay, CBaseAnimatingOverlay )
RecvPropDataTable( "overlay_vars", 0, 0, &REFERENCE_RECV_TABLE( DT_OverlayVars ) )
END_RECV_TABLE()
BEGIN_PREDICTION_DATA( C_BaseAnimatingOverlay )
/*
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_nSequence, FIELD_INTEGER ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flCycle, FIELD_FLOAT ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flPlaybackRate, FIELD_FLOAT),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flWeight, FIELD_FLOAT),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_nSequence, FIELD_INTEGER ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flCycle, FIELD_FLOAT ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flPlaybackRate, FIELD_FLOAT),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flWeight, FIELD_FLOAT),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_nSequence, FIELD_INTEGER ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flCycle, FIELD_FLOAT ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flPlaybackRate, FIELD_FLOAT),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flWeight, FIELD_FLOAT),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_nSequence, FIELD_INTEGER ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flCycle, FIELD_FLOAT ),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flPlaybackRate, FIELD_FLOAT),
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flWeight, FIELD_FLOAT),
*/
END_PREDICTION_DATA()
C_AnimationLayer* C_BaseAnimatingOverlay::GetAnimOverlay( int i )
{
Assert( i >= 0 && i < MAX_OVERLAYS );
return &m_AnimOverlay[i];
}
void C_BaseAnimatingOverlay::SetNumAnimOverlays( int num )
{
if ( m_AnimOverlay.Count() < num )
{
m_AnimOverlay.AddMultipleToTail( num - m_AnimOverlay.Count() );
}
else if ( m_AnimOverlay.Count() > num )
{
m_AnimOverlay.RemoveMultiple( num, m_AnimOverlay.Count() - num );
}
}
int C_BaseAnimatingOverlay::GetNumAnimOverlays() const
{
return m_AnimOverlay.Count();
}
void C_BaseAnimatingOverlay::GetRenderBounds( Vector& theMins, Vector& theMaxs )
{
BaseClass::GetRenderBounds( theMins, theMaxs );
if ( !IsRagdoll() )
{
CStudioHdr *pStudioHdr = GetModelPtr();
if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
return;
int nSequences = pStudioHdr->GetNumSeq();
int i;
for (i = 0; i < m_AnimOverlay.Count(); i++)
{
if (m_AnimOverlay[i].m_flWeight > 0.0)
{
if ( m_AnimOverlay[i].m_nSequence >= nSequences )
{
continue;
}
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[i].m_nSequence );
VectorMin( seqdesc.bbmin, theMins, theMins );
VectorMax( seqdesc.bbmax, theMaxs, theMaxs );
}
}
}
}
void C_BaseAnimatingOverlay::CheckForLayerChanges( CStudioHdr *hdr, float currentTime )
{
CDisableRangeChecks disableRangeChecks;
bool bLayersChanged = false;
// FIXME: damn, there has to be a better way than this.
int i;
for (i = 0; i < m_iv_AnimOverlay.Count(); i++)
{
CDisableRangeChecks disableRangeChecks;
int iHead, iPrev1, iPrev2;
m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
// fake up previous cycle values.
float t0;
C_AnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
// reset previous
float t1;
C_AnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
// reset previous previous
float t2;
C_AnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
if ( pHead && pPrev1 && pHead->m_nSequence != pPrev1->m_nSequence )
{
bLayersChanged = true;
#if 1 // _DEBUG
if (/* Q_stristr( hdr->pszName(), r_sequence_debug.GetString()) != NULL || */ r_sequence_debug.GetInt() == entindex())
{
DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t0, hdr->pSeqdesc( pHead->m_nSequence ).pszLabel(), (float)pHead->m_flCycle, (float)pHead->m_flWeight, i );
DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t1, hdr->pSeqdesc( pPrev1->m_nSequence ).pszLabel(), (float)pPrev1->m_flCycle, (float)pPrev1->m_flWeight, i );
if (pPrev2)
DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t2, hdr->pSeqdesc( pPrev2->m_nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev2->m_flWeight, i );
}
#endif
if (pPrev1)
{
pPrev1->m_nSequence = pHead->m_nSequence;
pPrev1->m_flCycle = pHead->m_flPrevCycle;
pPrev1->m_flWeight = pHead->m_flWeight;
}
if (pPrev2)
{
float num = 0;
if ( fabs( t0 - t1 ) > 0.001f )
num = (t2 - t1) / (t0 - t1);
pPrev2->m_nSequence = pHead->m_nSequence;
float flTemp;
if (IsSequenceLooping( hdr, pHead->m_nSequence ))
{
flTemp = LoopingLerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
}
else
{
flTemp = Lerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
}
pPrev2->m_flCycle = flTemp;
pPrev2->m_flWeight = pHead->m_flWeight;
}
/*
if (stricmp( r_seq_overlay_debug.GetString(), hdr->name ) == 0)
{
DevMsgRT( "(%30s %6.2f : %6.2f : %6.2f)\n", hdr->pSeqdesc( pHead->nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle );
}
*/
m_iv_AnimOverlay[i].SetLooping( IsSequenceLooping( hdr, pHead->m_nSequence ) );
m_iv_AnimOverlay[i].Interpolate( currentTime );
// reset event indexes
m_flOverlayPrevEventCycle[i] = pHead->m_flPrevCycle - 0.01;
}
}
if (bLayersChanged)
{
// render bounds may have changed
UpdateVisibility();
}
}
void C_BaseAnimatingOverlay::AccumulateLayers( CStudioHdr *hdr, Vector pos[], Quaternion q[], float poseparam[], float currentTime, int boneMask )
{
BaseClass::AccumulateLayers( hdr, pos, q, poseparam, currentTime, boneMask );
int i;
// resort the layers
int layer[MAX_OVERLAYS];
for (i = 0; i < MAX_OVERLAYS; i++)
{
layer[i] = MAX_OVERLAYS;
}
for (i = 0; i < m_AnimOverlay.Count(); i++)
{
if (m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS)
{
/*
Assert( layer[m_AnimOverlay[i].m_nOrder] == MAX_OVERLAYS );
layer[m_AnimOverlay[i].m_nOrder] = i;
*/
// hacky code until initialization of new layers is finished
if (layer[m_AnimOverlay[i].m_nOrder] != MAX_OVERLAYS)
{
m_AnimOverlay[i].m_nOrder = MAX_OVERLAYS;
}
else
{
layer[m_AnimOverlay[i].m_nOrder] = i;
}
}
}
CheckForLayerChanges( hdr, currentTime );
int nSequences = hdr->GetNumSeq();
// add in the overlay layers
int j;
for (j = 0; j < MAX_OVERLAYS; j++)
{
i = layer[ j ];
if (i < m_AnimOverlay.Count())
{
if ( m_AnimOverlay[i].m_nSequence >= nSequences )
{
continue;
}
/*
DevMsgRT( 1 , "%.3f %.3f %.3f\n", currentTime, fWeight, dadt );
debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -j - 1, 0,
"%2d(%s) : %6.2f : %6.2f",
m_AnimOverlay[i].m_nSequence,
hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence )->pszLabel(),
m_AnimOverlay[i].m_flCycle,
m_AnimOverlay[i].m_flWeight
);
*/
float fWeight = m_AnimOverlay[i].m_flWeight;
if (fWeight > 0)
{
// check to see if the sequence changed
// FIXME: move this to somewhere more reasonable
// do a nice spline interpolation of the values
// if ( m_AnimOverlay[i].m_nSequence != m_iv_AnimOverlay.GetPrev( i )->nSequence )
float fCycle = m_AnimOverlay[ i ].m_flCycle;
fCycle = ClampCycle( fCycle, IsSequenceLooping( m_AnimOverlay[i].m_nSequence ) );
if (fWeight > 1)
fWeight = 1;
AccumulatePose( hdr, m_pIk, pos, q, m_AnimOverlay[i].m_nSequence, fCycle, poseparam, boneMask, fWeight, currentTime );
#if 1 // _DEBUG
if (/* Q_stristr( hdr->pszName(), r_sequence_debug.GetString()) != NULL || */ r_sequence_debug.GetInt() == entindex())
{
if (1)
{
DevMsgRT( "%8.4f : %30s : %5.3f : %4.2f : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
}
else
{
int iHead, iPrev1, iPrev2;
m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
// fake up previous cycle values.
float t0;
C_AnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
// reset previous
float t1;
C_AnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
// reset previous previous
float t2;
C_AnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
if ( pHead && pPrev1 && pPrev2 )
{
DevMsgRT( "%6.2f : %30s %6.2f (%6.2f:%6.2f:%6.2f) : %6.2f (%6.2f:%6.2f:%6.2f) : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(),
fCycle, (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle,
fWeight, (float)pPrev2->m_flWeight, (float)pPrev1->m_flWeight, (float)pHead->m_flWeight,
i );
}
else
{
DevMsgRT( "%6.2f : %30s %6.2f : %6.2f : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
}
}
}
#endif
//#define DEBUG_TF2_OVERLAYS
#if defined( DEBUG_TF2_OVERLAYS )
engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
}
else
{
engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
#endif
}
}
#if defined( DEBUG_TF2_OVERLAYS )
else
{
engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
}
#endif
}
}
void C_BaseAnimatingOverlay::DoAnimationEvents( CStudioHdr *pStudioHdr )
{
if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
return;
MDLCACHE_CRITICAL_SECTION();
int nSequences = pStudioHdr->GetNumSeq();
BaseClass::DoAnimationEvents( pStudioHdr );
bool watch = false; // Q_strstr( hdr->name, "rifle" ) ? true : false;
CheckForLayerChanges( pStudioHdr, gpGlobals->curtime ); // !!!
int j;
for (j = 0; j < m_AnimOverlay.Count(); j++)
{
if ( m_AnimOverlay[j].m_nSequence >= nSequences )
{
continue;
}
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[j].m_nSequence );
if ( seqdesc.numevents == 0 )
continue;
// stalled?
if (m_AnimOverlay[j].m_flCycle == m_flOverlayPrevEventCycle[j])
continue;
bool bLoopingSequence = IsSequenceLooping( m_AnimOverlay[j].m_nSequence );
bool bLooped = false;
//in client code, m_flOverlayPrevEventCycle is set to -1 when we first start an overlay, looping or not
if ( bLoopingSequence &&
m_flOverlayPrevEventCycle[j] > 0.0f &&
m_AnimOverlay[j].m_flCycle <= m_flOverlayPrevEventCycle[j] )
{
if (m_flOverlayPrevEventCycle[j] - m_AnimOverlay[j].m_flCycle > 0.5)
{
bLooped = true;
}
else
{
// things have backed up, which is bad since it'll probably result in a hitch in the animation playback
// but, don't play events again for the same time slice
return;
}
}
mstudioevent_t *pevent = seqdesc.pEvent( 0 );
// This makes sure events that occur at the end of a sequence occur are
// sent before events that occur at the beginning of a sequence.
if (bLooped)
{
for (int i = 0; i < (int)seqdesc.numevents; i++)
{
// ignore all non-client-side events
if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
{
if ( !( pevent[i].type & AE_TYPE_CLIENT ) )
continue;
}
else if ( pevent[i].event < 5000 ) //Adrian - Support the old event system
continue;
if ( pevent[i].cycle <= m_flOverlayPrevEventCycle[j] )
continue;
if ( watch )
{
Msg( "%i FE %i Looped cycle %f, prev %f ev %f (time %.3f)\n",
gpGlobals->tickcount,
pevent[i].event,
pevent[i].cycle,
m_flOverlayPrevEventCycle[j],
m_AnimOverlay[j].m_flCycle,
gpGlobals->curtime );
}
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() );
}
// Necessary to get the next loop working
m_flOverlayPrevEventCycle[j] = -0.01;
}
for (int i = 0; i < (int)seqdesc.numevents; i++)
{
if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
{
if ( !( pevent[i].type & AE_TYPE_CLIENT ) )
continue;
}
else if ( pevent[i].event < 5000 ) //Adrian - Support the old event system
continue;
if ( (pevent[i].cycle > m_flOverlayPrevEventCycle[j] && pevent[i].cycle <= m_AnimOverlay[j].m_flCycle) )
{
if ( watch )
{
Msg( "%i (seq: %d) FE %i Normal cycle %f, prev %f ev %f (time %.3f)\n",
gpGlobals->tickcount,
m_AnimOverlay[j].m_nSequence,
pevent[i].event,
pevent[i].cycle,
m_flOverlayPrevEventCycle[j],
m_AnimOverlay[j].m_flCycle,
gpGlobals->curtime );
}
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() );
}
}
m_flOverlayPrevEventCycle[j] = m_AnimOverlay[j].m_flCycle;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStudioHdr *C_BaseAnimatingOverlay::OnNewModel()
{
CStudioHdr *hdr = BaseClass::OnNewModel();
// Clear out animation layers
for ( int i=0; i < m_AnimOverlay.Count(); i++ )
{
m_AnimOverlay[i].Reset();
m_AnimOverlay[i].m_nOrder = MAX_OVERLAYS;
}
return hdr;
}

View File

@ -0,0 +1,68 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef C_BASEANIMATINGOVERLAY_H
#define C_BASEANIMATINGOVERLAY_H
#pragma once
#include "c_baseanimating.h"
// For shared code.
#define CBaseAnimatingOverlay C_BaseAnimatingOverlay
class C_BaseAnimatingOverlay : public C_BaseAnimating
{
public:
DECLARE_CLASS( C_BaseAnimatingOverlay, C_BaseAnimating );
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
DECLARE_INTERPOLATION();
C_BaseAnimatingOverlay();
virtual CStudioHdr *OnNewModel();
C_AnimationLayer* GetAnimOverlay( int i );
void SetNumAnimOverlays( int num ); // This makes sure there is space for this # of layers.
int GetNumAnimOverlays() const;
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
void CheckForLayerChanges( CStudioHdr *hdr, float currentTime );
// model specific
virtual void AccumulateLayers( CStudioHdr *hdr, Vector pos[], Quaternion q[], float poseparam[], float currentTime, int boneMask );
virtual void DoAnimationEvents( CStudioHdr *pStudioHdr );
enum
{
MAX_OVERLAYS = 15,
};
CUtlVector < C_AnimationLayer > m_AnimOverlay;
CUtlVector < CInterpolatedVar< C_AnimationLayer > > m_iv_AnimOverlay;
float m_flOverlayPrevEventCycle[ MAX_OVERLAYS ];
private:
C_BaseAnimatingOverlay( const C_BaseAnimatingOverlay & ); // not defined, not accessible
};
EXTERN_RECV_TABLE(DT_BaseAnimatingOverlay);
#endif // C_BASEANIMATINGOVERLAY_H

View File

@ -0,0 +1,93 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client's C_BaseCombatCharacter entity
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "c_basecombatcharacter.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#if defined( CBaseCombatCharacter )
#undef CBaseCombatCharacter
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_BaseCombatCharacter::C_BaseCombatCharacter()
{
for ( int i=0; i < m_iAmmo.Count(); i++ )
m_iAmmo.Set( i, 0 );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_BaseCombatCharacter::~C_BaseCombatCharacter()
{
}
/*
//-----------------------------------------------------------------------------
// Purpose: Returns the amount of ammunition of the specified type the character's carrying
//-----------------------------------------------------------------------------
int C_BaseCombatCharacter::GetAmmoCount( char *szName ) const
{
return GetAmmoCount( g_pGameRules->GetAmmoDef()->Index(szName) );
}
*/
//-----------------------------------------------------------------------------
// Purpose: Overload our muzzle flash and send it to any actively held weapon
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::DoMuzzleFlash()
{
// Our weapon takes our muzzle flash command
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
if ( pWeapon )
{
pWeapon->DoMuzzleFlash();
//NOTENOTE: We do not chain to the base here
}
else
{
BaseClass::DoMuzzleFlash();
}
}
IMPLEMENT_CLIENTCLASS(C_BaseCombatCharacter, DT_BaseCombatCharacter, CBaseCombatCharacter);
// Only send active weapon index to local player
BEGIN_RECV_TABLE_NOBASE( C_BaseCombatCharacter, DT_BCCLocalPlayerExclusive )
RecvPropTime( RECVINFO( m_flNextAttack ) ),
END_RECV_TABLE();
BEGIN_RECV_TABLE(C_BaseCombatCharacter, DT_BaseCombatCharacter)
RecvPropDataTable( "bcc_localdata", 0, 0, &REFERENCE_RECV_TABLE(DT_BCCLocalPlayerExclusive) ),
RecvPropEHandle( RECVINFO( m_hActiveWeapon ) ),
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
#ifdef INVASION_CLIENT_DLL
RecvPropInt( RECVINFO( m_iPowerups ) ),
#endif
END_RECV_TABLE()
BEGIN_PREDICTION_DATA( C_BaseCombatCharacter )
DEFINE_PRED_ARRAY( m_iAmmo, FIELD_INTEGER, MAX_AMMO_TYPES, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_flNextAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_hActiveWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_ARRAY( m_hMyWeapons, FIELD_EHANDLE, MAX_WEAPONS, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()

View File

@ -0,0 +1,147 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Defines the client-side representation of CBaseCombatCharacter.
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_BASECOMBATCHARACTER_H
#define C_BASECOMBATCHARACTER_H
#ifdef _WIN32
#pragma once
#endif
#include "shareddefs.h"
#include "c_baseflex.h"
class C_BaseCombatWeapon;
class C_WeaponCombatShield;
class C_BaseCombatCharacter : public C_BaseFlex
{
DECLARE_CLASS( C_BaseCombatCharacter, C_BaseFlex );
public:
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
C_BaseCombatCharacter( void );
virtual ~C_BaseCombatCharacter( void );
virtual bool IsBaseCombatCharacter( void ) { return true; };
virtual C_BaseCombatCharacter *MyCombatCharacterPointer( void ) { return this; }
// -----------------------
// Ammo
// -----------------------
void RemoveAmmo( int iCount, int iAmmoIndex );
void RemoveAmmo( int iCount, const char *szName );
void RemoveAllAmmo( );
int GetAmmoCount( int iAmmoIndex ) const;
int GetAmmoCount( char *szName ) const;
C_BaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 );
virtual bool Weapon_CanSwitchTo(C_BaseCombatWeapon *pWeapon);
// I can't use my current weapon anymore. Switch me to the next best weapon.
bool SwitchToNextBestWeapon(C_BaseCombatWeapon *pCurrent);
virtual C_BaseCombatWeapon *GetActiveWeapon( void ) const;
int WeaponCount() const;
C_BaseCombatWeapon *GetWeapon( int i ) const;
// This is a sort of hack back-door only used by physgun!
void SetAmmoCount( int iCount, int iAmmoIndex );
float GetNextAttack() const { return m_flNextAttack; }
void SetNextAttack( float flWait ) { m_flNextAttack = flWait; }
virtual int BloodColor();
// Blood color (see BLOOD_COLOR_* macros in baseentity.h)
void SetBloodColor( int nBloodColor );
virtual void DoMuzzleFlash();
public:
float m_flNextAttack;
protected:
int m_bloodColor; // color of blood particless
private:
CNetworkArray( int, m_iAmmo, MAX_AMMO_TYPES );
CHandle<C_BaseCombatWeapon> m_hMyWeapons[MAX_WEAPONS];
CHandle< C_BaseCombatWeapon > m_hActiveWeapon;
private:
C_BaseCombatCharacter( const C_BaseCombatCharacter & ); // not defined, not accessible
//-----------------------
#ifdef INVASION_CLIENT_DLL
public:
virtual void Release( void );
virtual void SetDormant( bool bDormant );
virtual void OnPreDataChanged( DataUpdateType_t updateType );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void ClientThink( void );
// TF2 Powerups
virtual bool CanBePoweredUp( void ) { return true; }
bool HasPowerup( int iPowerup ) { return ( m_iPowerups & (1 << iPowerup) ) != 0; };
virtual void PowerupStart( int iPowerup, bool bInitial );
virtual void PowerupEnd( int iPowerup );
void RemoveAllPowerups( void );
// Powerup effects
void AddEMPEffect( float flSize );
void AddBuffEffect( float flSize );
C_WeaponCombatShield *GetShield( void );
public:
int m_iPowerups;
int m_iPrevPowerups;
#endif
};
inline C_BaseCombatCharacter *ToBaseCombatCharacter( C_BaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsBaseCombatCharacter() )
return NULL;
#if _DEBUG
return dynamic_cast<C_BaseCombatCharacter *>( pEntity );
#else
return static_cast<C_BaseCombatCharacter *>( pEntity );
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
inline int C_BaseCombatCharacter::WeaponCount() const
{
return MAX_WEAPONS;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : i -
//-----------------------------------------------------------------------------
inline C_BaseCombatWeapon *C_BaseCombatCharacter::GetWeapon( int i ) const
{
Assert( (i >= 0) && (i < MAX_WEAPONS) );
return m_hMyWeapons[i].Get();
}
EXTERN_RECV_TABLE(DT_BaseCombatCharacter);
#endif // C_BASECOMBATCHARACTER_H

View File

@ -0,0 +1,530 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client side implementation of CBaseCombatWeapon.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "history_resource.h"
#include "iclientmode.h"
#include "iinput.h"
#include "weapon_selection.h"
#include "hud_crosshair.h"
#include "engine/ivmodelinfo.h"
#include "tier0/vprof.h"
#include "hltvcamera.h"
#include "tier1/KeyValues.h"
#include "toolframework/itoolframework.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Gets the local client's active weapon, if any.
//-----------------------------------------------------------------------------
C_BaseCombatWeapon *GetActiveWeapon( void )
{
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
if ( !player )
return NULL;
return player->GetActiveWeapon();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::SetDormant( bool bDormant )
{
// If I'm going from active to dormant and I'm carried by another player, holster me.
if ( !IsDormant() && bDormant && !IsCarriedByLocalPlayer() )
{
Holster( NULL );
}
BaseClass::SetDormant( bDormant );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::NotifyShouldTransmit( ShouldTransmitState_t state )
{
BaseClass::NotifyShouldTransmit(state);
if (state == SHOULDTRANSMIT_END)
{
if (m_iState == WEAPON_IS_ACTIVE)
{
m_iState = WEAPON_IS_CARRIED_BY_PLAYER;
}
}
else if( state == SHOULDTRANSMIT_START )
{
if( m_iState == WEAPON_IS_CARRIED_BY_PLAYER )
{
if( GetOwner() && GetOwner()->GetActiveWeapon() == this )
{
// Restore the Activeness of the weapon if we client-twiddled it off in the first case above.
m_iState = WEAPON_IS_ACTIVE;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: To wrap PORTAL mod specific functionality into one place
//-----------------------------------------------------------------------------
static inline bool ShouldDrawLocalPlayer( void )
{
#if defined( PORTAL )
return true;
#else
return C_BasePlayer::ShouldDrawLocalPlayer();
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::OnRestore()
{
BaseClass::OnRestore();
// if the player is holding this weapon,
// mark it as just restored so it won't show as a new pickup
if (GetOwner() == C_BasePlayer::GetLocalPlayer())
{
m_bJustRestored = true;
}
}
int C_BaseCombatWeapon::GetWorldModelIndex( void )
{
return m_iWorldModelIndex;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : bnewentity -
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged(updateType);
CHandle< C_BaseCombatWeapon > handle = this;
// If it's being carried by the *local* player, on the first update,
// find the registered weapon for this ID
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
C_BaseCombatCharacter *pOwner = GetOwner();
// check if weapon is carried by local player
bool bIsLocalPlayer = pPlayer && pPlayer == pOwner;
if ( bIsLocalPlayer && !ShouldDrawLocalPlayer() )
{
// If I was just picked up, or created & immediately carried, add myself to this client's list of weapons
if ( (m_iState != WEAPON_NOT_CARRIED ) && (m_iOldState == WEAPON_NOT_CARRIED) )
{
// Tell the HUD this weapon's been picked up
if ( ShouldDrawPickup() )
{
CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
if ( pHudSelection )
{
pHudSelection->OnWeaponPickup( this );
}
pPlayer->EmitSound( "Player.PickupWeapon" );
}
}
}
else // weapon carried by other player or not at all
{
// See comment below
EnsureCorrectRenderingModel();
}
UpdateVisibility();
m_iOldState = m_iState;
m_bJustRestored = false;
}
//-----------------------------------------------------------------------------
// Is anyone carrying it?
//-----------------------------------------------------------------------------
bool C_BaseCombatWeapon::IsBeingCarried() const
{
return ( m_hOwner.Get() != NULL );
}
//-----------------------------------------------------------------------------
// Is the carrier alive?
//-----------------------------------------------------------------------------
bool C_BaseCombatWeapon::IsCarrierAlive() const
{
if ( !m_hOwner.Get() )
return false;
return m_hOwner.Get()->GetHealth() > 0;
}
//-----------------------------------------------------------------------------
// Should this object cast shadows?
//-----------------------------------------------------------------------------
ShadowType_t C_BaseCombatWeapon::ShadowCastType()
{
if ( IsEffectActive( /*EF_NODRAW |*/ EF_NOSHADOW ) )
return SHADOWS_NONE;
if (!IsBeingCarried())
return SHADOWS_RENDER_TO_TEXTURE;
if (IsCarriedByLocalPlayer())
return SHADOWS_NONE;
return (m_iState != WEAPON_IS_CARRIED_BY_PLAYER) ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_NONE;
}
//-----------------------------------------------------------------------------
// Purpose: This weapon is the active weapon, and it should now draw anything
// it wants to. This gets called every frame.
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::Redraw()
{
if ( g_pClientMode->ShouldDrawCrosshair() )
{
DrawCrosshair();
}
// ammo drawing has been moved into hud_ammo.cpp
}
//-----------------------------------------------------------------------------
// Purpose: Draw the weapon's crosshair
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::DrawCrosshair()
{
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
if ( !player )
return;
Color clr = gHUD.m_clrNormal;
/*
// TEST: if the thing under your crosshair is on a different team, light the crosshair with a different color.
Vector vShootPos, vShootAngles;
GetShootPosition( vShootPos, vShootAngles );
Vector vForward;
AngleVectors( vShootAngles, &vForward );
// Change the color depending on if we're looking at a friend or an enemy.
CPartitionFilterListMask filter( PARTITION_ALL_CLIENT_EDICTS );
trace_t tr;
traceline->TraceLine( vShootPos, vShootPos + vForward * 10000, COLLISION_GROUP_NONE, MASK_SHOT, &tr, true, ~0, &filter );
if ( tr.index != 0 && tr.index != INVALID_CLIENTENTITY_HANDLE )
{
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( tr.index );
if ( pEnt )
{
if ( pEnt->GetTeamNumber() != player->GetTeamNumber() )
{
g = b = 0;
}
}
}
*/
CHudCrosshair *crosshair = GET_HUDELEMENT( CHudCrosshair );
if ( !crosshair )
return;
// Find out if this weapon's auto-aimed onto a target
bool bOnTarget = ( m_iState == WEAPON_IS_ONTARGET );
if ( player->GetFOV() >= 90 )
{
// normal crosshairs
if ( bOnTarget && GetWpnData().iconAutoaim )
{
clr[3] = 255;
crosshair->SetCrosshair( GetWpnData().iconAutoaim, clr );
}
else if ( GetWpnData().iconCrosshair )
{
clr[3] = 255;
crosshair->SetCrosshair( GetWpnData().iconCrosshair, clr );
}
else
{
crosshair->ResetCrosshair();
}
}
else
{
Color white( 255, 255, 255, 255 );
// zoomed crosshairs
if (bOnTarget && GetWpnData().iconZoomedAutoaim)
crosshair->SetCrosshair(GetWpnData().iconZoomedAutoaim, white);
else if ( GetWpnData().iconZoomedCrosshair )
crosshair->SetCrosshair( GetWpnData().iconZoomedCrosshair, white );
else
crosshair->ResetCrosshair();
}
}
//-----------------------------------------------------------------------------
// Purpose: This weapon is the active weapon, and the viewmodel for it was just drawn.
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::ViewModelDrawn( C_BaseViewModel *pViewModel )
{
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if this client's carrying this weapon
//-----------------------------------------------------------------------------
bool C_BaseCombatWeapon::IsCarriedByLocalPlayer( void )
{
if ( !GetOwner() )
return false;
return ( GetOwner() == C_BasePlayer::GetLocalPlayer() );
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if this weapon is the local client's currently wielded weapon
//-----------------------------------------------------------------------------
bool C_BaseCombatWeapon::IsActiveByLocalPlayer( void )
{
if ( IsCarriedByLocalPlayer() )
{
return (m_iState == WEAPON_IS_ACTIVE);
}
return false;
}
bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles )
{
// Get the entity because the weapon doesn't have the right angles.
C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() );
if ( pEnt )
{
if ( pEnt == C_BasePlayer::GetLocalPlayer() )
{
vAngles = pEnt->EyeAngles();
}
else
{
vAngles = pEnt->GetRenderAngles();
}
}
else
{
vAngles.Init();
}
QAngle vDummy;
if ( IsActiveByLocalPlayer() && !ShouldDrawLocalPlayer() )
{
C_BasePlayer *player = ToBasePlayer( pEnt );
C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
if ( vm )
{
int iAttachment = vm->LookupAttachment( "muzzle" );
if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) )
{
return true;
}
}
}
else
{
// Thirdperson
int iAttachment = LookupAttachment( "muzzle" );
if ( GetAttachment( iAttachment, vOrigin, vDummy ) )
{
return true;
}
}
vOrigin = GetRenderOrigin();
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool C_BaseCombatWeapon::ShouldDraw( void )
{
if ( m_iWorldModelIndex == 0 )
return false;
// FIXME: All weapons with owners are set to transmit in CBaseCombatWeapon::UpdateTransmitState,
// even if they have EF_NODRAW set, so we have to check this here. Ideally they would never
// transmit except for the weapons owned by the local player.
if ( IsEffectActive( EF_NODRAW ) )
return false;
C_BaseCombatCharacter *pOwner = GetOwner();
// weapon has no owner, always draw it
if ( !pOwner )
return true;
bool bIsActive = ( m_iState == WEAPON_IS_ACTIVE );
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
// carried by local player?
if ( pOwner == pLocalPlayer )
{
// Only ever show the active weapon
if ( !bIsActive )
return false;
// 3rd person mode
if ( ShouldDrawLocalPlayer() )
return true;
// don't draw active weapon if not in some kind of 3rd person mode, the viewmodel will do that
return false;
}
// If it's a player, then only show active weapons
if ( pOwner->IsPlayer() )
{
// Show it if it's active...
return bIsActive;
}
// FIXME: We may want to only show active weapons on NPCs
// These are carried by AIs; always show them
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Return true if a weapon-pickup icon should be displayed when this weapon is received
//-----------------------------------------------------------------------------
bool C_BaseCombatWeapon::ShouldDrawPickup( void )
{
if ( GetWeaponFlags() & ITEM_FLAG_NOITEMPICKUP )
return false;
if ( m_bJustRestored )
return false;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
// by this player, otherwise draw the worldmodel.
//-----------------------------------------------------------------------------
int C_BaseCombatWeapon::DrawModel( int flags )
{
VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
if ( !m_bReadyToDraw )
return 0;
if ( !IsVisible() )
return 0;
// check if local player chases owner of this weapon in first person
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
if ( localplayer && localplayer->IsObserver() && GetOwner() )
{
// don't draw weapon if chasing this guy as spectator
// we don't check that in ShouldDraw() since this may change
// without notification
if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
localplayer->GetObserverTarget() == GetOwner() )
return false;
}
// See comment below
EnsureCorrectRenderingModel();
return BaseClass::DrawModel( flags );
}
// If the local player is visible (thirdperson mode, tf2 taunts, etc., then make sure that we are using the
// w_ (world) model not the v_ (view) model or else the model can flicker, etc.
// Otherwise, if we're not the local player, always use the world model
void C_BaseCombatWeapon::EnsureCorrectRenderingModel()
{
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
if ( localplayer &&
localplayer == GetOwner() &&
!ShouldDrawLocalPlayer() )
{
return;
}
// BRJ 10/14/02
// FIXME: Remove when Yahn's client-side prediction is done
// It's a hacky workaround for the model indices fighting
// (GetRenderBounds uses the model index, which is for the view model)
SetModelIndex( GetWorldModelIndex() );
// Validate our current sequence just in case ( in theory the view and weapon models should have the same sequences for sequences that overlap at least )
CStudioHdr *pStudioHdr = GetModelPtr();
if ( pStudioHdr &&
GetSequence() >= pStudioHdr->GetNumSeq() )
{
SetSequence( 0 );
}
}
//-----------------------------------------------------------------------------
// tool recording
//-----------------------------------------------------------------------------
void C_BaseCombatWeapon::GetToolRecordingState( KeyValues *msg )
{
if ( !ToolsEnabled() )
return;
int nModelIndex = GetModelIndex();
int nWorldModelIndex = GetWorldModelIndex();
if ( nModelIndex != nWorldModelIndex )
{
SetModelIndex( nWorldModelIndex );
}
BaseClass::GetToolRecordingState( msg );
if ( m_iState == WEAPON_NOT_CARRIED )
{
BaseEntityRecordingState_t *pBaseEntity = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" );
pBaseEntity->m_nOwner = -1;
}
else
{
msg->SetInt( "worldmodel", 1 );
if ( m_iState == WEAPON_IS_ACTIVE )
{
BaseEntityRecordingState_t *pBaseEntity = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" );
pBaseEntity->m_bVisible = true;
}
}
if ( nModelIndex != nWorldModelIndex )
{
SetModelIndex( nModelIndex );
}
}

View File

@ -0,0 +1,26 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client's CBaseCombatWeapon entity
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef C_BASECOMBATWEAPON_H
#define C_BASECOMBATWEAPON_H
#ifdef _WIN32
#pragma once
#endif
#include "basecombatweapon_shared.h"
#include "weapons_resource.h"
class CViewSetup;
class C_BaseViewModel;
// Accessors for local weapons
C_BaseCombatWeapon *GetActiveWeapon( void );
#endif // C_BASECOMBATWEAPON

View File

@ -0,0 +1,28 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "c_basedoor.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#ifdef CBaseDoor
#undef CBaseDoor
#endif
IMPLEMENT_CLIENTCLASS_DT(C_BaseDoor, DT_BaseDoor, CBaseDoor)
RecvPropFloat(RECVINFO(m_flWaveHeight)),
END_RECV_TABLE()
C_BaseDoor::C_BaseDoor( void )
{
m_flWaveHeight = 0.0f;
}
C_BaseDoor::~C_BaseDoor( void )
{
}

32
game/client/c_basedoor.h Normal file
View File

@ -0,0 +1,32 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#if !defined( C_BASEDOOR_H )
#define C_BASEDOOR_H
#ifdef _WIN32
#pragma once
#endif
#include "c_baseentity.h"
#if defined( CLIENT_DLL )
#define CBaseDoor C_BaseDoor
#endif
class C_BaseDoor : public C_BaseEntity
{
public:
DECLARE_CLASS( C_BaseDoor, C_BaseEntity );
DECLARE_CLIENTCLASS();
C_BaseDoor( void );
~C_BaseDoor( void );
public:
float m_flWaveHeight;
};
#endif // C_BASEDOOR_H

6204
game/client/c_baseentity.cpp Normal file

File diff suppressed because it is too large Load Diff

2096
game/client/c_baseentity.h Normal file

File diff suppressed because it is too large Load Diff

1999
game/client/c_baseflex.cpp Normal file

File diff suppressed because it is too large Load Diff

301
game/client/c_baseflex.h Normal file
View File

@ -0,0 +1,301 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
// Client-side CBasePlayer
#ifndef C_STUDIOFLEX_H
#define C_STUDIOFLEX_H
#pragma once
#include "c_baseanimating.h"
#include "c_baseanimatingoverlay.h"
#include "sceneentity_shared.h"
#include "UtlVector.h"
//-----------------------------------------------------------------------------
// Purpose: Item in list of loaded scene files
//-----------------------------------------------------------------------------
class CFlexSceneFile
{
public:
enum
{
MAX_FLEX_FILENAME = 128,
};
char filename[ MAX_FLEX_FILENAME ];
void *buffer;
};
// For phoneme emphasis track
struct Emphasized_Phoneme;
class CSentence;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class C_BaseFlex : public C_BaseAnimatingOverlay
{
DECLARE_CLASS( C_BaseFlex, C_BaseAnimatingOverlay );
public:
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
DECLARE_INTERPOLATION();
C_BaseFlex();
virtual ~C_BaseFlex();
virtual void Spawn();
virtual void InitPhonemeMappings();
void SetupMappings( char const *pchFileRoot );
virtual CStudioHdr *OnNewModel( void );
virtual void StandardBlendingRules( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
virtual void OnThreadedDrawSetup();
// model specific
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
virtual bool UsesFlexDelayedWeights();
virtual void RunFlexRules( CStudioHdr *pStudioHdr, float *dest );
virtual Vector SetViewTarget( CStudioHdr *pStudioHdr );
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
virtual void GetToolRecordingState( KeyValues *msg );
// Called at the lowest level to actually apply a flex animation
void AddFlexAnimation( CSceneEventInfo *info );
void SetFlexWeight( LocalFlexController_t index, float value );
float GetFlexWeight( LocalFlexController_t index );
// Look up flex controller index by global name
LocalFlexController_t FindFlexController( const char *szName );
public:
Vector m_viewtarget;
CInterpolatedVar< Vector > m_iv_viewtarget;
// indexed by model local flexcontroller
float m_flexWeight[MAXSTUDIOFLEXCTRL];
CInterpolatedVarArray< float, MAXSTUDIOFLEXCTRL > m_iv_flexWeight;
int m_blinktoggle;
static int AddGlobalFlexController( char *szName );
static char const *GetGlobalFlexControllerName( int idx );
// bah, this should be unified with all prev/current stuff.
public:
// Keep track of what scenes are being played
void StartChoreoScene( CChoreoScene *scene );
void RemoveChoreoScene( CChoreoScene *scene );
// Start the specifics of an scene event
virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, C_BaseEntity *pTarget );
// Manipulation of events for the object
// Should be called by think function to process all scene events
// The default implementation resets m_flexWeight array and calls
// AddSceneEvents
virtual void ProcessSceneEvents( bool bFlexEvents );
// Assumes m_flexWeight array has been set up, this adds the actual currently playing
// expressions to the flex weights and adds other scene events as needed
virtual bool ProcessSceneEvent( bool bFlexEvents, CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
virtual bool ProcessSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
// Remove all playing events
void ClearSceneEvents( CChoreoScene *scene, bool canceled );
// Stop specifics of event
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled );
// Add the event to the queue for this actor
void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL, bool bClientSide = false );
// Remove the event from the queue for this actor
void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill );
// Checks to see if the event should be considered "completed"
bool CheckSceneEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event );
// Checks to see if a event should be considered "completed"
virtual bool CheckSceneEventCompletion( CSceneEventInfo *info, float currenttime, CChoreoScene *scene, CChoreoEvent *event );
int FlexControllerLocalToGlobal( const flexsettinghdr_t *pSettinghdr, int key );
void EnsureTranslations( const flexsettinghdr_t *pSettinghdr );
// For handling scene files
void *FindSceneFile( const char *filename );
private:
bool RequestStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget );
bool ProcessFlexAnimationSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
bool ProcessFlexSettingSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
void AddFlexSetting( const char *expr, float scale,
const flexsettinghdr_t *pSettinghdr, bool newexpression );
// Array of active SceneEvents, in order oldest to newest
CUtlVector < CSceneEventInfo > m_SceneEvents;
CUtlVector < CChoreoScene * > m_ActiveChoreoScenes;
bool HasSceneEvents() const;
private:
// Mapping for each loaded scene file used by this actor
struct FS_LocalToGlobal_t
{
explicit FS_LocalToGlobal_t() :
m_Key( 0 ),
m_nCount( 0 ),
m_Mapping( 0 )
{
}
explicit FS_LocalToGlobal_t( const flexsettinghdr_t *key ) :
m_Key( key ),
m_nCount( 0 ),
m_Mapping( 0 )
{
}
void SetCount( int count )
{
Assert( !m_Mapping );
Assert( count > 0 );
m_nCount = count;
m_Mapping = new int[ m_nCount ];
Q_memset( m_Mapping, 0, m_nCount * sizeof( int ) );
}
FS_LocalToGlobal_t( const FS_LocalToGlobal_t& src )
{
m_Key = src.m_Key;
delete m_Mapping;
m_Mapping = new int[ src.m_nCount ];
Q_memcpy( m_Mapping, src.m_Mapping, src.m_nCount * sizeof( int ) );
m_nCount = src.m_nCount;
}
~FS_LocalToGlobal_t()
{
delete m_Mapping;
m_nCount = 0;
m_Mapping = 0;
}
const flexsettinghdr_t *m_Key;
int m_nCount;
int *m_Mapping;
};
static bool FlexSettingLessFunc( const FS_LocalToGlobal_t& lhs, const FS_LocalToGlobal_t& rhs );
CUtlRBTree< FS_LocalToGlobal_t, unsigned short > m_LocalToGlobal;
float m_blinktime;
int m_prevblinktoggle;
int m_iBlink;
LocalFlexController_t m_iEyeUpdown;
LocalFlexController_t m_iEyeRightleft;
bool m_bSearchedForEyeFlexes;
int m_iMouthAttachment;
float *m_flFlexDelayedWeight;
// shared flex controllers
static int g_numflexcontrollers;
static char *g_flexcontroller[MAXSTUDIOFLEXCTRL*4]; // room for global set of flexcontrollers
static float g_flexweight[MAXSTUDIOFLEXDESC];
protected:
enum
{
PHONEME_CLASS_WEAK = 0,
PHONEME_CLASS_NORMAL,
PHONEME_CLASS_STRONG,
NUM_PHONEME_CLASSES
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
struct Emphasized_Phoneme
{
// Global fields, setup at start
char classname[ 64 ];
bool required;
// Global fields setup first time tracks played
bool basechecked;
const flexsettinghdr_t *base;
const flexsetting_t *exp;
// Local fields, processed for each sentence
bool valid;
float amount;
};
Emphasized_Phoneme m_PhonemeClasses[ NUM_PHONEME_CLASSES ];
private:
C_BaseFlex( const C_BaseFlex & ); // not defined, not accessible
const flexsetting_t *FindNamedSetting( const flexsettinghdr_t *pSettinghdr, const char *expr );
void ProcessVisemes( Emphasized_Phoneme *classes );
void AddVisemesForSentence( Emphasized_Phoneme *classes, float emphasis_intensity, CSentence *sentence, float t, float dt, bool juststarted );
void AddViseme( Emphasized_Phoneme *classes, float emphasis_intensity, int phoneme, float scale, bool newexpression );
bool SetupEmphasisBlend( Emphasized_Phoneme *classes, int phoneme );
void ComputeBlendedSetting( Emphasized_Phoneme *classes, float emphasis_intensity );
#ifdef HL2_CLIENT_DLL
public:
Vector m_vecLean;
CInterpolatedVar< Vector > m_iv_vecLean;
Vector m_vecShift;
CInterpolatedVar< Vector > m_iv_vecShift;
#endif
};
//-----------------------------------------------------------------------------
// Do we have active expressions?
//-----------------------------------------------------------------------------
inline bool C_BaseFlex::HasSceneEvents() const
{
return m_SceneEvents.Count() != 0;
}
EXTERN_RECV_TABLE(DT_BaseFlex);
float *GetVisemeWeights( int phoneme );
#endif // C_STUDIOFLEX_H

2450
game/client/c_baseplayer.cpp Normal file

File diff suppressed because it is too large Load Diff

639
game/client/c_baseplayer.h Normal file
View File

@ -0,0 +1,639 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client-side CBasePlayer.
//
// - Manages the player's flashlight effect.
//
//=============================================================================//
#ifndef C_BASEPLAYER_H
#define C_BASEPLAYER_H
#ifdef _WIN32
#pragma once
#endif
#include "c_playerlocaldata.h"
#include "c_basecombatcharacter.h"
#include "playerstate.h"
#include "usercmd.h"
#include "shareddefs.h"
#include "timedevent.h"
#include "smartptr.h"
#include "fx_water.h"
#include "hintsystem.h"
#include "soundemittersystem/isoundemittersystembase.h"
#include "c_env_fog_controller.h"
class C_BaseCombatWeapon;
class C_BaseViewModel;
class C_FuncLadder;
class CFlashlightEffect;
extern int g_nKillCamMode;
extern int g_nKillCamTarget1;
extern int g_nKillCamTarget2;
class C_CommandContext
{
public:
bool needsprocessing;
CUserCmd cmd;
int command_number;
};
class C_PredictionError
{
public:
float time;
Vector error;
};
#define CHASE_CAM_DISTANCE 96.0f
#define WALL_OFFSET 6.0f
bool IsInFreezeCam( void );
//-----------------------------------------------------------------------------
// Purpose: Base Player class
//-----------------------------------------------------------------------------
class C_BasePlayer : public C_BaseCombatCharacter
{
public:
DECLARE_CLASS( C_BasePlayer, C_BaseCombatCharacter );
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
DECLARE_INTERPOLATION();
C_BasePlayer();
virtual ~C_BasePlayer();
virtual void Spawn( void );
virtual void SharedSpawn(); // Shared between client and server.
// IClientEntity overrides.
virtual void OnPreDataChanged( DataUpdateType_t updateType );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void PreDataUpdate( DataUpdateType_t updateType );
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual void ReceiveMessage( int classID, bf_read &msg );
virtual void OnRestore();
virtual void AddEntity( void );
virtual void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
virtual void GetToolRecordingState( KeyValues *msg );
void SetAnimationExtension( const char *pExtension );
C_BaseViewModel *GetViewModel( int viewmodelindex = 0 );
C_BaseCombatWeapon *GetActiveWeapon( void ) const;
const char *GetTracerType( void );
// View model prediction setup
virtual void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
virtual void CalcViewModelView( const Vector& eyeOrigin, const QAngle& eyeAngles);
// Handle view smoothing when going up stairs
void SmoothViewOnStairs( Vector& eyeOrigin );
virtual float CalcRoll (const QAngle& angles, const Vector& velocity, float rollangle, float rollspeed);
void CalcViewRoll( QAngle& eyeAngles );
void CreateWaterEffects( void );
virtual void SetPlayerUnderwater( bool state );
void UpdateUnderwaterState( void );
bool IsPlayerUnderwater( void ) { return m_bPlayerUnderwater; }
virtual Vector Weapon_ShootPosition();
virtual void Weapon_DropPrimary( void ) {}
virtual Vector GetAutoaimVector( float flScale );
void SetSuitUpdate(char *name, int fgroup, int iNoRepeat);
// Input handling
virtual bool CreateMove( float flInputSampleTime, CUserCmd *pCmd );
virtual void AvoidPhysicsProps( CUserCmd *pCmd );
virtual void PlayerUse( void );
CBaseEntity *FindUseEntity( void );
virtual bool IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps );
// Data handlers
virtual bool IsPlayer( void ) const { return true; }
virtual int GetHealth() const { return m_iHealth; }
int GetBonusProgress() const { return m_iBonusProgress; }
int GetBonusChallenge() const { return m_iBonusChallenge; }
// observer mode
virtual int GetObserverMode() const;
virtual CBaseEntity *GetObserverTarget() const;
void SetObserverTarget( EHANDLE hObserverTarget );
bool AudioStateIsUnderwater( Vector vecMainViewOrigin );
bool IsObserver() const;
bool IsHLTV() const;
void ResetObserverMode();
bool IsBot( void ) const { return false; }
// Eye position..
virtual Vector EyePosition();
virtual const QAngle &EyeAngles(); // Direction of eyes
void EyePositionAndVectors( Vector *pPosition, Vector *pForward, Vector *pRight, Vector *pUp );
virtual const QAngle &LocalEyeAngles(); // Direction of eyes
// This can be overridden to return something other than m_pRagdoll if the mod uses separate
// entities for ragdolls.
virtual IRagdoll* GetRepresentativeRagdoll() const;
// override the initial bone position for ragdolls
virtual void GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt );
// Returns eye vectors
void EyeVectors( Vector *pForward, Vector *pRight = NULL, Vector *pUp = NULL );
void CacheVehicleView( void ); // Calculate and cache the position of the player in the vehicle
bool IsSuitEquipped( void ) { return m_Local.m_bWearingSuit; };
// Team handlers
virtual void TeamChange( int iNewTeam );
// Flashlight
void Flashlight( void );
void UpdateFlashlight( void );
// Weapon selection code
virtual bool IsAllowedToSwitchWeapons( void ) { return !IsObserver(); }
virtual C_BaseCombatWeapon *GetActiveWeaponForSelection( void );
// Returns the view model if this is the local player. If you're in third person or
// this is a remote player, it returns the active weapon
// (and its appropriate left/right weapon if this is TF2).
virtual C_BaseAnimating* GetRenderedWeaponModel();
virtual bool IsOverridingViewmodel( void ) { return false; };
virtual int DrawOverriddenViewmodel( C_BaseViewModel *pViewmodel, int flags ) { return 0; };
virtual float GetDefaultAnimSpeed( void ) { return 1.0; }
void SetMaxSpeed( float flMaxSpeed ) { m_flMaxspeed = flMaxSpeed; }
float MaxSpeed() const { return m_flMaxspeed; }
// Should this object cast shadows?
virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; }
virtual bool ShouldReceiveProjectedTextures( int flags )
{
return false;
}
bool IsLocalPlayer( void ) const;
// Global/static methods
virtual void ThirdPersonSwitch( bool bThirdperson );
static bool ShouldDrawLocalPlayer();
static C_BasePlayer *GetLocalPlayer( void );
int GetUserID( void );
virtual bool CanSetSoundMixer( void );
// Called by the view model if its rendering is being overridden.
virtual bool ViewModel_IsTransparent( void );
#if !defined( NO_ENTITY_PREDICTION )
void AddToPlayerSimulationList( C_BaseEntity *other );
void SimulatePlayerSimulatedEntities( void );
void RemoveFromPlayerSimulationList( C_BaseEntity *ent );
void ClearPlayerSimulationList( void );
#endif
virtual void PhysicsSimulate( void );
virtual unsigned int PhysicsSolidMaskForEntity( void ) const { return MASK_PLAYERSOLID; }
// Prediction stuff
virtual bool ShouldPredict( void );
virtual void PreThink( void );
virtual void PostThink( void );
virtual void ItemPreFrame( void );
virtual void ItemPostFrame( void );
virtual void AbortReload( void );
virtual void SelectLastItem(void);
virtual void Weapon_SetLast( C_BaseCombatWeapon *pWeapon );
virtual bool Weapon_ShouldSetLast( C_BaseCombatWeapon *pOldWeapon, C_BaseCombatWeapon *pNewWeapon ) { return true; }
virtual bool Weapon_ShouldSelectItem( C_BaseCombatWeapon *pWeapon );
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed)
virtual C_BaseCombatWeapon *GetLastWeapon( void ) { return m_hLastWeapon.Get(); }
void ResetAutoaim( void );
virtual void SelectItem( const char *pstr, int iSubType = 0 );
virtual void UpdateClientData( void );
virtual float GetFOV( void );
int GetDefaultFOV( void ) const;
virtual bool IsZoomed( void ) { return false; }
bool SetFOV( CBaseEntity *pRequester, int FOV, float zoomRate, int iZoomStart = 0 );
void ClearZoomOwner( void );
float GetFOVDistanceAdjustFactor();
virtual void ViewPunch( const QAngle &angleOffset );
void ViewPunchReset( float tolerance = 0 );
void UpdateButtonState( int nUserCmdButtonMask );
int GetImpulse( void ) const;
virtual void Simulate();
virtual bool ShouldInterpolate();
virtual bool ShouldDraw();
virtual int DrawModel( int flags );
// Called when not in tactical mode. Allows view to be overriden for things like driving a tank.
virtual void OverrideView( CViewSetup *pSetup );
// returns the player name
const char * GetPlayerName();
virtual const Vector GetPlayerMins( void ) const; // uses local player
virtual const Vector GetPlayerMaxs( void ) const; // uses local player
// Is the player dead?
bool IsPlayerDead();
bool IsPoisoned( void ) { return m_Local.m_bPoisoned; }
C_BaseEntity *GetUseEntity();
// Vehicles...
IClientVehicle *GetVehicle();
bool IsInAVehicle() const { return ( NULL != m_hVehicle.Get() ) ? true : false; }
virtual void SetVehicleRole( int nRole );
void LeaveVehicle( void );
bool UsingStandardWeaponsInVehicle( void );
virtual void SetAnimation( PLAYER_ANIM playerAnim );
float GetTimeBase( void ) const;
float GetFinalPredictedTime() const;
bool IsInVGuiInputMode() const;
bool IsInViewModelVGuiInputMode() const;
C_CommandContext *GetCommandContext();
// Get the command number associated with the current usercmd we're running (if in predicted code).
int CurrentCommandNumber() const;
const CUserCmd *GetCurrentUserCommand() const;
const QAngle& GetPunchAngle();
void SetPunchAngle( const QAngle &angle );
float GetWaterJumpTime() const;
void SetWaterJumpTime( float flWaterJumpTime );
float GetSwimSoundTime( void ) const;
void SetSwimSoundTime( float flSwimSoundTime );
float GetDeathTime( void ) { return m_flDeathTime; }
void SetPreviouslyPredictedOrigin( const Vector &vecAbsOrigin );
const Vector &GetPreviouslyPredictedOrigin() const;
// CS wants to allow small FOVs for zoomed-in AWPs.
virtual float GetMinFOV() const;
virtual void DoMuzzleFlash();
virtual void PlayPlayerJingle();
virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
virtual surfacedata_t * GetFootstepSurface( const Vector &origin, const char *surfaceName );
virtual void GetStepSoundVelocities( float *velwalk, float *velrun );
virtual void SetStepSoundTime( stepsoundtimes_t iStepSoundTime, bool bWalking );
// Called by prediction when it detects a prediction correction.
// vDelta is the line from where the client had predicted the player to at the usercmd in question,
// to where the server says the client should be at said usercmd.
void NotePredictionError( const Vector &vDelta );
// Called by the renderer to apply the prediction error smoothing.
void GetPredictionErrorSmoothingVector( Vector &vOffset );
virtual void ExitLadder() {}
surfacedata_t *GetLadderSurface( const Vector &origin );
surfacedata_t *GetSurfaceData( void ) { return m_pSurfaceData; }
void SetLadderNormal( Vector vecLadderNormal ) { m_vecLadderNormal = vecLadderNormal; }
// Hints
virtual CHintSystem *Hints( void ) { return NULL; }
bool ShouldShowHints( void ) { return Hints() ? Hints()->ShouldShowHints() : false; }
bool HintMessage( int hint, bool bForce = false, bool bOnlyIfClear = false ) { return Hints() ? Hints()->HintMessage( hint, bForce, bOnlyIfClear ) : false; }
void HintMessage( const char *pMessage ) { if (Hints()) Hints()->HintMessage( pMessage ); }
virtual IMaterial *GetHeadLabelMaterial( void );
// Fog
fogparams_t *GetFogParams( void ) { return &m_CurrentFog; }
void FogControllerChanged( bool bSnap );
void UpdateFogController( void );
void UpdateFogBlend( void );
void IncrementEFNoInterpParity();
int GetEFNoInterpParity() const;
float GetFOVTime( void ){ return m_flFOVTime; }
virtual void OnAchievementAchieved( int iAchievement ) {}
protected:
fogparams_t m_CurrentFog;
EHANDLE m_hOldFogController;
public:
int m_StuckLast;
// Data for only the local player
CNetworkVarEmbedded( CPlayerLocalData, m_Local );
// Data common to all other players, too
CPlayerState pl;
// Player FOV values
int m_iFOV; // field of view
int m_iFOVStart; // starting value of the FOV changing over time (client only)
float m_flFOVTime; // starting time of the FOV zoom
int m_iDefaultFOV; // default FOV if no other zooms are occurring
EHANDLE m_hZoomOwner; // This is a pointer to the entity currently controlling the player's zoom
// Only this entity can change the zoom state once it has ownership
// For weapon prediction
bool m_fOnTarget; //Is the crosshair on a target?
char m_szAnimExtension[32];
int m_afButtonLast;
int m_afButtonPressed;
int m_afButtonReleased;
int m_nButtons;
CUserCmd *m_pCurrentCommand;
// Movement constraints
EHANDLE m_hConstraintEntity;
Vector m_vecConstraintCenter;
float m_flConstraintRadius;
float m_flConstraintWidth;
float m_flConstraintSpeedFactor;
protected:
void CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
void CalcVehicleView(IClientVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles,
float& zNear, float& zFar, float& fov );
virtual void CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
virtual Vector GetChaseCamViewOffset( CBaseEntity *target );
void CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
void CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
virtual void CalcDeathCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
void CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov);
virtual void CalcFreezeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
// Check to see if we're in vgui input mode...
void DetermineVguiInputMode( CUserCmd *pCmd );
// Used by prediction, sets the view angles for the player
virtual void SetLocalViewAngles( const QAngle &viewAngles );
virtual void SetViewAngles( const QAngle& ang );
// used by client side player footsteps
surfacedata_t* GetGroundSurface();
protected:
// Did we just enter a vehicle this frame?
bool JustEnteredVehicle();
// DATA
int m_iObserverMode; // if in spectator mode != 0
EHANDLE m_hObserverTarget; // current observer target
float m_flObserverChaseDistance; // last distance to observer traget
Vector m_vecFreezeFrameStart;
float m_flFreezeFrameStartTime; // Time at which we entered freeze frame observer mode
float m_flFreezeFrameDistance;
bool m_bWasFreezeFraming;
float m_flDeathTime; // last time player died
float m_flStepSoundTime;
private:
// Make sure no one calls this...
C_BasePlayer& operator=( const C_BasePlayer& src );
C_BasePlayer( const C_BasePlayer & ); // not defined, not accessible
// Vehicle stuff.
EHANDLE m_hVehicle;
EHANDLE m_hOldVehicle;
EHANDLE m_hUseEntity;
float m_flMaxspeed;
int m_iBonusProgress;
int m_iBonusChallenge;
CInterpolatedVar< Vector > m_iv_vecViewOffset;
// Not replicated
Vector m_vecWaterJumpVel;
float m_flWaterJumpTime; // used to be called teleport_time
int m_nImpulse;
float m_flSwimSoundTime;
Vector m_vecLadderNormal;
QAngle m_vecOldViewAngles;
bool m_bWasFrozen;
int m_flPhysics;
int m_nTickBase;
int m_nFinalPredictedTick;
EHANDLE m_pCurrentVguiScreen;
// Player flashlight dynamic light pointers
CFlashlightEffect *m_pFlashlight;
typedef CHandle<C_BaseCombatWeapon> CBaseCombatWeaponHandle;
CNetworkVar( CBaseCombatWeaponHandle, m_hLastWeapon );
#if !defined( NO_ENTITY_PREDICTION )
CUtlVector< CHandle< C_BaseEntity > > m_SimulatedByThisPlayer;
#endif
// players own view models, left & right hand
CHandle< C_BaseViewModel > m_hViewModel[ MAX_VIEWMODELS ];
float m_flOldPlayerZ;
float m_flOldPlayerViewOffsetZ;
Vector m_vecVehicleViewOrigin; // Used to store the calculated view of the player while riding in a vehicle
QAngle m_vecVehicleViewAngles; // Vehicle angles
float m_flVehicleViewFOV;
int m_nVehicleViewSavedFrame; // Used to mark which frame was the last one the view was calculated for
// For UI purposes...
int m_iOldAmmo[ MAX_AMMO_TYPES ];
C_CommandContext m_CommandContext;
// For underwater effects
float m_flWaterSurfaceZ;
bool m_bResampleWaterSurface;
TimedEvent m_tWaterParticleTimer;
CSmartPtr<WaterDebrisEffect> m_pWaterEmitter;
bool m_bPlayerUnderwater;
friend class CPrediction;
// HACK FOR TF2 Prediction
friend class CTFGameMovementRecon;
friend class CGameMovement;
friend class CTFGameMovement;
friend class CHL1GameMovement;
friend class CCSGameMovement;
friend class CHL2GameMovement;
friend class CDODGameMovement;
friend class CPortalGameMovement;
// Accessors for gamemovement
float GetStepSize( void ) const { return m_Local.m_flStepSize; }
float m_flNextAvoidanceTime;
float m_flAvoidanceRight;
float m_flAvoidanceForward;
float m_flAvoidanceDotForward;
float m_flAvoidanceDotRight;
protected:
virtual bool IsDucked( void ) const { return m_Local.m_bDucked; }
virtual bool IsDucking( void ) const { return m_Local.m_bDucking; }
virtual float GetFallVelocity( void ) { return m_Local.m_flFallVelocity; }
void ForceSetupBonesAtTimeFakeInterpolation( matrix3x4_t *pBonesOut, float curtimeOffset );
float m_flLaggedMovementValue;
// These are used to smooth out prediction corrections. They're most useful when colliding with
// vphysics objects. The server will be sending constant prediction corrections, and these can help
// the errors not be so jerky.
Vector m_vecPredictionError;
float m_flPredictionErrorTime;
Vector m_vecPreviouslyPredictedOrigin; // Used to determine if non-gamemovement game code has teleported, or tweaked the player's origin
char m_szLastPlaceName[MAX_PLACE_NAME_LENGTH]; // received from the server
// Texture names and surface data, used by CGameMovement
int m_surfaceProps;
surfacedata_t* m_pSurfaceData;
float m_surfaceFriction;
char m_chTextureType;
bool m_bSentFreezeFrame;
float m_flFreezeZOffset;
byte m_ubEFNoInterpParity;
byte m_ubOldEFNoInterpParity;
private:
struct StepSoundCache_t
{
StepSoundCache_t() : m_usSoundNameIndex( 0 ) {}
CSoundParameters m_SoundParameters;
unsigned short m_usSoundNameIndex;
};
// One for left and one for right side of step
StepSoundCache_t m_StepSoundCache[ 2 ];
public:
const char *GetLastKnownPlaceName( void ) const { return m_szLastPlaceName; } // return the last nav place name the player occupied
float GetLaggedMovementValue( void ){ return m_flLaggedMovementValue; }
bool ShouldGoSouth( Vector vNPCForward, Vector vNPCRight ); //Such a bad name.
void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; }
};
EXTERN_RECV_TABLE(DT_BasePlayer);
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline C_BasePlayer *ToBasePlayer( C_BaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
#if _DEBUG
Assert( dynamic_cast<C_BasePlayer *>( pEntity ) != NULL );
#endif
return static_cast<C_BasePlayer *>( pEntity );
}
inline C_BaseEntity *C_BasePlayer::GetUseEntity()
{
return m_hUseEntity;
}
inline IClientVehicle *C_BasePlayer::GetVehicle()
{
C_BaseEntity *pVehicleEnt = m_hVehicle.Get();
return pVehicleEnt ? pVehicleEnt->GetClientVehicle() : NULL;
}
inline bool C_BasePlayer::IsObserver() const
{
return (GetObserverMode() != OBS_MODE_NONE);
}
inline int C_BasePlayer::GetImpulse( void ) const
{
return m_nImpulse;
}
inline C_CommandContext* C_BasePlayer::GetCommandContext()
{
return &m_CommandContext;
}
inline int CBasePlayer::CurrentCommandNumber() const
{
Assert( m_pCurrentCommand );
return m_pCurrentCommand->command_number;
}
inline const CUserCmd *CBasePlayer::GetCurrentUserCommand() const
{
Assert( m_pCurrentCommand );
return m_pCurrentCommand;
}
#endif // C_BASEPLAYER_H

View File

@ -0,0 +1,201 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Core Temp Entity client implementation.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "c_basetempentity.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
IMPLEMENT_CLIENTCLASS(C_BaseTempEntity, DT_BaseTempEntity, CBaseTempEntity);
BEGIN_RECV_TABLE_NOBASE(C_BaseTempEntity, DT_BaseTempEntity)
END_RECV_TABLE()
// Global list of temp entity classes
C_BaseTempEntity *C_BaseTempEntity::s_pTempEntities = NULL;
// Global list of dynamic temp entities
C_BaseTempEntity *C_BaseTempEntity::s_pDynamicEntities = NULL;
//-----------------------------------------------------------------------------
// Purpose: Returns head of list
// Output : CBaseTempEntity * -- head of list
//-----------------------------------------------------------------------------
C_BaseTempEntity *C_BaseTempEntity::GetDynamicList( void )
{
return s_pDynamicEntities;
}
//-----------------------------------------------------------------------------
// Purpose: Returns head of list
// Output : CBaseTempEntity * -- head of list
//-----------------------------------------------------------------------------
C_BaseTempEntity *C_BaseTempEntity::GetList( void )
{
return s_pTempEntities;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output :
//-----------------------------------------------------------------------------
C_BaseTempEntity::C_BaseTempEntity( void )
{
// Add to list
m_pNext = s_pTempEntities;
s_pTempEntities = this;
m_pNextDynamic = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output :
//-----------------------------------------------------------------------------
C_BaseTempEntity::~C_BaseTempEntity( void )
{
}
//-----------------------------------------------------------------------------
// Purpose: Get next temp ent in chain
// Output : CBaseTempEntity *
//-----------------------------------------------------------------------------
C_BaseTempEntity *C_BaseTempEntity::GetNext( void )
{
return m_pNext;
}
//-----------------------------------------------------------------------------
// Purpose: Get next temp ent in chain
// Output : CBaseTempEntity *
//-----------------------------------------------------------------------------
C_BaseTempEntity *C_BaseTempEntity::GetNextDynamic( void )
{
return m_pNextDynamic;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseTempEntity::Precache( void )
{
// Nothing...
}
//-----------------------------------------------------------------------------
// Purpose: Called at startup to allow temp entities to precache any models/sounds that they need
//-----------------------------------------------------------------------------
void C_BaseTempEntity::PrecacheTempEnts( void )
{
C_BaseTempEntity *te = GetList();
while ( te )
{
te->Precache();
te = te->GetNext();
}
}
//-----------------------------------------------------------------------------
// Purpose: Called at startup and level load to clear out leftover temp entities
//-----------------------------------------------------------------------------
void C_BaseTempEntity::ClearDynamicTempEnts( void )
{
C_BaseTempEntity *next;
C_BaseTempEntity *te = s_pDynamicEntities;
while ( te )
{
next = te->GetNextDynamic();
delete te;
te = next;
}
s_pDynamicEntities = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Called at startup and level load to clear out leftover temp entities
//-----------------------------------------------------------------------------
void C_BaseTempEntity::CheckDynamicTempEnts( void )
{
C_BaseTempEntity *next, *newlist = NULL;
C_BaseTempEntity *te = s_pDynamicEntities;
while ( te )
{
next = te->GetNextDynamic();
if ( te->ShouldDestroy() )
{
delete te;
}
else
{
te->m_pNextDynamic = newlist;
newlist = te;
}
te = next;
}
s_pDynamicEntities = newlist;
}
//-----------------------------------------------------------------------------
// Purpose: Dynamic/non-singleton temp entities are initialized by
// calling into here. They should be added to a list of C_BaseTempEntities so
// that their memory can be deallocated appropriately.
// Input : *pEnt -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool C_BaseTempEntity::Init( int entnum, int iSerialNum )
{
if ( entnum != -1 )
{
Assert( 0 );
}
// Link into dynamic entity list
m_pNextDynamic = s_pDynamicEntities;
s_pDynamicEntities = this;
return true;
}
void C_BaseTempEntity::Release()
{
Assert( !"C_BaseTempEntity::Release should never be called" );
}
void C_BaseTempEntity::NotifyShouldTransmit( ShouldTransmitState_t state )
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : bool -
//-----------------------------------------------------------------------------
void C_BaseTempEntity::PreDataUpdate( DataUpdateType_t updateType )
{
// TE's may or may not implement this
}
int C_BaseTempEntity::entindex( void ) const { Assert( 0 ); return 0; }
void C_BaseTempEntity::PostDataUpdate( DataUpdateType_t updateType ) { Assert( 0 ); }
void C_BaseTempEntity::OnPreDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
void C_BaseTempEntity::OnDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
void C_BaseTempEntity::SetDormant( bool bDormant ) { Assert( 0 ); }
bool C_BaseTempEntity::IsDormant( void ) { Assert( 0 ); return false; };
void C_BaseTempEntity::ReceiveMessage( int classID, bf_read &msg ) { Assert( 0 ); }
void C_BaseTempEntity::SetDestroyedOnRecreateEntities( void ) { Assert(0); }
void* C_BaseTempEntity::GetDataTableBasePtr()
{
return this;
}

View File

@ -0,0 +1,121 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_BASETEMPENTITY_H
#define C_BASETEMPENTITY_H
#ifdef _WIN32
#pragma once
#endif
#include "client_class.h"
#include "iclientnetworkable.h"
#include "c_recipientfilter.h"
//-----------------------------------------------------------------------------
// Purpose: Base class for TEs. All TEs should derive from this and at
// least implement OnDataChanged to be notified when the TE has been received
// from the server
//-----------------------------------------------------------------------------
class C_BaseTempEntity : public IClientUnknown, public IClientNetworkable
{
public:
DECLARE_CLASS_NOBASE( C_BaseTempEntity );
DECLARE_CLIENTCLASS();
C_BaseTempEntity( void );
virtual ~C_BaseTempEntity( void );
// IClientUnknown implementation.
public:
virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); }
virtual const CBaseHandle& GetRefEHandle() const { return *((CBaseHandle*)0); }
virtual IClientUnknown* GetIClientUnknown() { return this; }
virtual ICollideable* GetCollideable() { return 0; }
virtual IClientNetworkable* GetClientNetworkable() { return this; }
virtual IClientRenderable* GetClientRenderable() { return 0; }
virtual IClientEntity* GetIClientEntity() { return 0; }
virtual C_BaseEntity* GetBaseEntity() { return 0; }
virtual IClientThinkable* GetClientThinkable() { return 0; }
// IClientNetworkable overrides.
public:
virtual void Release();
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
virtual void PreDataUpdate( DataUpdateType_t updateType );
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual void OnPreDataChanged( DataUpdateType_t updateType );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void SetDormant( bool bDormant );
virtual bool IsDormant( void );
virtual int entindex( void ) const;
virtual void ReceiveMessage( int classID, bf_read &msg );
virtual void* GetDataTableBasePtr();
virtual void SetDestroyedOnRecreateEntities( void );
public:
// Dummy for CNetworkVars.
void NetworkStateChanged() {}
void NetworkStateChanged( void *pVar ) {}
virtual bool Init(int entnum, int iSerialNum);
virtual void Precache( void );
// For dynamic entities, return true to allow destruction
virtual bool ShouldDestroy( void ) { return false; };
C_BaseTempEntity *GetNext( void );
// Get list of tempentities
static C_BaseTempEntity *GetList( void );
C_BaseTempEntity *GetNextDynamic( void );
// Determine the color modulation amount
void GetColorModulation( float* color )
{
assert(color);
color[0] = color[1] = color[2] = 1.0f;
}
// Should this object be able to have shadows cast onto it?
virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
// Static members
public:
// List of dynamically allocated temp entis
static C_BaseTempEntity *GetDynamicList();
// Called at startup to allow temp entities to precache any models/sounds that they need
static void PrecacheTempEnts( void );
static void ClearDynamicTempEnts( void );
static void CheckDynamicTempEnts( void );
private:
// Next in chain
C_BaseTempEntity *m_pNext;
C_BaseTempEntity *m_pNextDynamic;
// TEs add themselves to this list for the executable.
static C_BaseTempEntity *s_pTempEntities;
static C_BaseTempEntity *s_pDynamicEntities;
};
#endif // C_BASETEMPENTITY_H

View File

@ -0,0 +1,432 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client side view model implementation. Responsible for drawing
// the view model.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "c_baseviewmodel.h"
#include "model_types.h"
#include "hud.h"
#include "view_shared.h"
#include "iviewrender.h"
#include "view.h"
#include "mathlib/vmatrix.h"
#include "cl_animevent.h"
#include "eventlist.h"
#include "tools/bonelist.h"
#include <KeyValues.h>
#include "hltvcamera.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#ifdef CSTRIKE_DLL
ConVar cl_righthand( "cl_righthand", "1", FCVAR_ARCHIVE, "Use right-handed view models." );
#endif
void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
void FormatViewModelAttachment( Vector &vOrigin, bool bInverse )
{
// Presumably, SetUpView has been called so we know our FOV and render origin.
const CViewSetup *pViewSetup = view->GetPlayerViewSetup();
float worldx = tan( pViewSetup->fov * M_PI/360.0 );
float viewx = tan( pViewSetup->fovViewmodel * M_PI/360.0 );
// aspect ratio cancels out, so only need one factor
// the difference between the screen coordinates of the 2 systems is the ratio
// of the coefficients of the projection matrices (tan (fov/2) is that coefficient)
float factorX = worldx / viewx;
float factorY = factorX;
// Get the coordinates in the viewer's space.
Vector tmp = vOrigin - pViewSetup->origin;
Vector vTransformed( MainViewRight().Dot( tmp ), MainViewUp().Dot( tmp ), MainViewForward().Dot( tmp ) );
// Now squash X and Y.
if ( bInverse )
{
if ( factorX != 0 && factorY != 0 )
{
vTransformed.x /= factorX;
vTransformed.y /= factorY;
}
else
{
vTransformed.x = 0.0f;
vTransformed.y = 0.0f;
}
}
else
{
vTransformed.x *= factorX;
vTransformed.y *= factorY;
}
// Transform back to world space.
Vector vOut = (MainViewRight() * vTransformed.x) + (MainViewUp() * vTransformed.y) + (MainViewForward() * vTransformed.z);
vOrigin = pViewSetup->origin + vOut;
}
void C_BaseViewModel::FormatViewModelAttachment( int nAttachment, matrix3x4_t &attachmentToWorld )
{
Vector vecOrigin;
MatrixPosition( attachmentToWorld, vecOrigin );
::FormatViewModelAttachment( vecOrigin, false );
PositionMatrix( vecOrigin, attachmentToWorld );
}
bool C_BaseViewModel::IsViewModel() const
{
return true;
}
void C_BaseViewModel::UncorrectViewModelAttachment( Vector &vOrigin )
{
// Unformat the attachment.
::FormatViewModelAttachment( vOrigin, true );
}
//-----------------------------------------------------------------------------
// Purpose
//-----------------------------------------------------------------------------
void C_BaseViewModel::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
{
// We override sound requests so that we can play them locally on the owning player
if ( ( event == AE_CL_PLAYSOUND ) || ( event == CL_EVENT_SOUND ) )
{
// Only do this if we're owned by someone
if ( GetOwner() != NULL )
{
CLocalPlayerFilter filter;
EmitSound( filter, GetOwner()->GetSoundSourceIndex(), options, &GetAbsOrigin() );
return;
}
}
// Otherwise pass the event to our associated weapon
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
if ( pWeapon )
{
bool bResult = pWeapon->OnFireEvent( this, origin, angles, event, options );
if ( !bResult )
{
BaseClass::FireEvent( origin, angles, event, options );
}
}
}
bool C_BaseViewModel::Interpolate( float currentTime )
{
CStudioHdr *pStudioHdr = GetModelPtr();
// Make sure we reset our animation information if we've switch sequences
UpdateAnimationParity();
bool bret = BaseClass::Interpolate( currentTime );
// Hack to extrapolate cycle counter for view model
float elapsed_time = currentTime - m_flAnimTime;
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
// Predicted viewmodels have fixed up interval
if ( GetPredictable() || IsClientCreated() )
{
Assert( pPlayer );
float curtime = pPlayer ? pPlayer->GetFinalPredictedTime() : gpGlobals->curtime;
elapsed_time = curtime - m_flAnimTime;
// Adjust for interpolated partial frame
elapsed_time += ( gpGlobals->interpolation_amount * TICK_INTERVAL );
}
// Prediction errors?
if ( elapsed_time < 0 )
{
elapsed_time = 0;
}
float dt = elapsed_time * GetSequenceCycleRate( pStudioHdr, GetSequence() );
if ( dt >= 1.0f )
{
if ( !IsSequenceLooping( GetSequence() ) )
{
dt = 0.999f;
}
else
{
dt = fmod( dt, 1.0f );
}
}
SetCycle( dt );
return bret;
}
inline bool C_BaseViewModel::ShouldFlipViewModel()
{
#ifdef CSTRIKE_DLL
// If cl_righthand is set, then we want them all right-handed.
CBaseCombatWeapon *pWeapon = m_hWeapon.Get();
if ( pWeapon )
{
const FileWeaponInfo_t *pInfo = &pWeapon->GetWpnData();
return pInfo->m_bAllowFlipping && pInfo->m_bBuiltRightHanded != cl_righthand.GetBool();
}
#endif
return false;
}
void C_BaseViewModel::ApplyBoneMatrixTransform( matrix3x4_t& transform )
{
if ( ShouldFlipViewModel() )
{
matrix3x4_t viewMatrix, viewMatrixInverse;
// We could get MATERIAL_VIEW here, but this is called sometimes before the renderer
// has set that matrix. Luckily, this is called AFTER the CViewSetup has been initialized.
const CViewSetup *pSetup = view->GetPlayerViewSetup();
AngleMatrix( pSetup->angles, pSetup->origin, viewMatrixInverse );
MatrixInvert( viewMatrixInverse, viewMatrix );
// Transform into view space.
matrix3x4_t temp, temp2;
ConcatTransforms( viewMatrix, transform, temp );
// Flip it along X.
// (This is the slower way to do it, and it equates to negating the top row).
//matrix3x4_t mScale;
//SetIdentityMatrix( mScale );
//mScale[0][0] = 1;
//mScale[1][1] = -1;
//mScale[2][2] = 1;
//ConcatTransforms( mScale, temp, temp2 );
temp[1][0] = -temp[1][0];
temp[1][1] = -temp[1][1];
temp[1][2] = -temp[1][2];
temp[1][3] = -temp[1][3];
// Transform back out of view space.
ConcatTransforms( viewMatrixInverse, temp, transform );
}
}
//-----------------------------------------------------------------------------
// Purpose: check if weapon viewmodel should be drawn
//-----------------------------------------------------------------------------
bool C_BaseViewModel::ShouldDraw()
{
if ( engine->IsHLTV() )
{
return ( HLTVCamera()->GetMode() == OBS_MODE_IN_EYE &&
HLTVCamera()->GetPrimaryTarget() == GetOwner() );
}
else
{
return BaseClass::ShouldDraw();
}
}
//-----------------------------------------------------------------------------
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
// by this player, otherwise draw the worldmodel.
//-----------------------------------------------------------------------------
int C_BaseViewModel::DrawModel( int flags )
{
if ( !m_bReadyToDraw )
return 0;
if ( flags & STUDIO_RENDER )
{
// Determine blending amount and tell engine
float blend = (float)( GetFxBlend() / 255.0f );
// Totally gone
if ( blend <= 0.0f )
return 0;
// Tell engine
render->SetBlend( blend );
float color[3];
GetColorModulation( color );
render->SetColorModulation( color );
}
CMatRenderContextPtr pRenderContext( materials );
if ( ShouldFlipViewModel() )
pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
C_BaseCombatWeapon *pWeapon = GetOwningWeapon();
int ret;
// If the local player's overriding the viewmodel rendering, let him do it
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
{
ret = pPlayer->DrawOverriddenViewmodel( this, flags );
}
else if ( pWeapon && pWeapon->IsOverridingViewmodel() )
{
ret = pWeapon->DrawOverriddenViewmodel( this, flags );
}
else
{
ret = BaseClass::DrawModel( flags );
}
pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
// Now that we've rendered, reset the animation restart flag
if ( flags & STUDIO_RENDER )
{
if ( m_nOldAnimationParity != m_nAnimationParity )
{
m_nOldAnimationParity = m_nAnimationParity;
}
// Tell the weapon itself that we've rendered, in case it wants to do something
if ( pWeapon )
{
pWeapon->ViewModelDrawn( this );
}
}
return ret;
}
//-----------------------------------------------------------------------------
// Purpose: Called by the player when the player's overriding the viewmodel drawing. Avoids infinite recursion.
//-----------------------------------------------------------------------------
int C_BaseViewModel::DrawOverriddenViewmodel( int flags )
{
return BaseClass::DrawModel( flags );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : int
//-----------------------------------------------------------------------------
int C_BaseViewModel::GetFxBlend( void )
{
// See if the local player wants to override the viewmodel's rendering
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
{
pPlayer->ComputeFxBlend();
return pPlayer->GetFxBlend();
}
C_BaseCombatWeapon *pWeapon = GetOwningWeapon();
if ( pWeapon && pWeapon->IsOverridingViewmodel() )
{
pWeapon->ComputeFxBlend();
return pWeapon->GetFxBlend();
}
return BaseClass::GetFxBlend();
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool C_BaseViewModel::IsTransparent( void )
{
// See if the local player wants to override the viewmodel's rendering
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
{
return pPlayer->ViewModel_IsTransparent();
}
C_BaseCombatWeapon *pWeapon = GetOwningWeapon();
if ( pWeapon && pWeapon->IsOverridingViewmodel() )
return pWeapon->ViewModel_IsTransparent();
return BaseClass::IsTransparent();
}
//-----------------------------------------------------------------------------
// Purpose: If the animation parity of the weapon has changed, we reset cycle to avoid popping
//-----------------------------------------------------------------------------
void C_BaseViewModel::UpdateAnimationParity( void )
{
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
// If we're predicting, then we don't use animation parity because we change the animations on the clientside
// while predicting. When not predicting, only the server changes the animations, so a parity mismatch
// tells us if we need to reset the animation.
if ( m_nOldAnimationParity != m_nAnimationParity && !GetPredictable() )
{
float curtime = (pPlayer && IsIntermediateDataAllocated()) ? pPlayer->GetFinalPredictedTime() : gpGlobals->curtime;
// FIXME: this is bad
// Simulate a networked m_flAnimTime and m_flCycle
// FIXME: Do we need the magic 0.1?
SetCycle( 0.0f ); // GetSequenceCycleRate( GetSequence() ) * 0.1;
m_flAnimTime = curtime;
}
}
//-----------------------------------------------------------------------------
// Purpose: Update global map state based on data received
// Input : bnewentity -
//-----------------------------------------------------------------------------
void C_BaseViewModel::OnDataChanged( DataUpdateType_t updateType )
{
SetPredictionEligible( true );
BaseClass::OnDataChanged(updateType);
}
void C_BaseViewModel::PostDataUpdate( DataUpdateType_t updateType )
{
BaseClass::PostDataUpdate(updateType);
OnLatchInterpolatedVariables( LATCH_ANIMATION_VAR );
}
//-----------------------------------------------------------------------------
// Purpose: Add entity to visible view models list
//-----------------------------------------------------------------------------
void C_BaseViewModel::AddEntity( void )
{
// Server says don't interpolate this frame, so set previous info to new info.
if ( IsEffectActive(EF_NOINTERP) )
{
ResetLatched();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseViewModel::GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS])
{
BaseClass::GetBoneControllers( controllers );
// Tell the weapon itself that we've rendered, in case it wants to do something
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
if ( pWeapon )
{
pWeapon->GetViewmodelBoneControllers( this, controllers );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : RenderGroup_t
//-----------------------------------------------------------------------------
RenderGroup_t C_BaseViewModel::GetRenderGroup()
{
return RENDER_GROUP_VIEW_MODEL_OPAQUE;
}

View File

@ -0,0 +1,19 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client side view model implementation. Responsible for drawing
// the view model.
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_BASEVIEWMODEL_H
#define C_BASEVIEWMODEL_H
#ifdef _WIN32
#pragma once
#endif
#include "c_baseanimating.h"
#include "UtlVector.h"
#include "baseviewmodel_shared.h"
#endif // C_BASEVIEWMODEL_H

View File

@ -0,0 +1,46 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "model_types.h"
#include "vcollide.h"
#include "vcollide_parse.h"
#include "solidsetdefaults.h"
#include "bone_setup.h"
#include "engine/ivmodelinfo.h"
#include "physics.h"
#include "c_breakableprop.h"
#include "view.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
IMPLEMENT_CLIENTCLASS_DT(C_BreakableProp, DT_BreakableProp, CBreakableProp)
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_BreakableProp::C_BreakableProp( void )
{
m_takedamage = DAMAGE_YES;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BreakableProp::SetFadeMinMax( float fademin, float fademax )
{
m_fadeMinDist = fademin;
m_fadeMaxDist = fademax;
}
//-----------------------------------------------------------------------------
// Copy fade from another breakable prop
//-----------------------------------------------------------------------------
void C_BreakableProp::CopyFadeFrom( C_BreakableProp *pSource )
{
m_flFadeScale = pSource->m_flFadeScale;
}

View File

@ -0,0 +1,30 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef C_BREAKABLEPROP_H
#define C_BREAKABLEPROP_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class C_BreakableProp : public C_BaseAnimating
{
typedef C_BaseAnimating BaseClass;
public:
DECLARE_CLIENTCLASS();
C_BreakableProp();
virtual void SetFadeMinMax( float fademin, float fademax );
// Copy fade from another breakable prop
void CopyFadeFrom( C_BreakableProp *pSource );
};
#endif // C_BREAKABLEPROP_H

View File

@ -0,0 +1,156 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Color correction entity with simple radial falloff
//
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "filesystem.h"
#include "cdll_client_int.h"
#include "colorcorrectionmgr.h"
#include "materialsystem/materialsystemutil.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static ConVar mat_colcorrection_disableentities( "mat_colcorrection_disableentities", "0", FCVAR_NONE, "Disable map color-correction entities" );
//------------------------------------------------------------------------------
// Purpose : Color correction entity with radial falloff
//------------------------------------------------------------------------------
class C_ColorCorrection : public C_BaseEntity
{
public:
DECLARE_CLASS( C_ColorCorrection, C_BaseEntity );
DECLARE_CLIENTCLASS();
C_ColorCorrection();
virtual ~C_ColorCorrection();
void OnDataChanged(DataUpdateType_t updateType);
bool ShouldDraw();
void ClientThink();
private:
Vector m_vecOrigin;
float m_minFalloff;
float m_maxFalloff;
float m_flCurWeight;
char m_netLookupFilename[MAX_PATH];
bool m_bEnabled;
ClientCCHandle_t m_CCHandle;
};
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrection, DT_ColorCorrection, CColorCorrection)
RecvPropVector( RECVINFO(m_vecOrigin) ),
RecvPropFloat( RECVINFO(m_minFalloff) ),
RecvPropFloat( RECVINFO(m_maxFalloff) ),
RecvPropFloat( RECVINFO(m_flCurWeight) ),
RecvPropString( RECVINFO(m_netLookupFilename) ),
RecvPropBool( RECVINFO(m_bEnabled) ),
END_RECV_TABLE()
//------------------------------------------------------------------------------
// Constructor, destructor
//------------------------------------------------------------------------------
C_ColorCorrection::C_ColorCorrection()
{
m_CCHandle = INVALID_CLIENT_CCHANDLE;
}
C_ColorCorrection::~C_ColorCorrection()
{
g_pColorCorrectionMgr->RemoveColorCorrection( m_CCHandle );
}
//------------------------------------------------------------------------------
// Purpose :
// Input :
// Output :
//------------------------------------------------------------------------------
void C_ColorCorrection::OnDataChanged(DataUpdateType_t updateType)
{
BaseClass::OnDataChanged( updateType );
if ( updateType == DATA_UPDATE_CREATED )
{
if ( m_CCHandle == INVALID_CLIENT_CCHANDLE )
{
char filename[MAX_PATH];
Q_strncpy( filename, m_netLookupFilename, MAX_PATH );
m_CCHandle = g_pColorCorrectionMgr->AddColorCorrection( filename );
SetNextClientThink( ( m_CCHandle != INVALID_CLIENT_CCHANDLE ) ? CLIENT_THINK_ALWAYS : CLIENT_THINK_NEVER );
}
}
}
//------------------------------------------------------------------------------
// We don't draw...
//------------------------------------------------------------------------------
bool C_ColorCorrection::ShouldDraw()
{
return false;
}
void C_ColorCorrection::ClientThink()
{
if ( m_CCHandle == INVALID_CLIENT_CCHANDLE )
return;
if ( mat_colcorrection_disableentities.GetInt() )
{
// Allow the colorcorrectionui panel (or user) to turn off color-correction entities
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f );
return;
}
if( !m_bEnabled && m_flCurWeight == 0.0f )
{
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f );
return;
}
CBaseEntity *pPlayer = UTIL_PlayerByIndex(1);
if( !pPlayer )
return;
Vector playerOrigin = pPlayer->GetAbsOrigin();
float weight = 0;
if ( ( m_minFalloff != -1 ) && ( m_maxFalloff != -1 ) && m_minFalloff != m_maxFalloff )
{
float dist = (playerOrigin - m_vecOrigin).Length();
weight = (dist-m_minFalloff) / (m_maxFalloff-m_minFalloff);
if ( weight<0.0f ) weight = 0.0f;
if ( weight>1.0f ) weight = 1.0f;
}
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_flCurWeight * ( 1.0 - weight ) );
BaseClass::ClientThink();
}

View File

@ -0,0 +1,119 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Color correction entity.
//
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "filesystem.h"
#include "cdll_client_int.h"
#include "materialsystem/materialsystemutil.h"
#include "colorcorrectionmgr.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//------------------------------------------------------------------------------
// FIXME: This really should inherit from something more lightweight
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Purpose : Shadow control entity
//------------------------------------------------------------------------------
class C_ColorCorrectionVolume : public C_BaseEntity
{
public:
DECLARE_CLASS( C_ColorCorrectionVolume, C_BaseEntity );
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
C_ColorCorrectionVolume();
virtual ~C_ColorCorrectionVolume();
void OnDataChanged(DataUpdateType_t updateType);
bool ShouldDraw();
void ClientThink();
private:
float m_Weight;
char m_lookupFilename[MAX_PATH];
ClientCCHandle_t m_CCHandle;
};
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrectionVolume, DT_ColorCorrectionVolume, CColorCorrectionVolume)
RecvPropFloat( RECVINFO(m_Weight) ),
RecvPropString( RECVINFO(m_lookupFilename) ),
END_RECV_TABLE()
BEGIN_PREDICTION_DATA( C_ColorCorrectionVolume )
DEFINE_PRED_FIELD( m_Weight, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()
//------------------------------------------------------------------------------
// Constructor, destructor
//------------------------------------------------------------------------------
C_ColorCorrectionVolume::C_ColorCorrectionVolume()
{
m_CCHandle = INVALID_CLIENT_CCHANDLE;
}
C_ColorCorrectionVolume::~C_ColorCorrectionVolume()
{
g_pColorCorrectionMgr->RemoveColorCorrection( m_CCHandle );
}
//------------------------------------------------------------------------------
// Purpose :
// Input :
// Output :
//------------------------------------------------------------------------------
void C_ColorCorrectionVolume::OnDataChanged(DataUpdateType_t updateType)
{
BaseClass::OnDataChanged( updateType );
if ( updateType == DATA_UPDATE_CREATED )
{
if ( m_CCHandle == INVALID_CLIENT_CCHANDLE )
{
char filename[MAX_PATH];
Q_strncpy( filename, m_lookupFilename, MAX_PATH );
m_CCHandle = g_pColorCorrectionMgr->AddColorCorrection( filename );
SetNextClientThink( ( m_CCHandle != INVALID_CLIENT_CCHANDLE ) ? CLIENT_THINK_ALWAYS : CLIENT_THINK_NEVER );
}
}
}
//------------------------------------------------------------------------------
// We don't draw...
//------------------------------------------------------------------------------
bool C_ColorCorrectionVolume::ShouldDraw()
{
return false;
}
void C_ColorCorrectionVolume::ClientThink()
{
Vector entityPosition = GetAbsOrigin();
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_Weight );
}

View File

@ -0,0 +1,237 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Dynamic light
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "dlight.h"
#include "iefx.h"
#include "IViewRender.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#if HL2_EPISODIC
// In Episodic we unify the NO_WORLD_ILLUMINATION lights to use
// the more efficient elight structure instead. This should theoretically
// be extended to other projects but may have unintended consequences
// and bears more thorough testing.
//
// For an earlier iteration on this technique see changelist 214433,
// which had a specific flag for use of elights.
#define DLIGHT_NO_WORLD_USES_ELIGHT 1
#endif
//-----------------------------------------------------------------------------
// A dynamic light, with the goofy hack needed for spotlights
//-----------------------------------------------------------------------------
class C_DynamicLight : public C_BaseEntity
{
public:
DECLARE_CLASS( C_DynamicLight, C_BaseEntity );
DECLARE_CLIENTCLASS();
C_DynamicLight();
public:
void OnDataChanged(DataUpdateType_t updateType);
bool ShouldDraw();
void ClientThink( void );
void Release( void );
unsigned char m_Flags;
unsigned char m_LightStyle;
float m_Radius;
int m_Exponent;
float m_InnerAngle;
float m_OuterAngle;
float m_SpotRadius;
private:
dlight_t* m_pDynamicLight;
dlight_t* m_pSpotlightEnd;
inline bool ShouldBeElight() { return (m_Flags & DLIGHT_NO_WORLD_ILLUMINATION); }
};
IMPLEMENT_CLIENTCLASS_DT(C_DynamicLight, DT_DynamicLight, CDynamicLight)
RecvPropInt (RECVINFO(m_Flags)),
RecvPropInt (RECVINFO(m_LightStyle)),
RecvPropFloat (RECVINFO(m_Radius)),
RecvPropInt (RECVINFO(m_Exponent)),
RecvPropFloat (RECVINFO(m_InnerAngle)),
RecvPropFloat (RECVINFO(m_OuterAngle)),
RecvPropFloat (RECVINFO(m_SpotRadius)),
END_RECV_TABLE()
//------------------------------------------------------------------------------
// Purpose :
//------------------------------------------------------------------------------
C_DynamicLight::C_DynamicLight(void) : m_pSpotlightEnd(0), m_pDynamicLight(0)
{
}
//------------------------------------------------------------------------------
// Purpose :
//------------------------------------------------------------------------------
void C_DynamicLight::OnDataChanged(DataUpdateType_t updateType)
{
if ( updateType == DATA_UPDATE_CREATED )
{
SetNextClientThink(gpGlobals->curtime + 0.05);
}
BaseClass::OnDataChanged( updateType );
}
//------------------------------------------------------------------------------
// Purpose :
//------------------------------------------------------------------------------
bool C_DynamicLight::ShouldDraw()
{
return false;
}
//------------------------------------------------------------------------------
// Purpose : Disable drawing of this light when entity perishes
//------------------------------------------------------------------------------
void C_DynamicLight::Release()
{
if (m_pDynamicLight)
{
m_pDynamicLight->die = gpGlobals->curtime;
m_pDynamicLight = 0;
}
if (m_pSpotlightEnd)
{
m_pSpotlightEnd->die = gpGlobals->curtime;
m_pSpotlightEnd = 0;
}
BaseClass::Release();
}
//------------------------------------------------------------------------------
// Purpose :
//------------------------------------------------------------------------------
void C_DynamicLight::ClientThink(void)
{
Vector forward;
AngleVectors( GetAbsAngles(), &forward );
if ( (m_Flags & DLIGHT_NO_MODEL_ILLUMINATION) == 0 )
{
// Deal with the model light
if ( !m_pDynamicLight || (m_pDynamicLight->key != index) )
{
#if DLIGHT_NO_WORLD_USES_ELIGHT
m_pDynamicLight = ShouldBeElight() != 0
? effects->CL_AllocElight( index )
: effects->CL_AllocDlight( index );
#else
m_pDynamicLight = effects->CL_AllocDlight( index );
#endif
Assert (m_pDynamicLight);
m_pDynamicLight->minlight = 0;
}
m_pDynamicLight->style = m_LightStyle;
m_pDynamicLight->radius = m_Radius;
m_pDynamicLight->flags = m_Flags;
if ( m_OuterAngle > 0 )
m_pDynamicLight->flags |= DLIGHT_NO_WORLD_ILLUMINATION;
m_pDynamicLight->color.r = m_clrRender->r;
m_pDynamicLight->color.g = m_clrRender->g;
m_pDynamicLight->color.b = m_clrRender->b;
m_pDynamicLight->color.exponent = m_Exponent; // this makes it match the world
m_pDynamicLight->origin = GetAbsOrigin();
m_pDynamicLight->m_InnerAngle = m_InnerAngle;
m_pDynamicLight->m_OuterAngle = m_OuterAngle;
m_pDynamicLight->die = gpGlobals->curtime + 1e6;
m_pDynamicLight->m_Direction = forward;
}
else
{
// In this case, the m_Flags could have changed; which is how we turn the light off
if (m_pDynamicLight)
{
m_pDynamicLight->die = gpGlobals->curtime;
m_pDynamicLight = 0;
}
}
#if DLIGHT_NO_WORLD_USES_ELIGHT
if (( m_OuterAngle > 0 ) && !ShouldBeElight())
#else
if (( m_OuterAngle > 0 ) && ((m_Flags & DLIGHT_NO_WORLD_ILLUMINATION) == 0))
#endif
{
// Raycast to where the endpoint goes
// Deal with the environment light
if ( !m_pSpotlightEnd || (m_pSpotlightEnd->key != -index) )
{
m_pSpotlightEnd = effects->CL_AllocDlight( -index );
Assert (m_pSpotlightEnd);
}
// Trace a line outward, don't use hitboxes (too slow)
Vector end;
VectorMA( GetAbsOrigin(), m_Radius, forward, end );
trace_t pm;
C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace
UTIL_TraceLine( GetAbsOrigin(), end, MASK_NPCWORLDSTATIC, NULL, COLLISION_GROUP_NONE, &pm );
C_BaseEntity::PopEnableAbsRecomputations();
VectorCopy( pm.endpos, m_pSpotlightEnd->origin );
if (pm.fraction == 1.0f)
{
m_pSpotlightEnd->die = gpGlobals->curtime;
m_pSpotlightEnd = 0;
}
else
{
float falloff = 1.0 - pm.fraction;
falloff *= falloff;
m_pSpotlightEnd->style = m_LightStyle;
m_pSpotlightEnd->flags = DLIGHT_NO_MODEL_ILLUMINATION | (m_Flags & DLIGHT_DISPLACEMENT_MASK);
m_pSpotlightEnd->radius = m_SpotRadius; // * falloff;
m_pSpotlightEnd->die = gpGlobals->curtime + 1e6;
m_pSpotlightEnd->color.r = m_clrRender->r * falloff;
m_pSpotlightEnd->color.g = m_clrRender->g * falloff;
m_pSpotlightEnd->color.b = m_clrRender->b * falloff;
m_pSpotlightEnd->color.exponent = m_Exponent;
// For bumped lighting
m_pSpotlightEnd->m_Direction = forward;
// Update list of surfaces we influence
render->TouchLight( m_pSpotlightEnd );
}
}
else
{
// In this case, the m_Flags could have changed; which is how we turn the light off
if (m_pSpotlightEnd)
{
m_pSpotlightEnd->die = gpGlobals->curtime;
m_pSpotlightEnd = 0;
}
}
SetNextClientThink(gpGlobals->curtime + 0.001);
}

2220
game/client/c_effects.cpp Normal file

File diff suppressed because it is too large Load Diff

18
game/client/c_effects.h Normal file
View File

@ -0,0 +1,18 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef C_EFFECTS_H
#define C_EFFECTS_H
#ifdef _WIN32
#pragma once
#endif
// Draw rain effects.
void DrawPrecipitation();
#endif // C_EFFECTS_H

View File

@ -0,0 +1,773 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "IViewRender.h"
#include "view.h"
#include "studio.h"
#include "bone_setup.h"
#include "model_types.h"
#include "beamdraw.h"
#include "engine/ivdebugoverlay.h"
#include "iviewrender_beams.h"
#include "fx.h"
#include "IEffects.h"
#include "c_entitydissolve.h"
#include "movevars_shared.h"
#include "ClientEffectPrecacheSystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectBuild )
CLIENTEFFECT_MATERIAL( "effects/tesla_glow_noz" )
CLIENTEFFECT_MATERIAL( "effects/spark" )
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2" )
CLIENTEFFECT_REGISTER_END()
//-----------------------------------------------------------------------------
// Networking
//-----------------------------------------------------------------------------
IMPLEMENT_CLIENTCLASS_DT( C_EntityDissolve, DT_EntityDissolve, CEntityDissolve )
RecvPropTime(RECVINFO(m_flStartTime)),
RecvPropFloat(RECVINFO(m_flFadeOutStart)),
RecvPropFloat(RECVINFO(m_flFadeOutLength)),
RecvPropFloat(RECVINFO(m_flFadeOutModelStart)),
RecvPropFloat(RECVINFO(m_flFadeOutModelLength)),
RecvPropFloat(RECVINFO(m_flFadeInStart)),
RecvPropFloat(RECVINFO(m_flFadeInLength)),
RecvPropInt(RECVINFO(m_nDissolveType)),
RecvPropVector( RECVINFO( m_vDissolverOrigin) ),
RecvPropInt( RECVINFO( m_nMagnitude ) ),
END_RECV_TABLE()
extern PMaterialHandle g_Material_Spark;
PMaterialHandle g_Material_AR2Glow = NULL;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_EntityDissolve::C_EntityDissolve( void )
{
m_bLinkedToServerEnt = true;
m_pController = false;
m_bCoreExplode = false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityDissolve::GetRenderBounds( Vector& theMins, Vector& theMaxs )
{
if ( GetMoveParent() )
{
GetMoveParent()->GetRenderBounds( theMins, theMaxs );
}
else
{
theMins = GetAbsOrigin();
theMaxs = theMaxs;
}
}
//-----------------------------------------------------------------------------
// On data changed
//-----------------------------------------------------------------------------
void C_EntityDissolve::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged( updateType );
if ( updateType == DATA_UPDATE_CREATED )
{
m_flNextSparkTime = m_flStartTime;
SetNextClientThink( CLIENT_THINK_ALWAYS );
}
}
//-----------------------------------------------------------------------------
// Cleanup
//-----------------------------------------------------------------------------
void C_EntityDissolve::UpdateOnRemove( void )
{
if ( m_pController )
{
physenv->DestroyMotionController( m_pController );
m_pController = NULL;
}
BaseClass::UpdateOnRemove();
}
//------------------------------------------------------------------------------
// Apply the forces to the entity
//------------------------------------------------------------------------------
IMotionEvent::simresult_e C_EntityDissolve::Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular )
{
linear.Init();
angular.Init();
// Make it zero g
linear.z -= -1.02 * sv_gravity.GetFloat();
Vector vel;
AngularImpulse angVel;
pObject->GetVelocity( &vel, &angVel );
vel += linear * deltaTime; // account for gravity scale
Vector unitVel = vel;
Vector unitAngVel = angVel;
float speed = VectorNormalize( unitVel );
// float angSpeed = VectorNormalize( unitAngVel );
// float speedScale = 0.0;
// float angSpeedScale = 0.0;
float flLinearLimit = 50;
float flLinearLimitDelta = 40;
if ( speed > flLinearLimit )
{
float flDeltaVel = (flLinearLimit - speed) / deltaTime;
if ( flLinearLimitDelta != 0.0f )
{
float flMaxDeltaVel = -flLinearLimitDelta / deltaTime;
if ( flDeltaVel < flMaxDeltaVel )
{
flDeltaVel = flMaxDeltaVel;
}
}
VectorMA( linear, flDeltaVel, unitVel, linear );
}
return SIM_GLOBAL_ACCELERATION;
}
//-----------------------------------------------------------------------------
// Tesla effect
//-----------------------------------------------------------------------------
static void FX_BuildTesla( C_BaseEntity *pEntity, Vector &vecOrigin, Vector &vecEnd )
{
BeamInfo_t beamInfo;
beamInfo.m_pStartEnt = pEntity;
beamInfo.m_nStartAttachment = 0;
beamInfo.m_pEndEnt = NULL;
beamInfo.m_nEndAttachment = 0;
beamInfo.m_nType = TE_BEAMTESLA;
beamInfo.m_vecStart = vecOrigin;
beamInfo.m_vecEnd = vecEnd;
beamInfo.m_pszModelName = "sprites/lgtning.vmt";
beamInfo.m_flHaloScale = 0.0;
beamInfo.m_flLife = random->RandomFloat( 0.25f, 1.0f );
beamInfo.m_flWidth = random->RandomFloat( 8.0f, 14.0f );
beamInfo.m_flEndWidth = 1.0f;
beamInfo.m_flFadeLength = 0.5f;
beamInfo.m_flAmplitude = 24;
beamInfo.m_flBrightness = 255.0;
beamInfo.m_flSpeed = 150.0f;
beamInfo.m_nStartFrame = 0.0;
beamInfo.m_flFrameRate = 30.0;
beamInfo.m_flRed = 255.0;
beamInfo.m_flGreen = 255.0;
beamInfo.m_flBlue = 255.0;
beamInfo.m_nSegments = 18;
beamInfo.m_bRenderable = true;
beamInfo.m_nFlags = 0; //FBEAM_ONLYNOISEONCE;
beams->CreateBeamEntPoint( beamInfo );
}
//-----------------------------------------------------------------------------
// Purpose: Tesla effect
//-----------------------------------------------------------------------------
void C_EntityDissolve::BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset )
{
Vector vecOrigin;
QAngle vecAngles;
MatrixGetColumn( hitboxToWorld, 3, vecOrigin );
MatrixAngles( hitboxToWorld, vecAngles.Base() );
C_BaseEntity *pEntity = GetMoveParent();
// Make a couple of tries at it
int iTries = -1;
Vector vecForward;
trace_t tr;
do
{
iTries++;
// Some beams are deliberatly aimed around the point, the rest are random.
if ( !bRandom )
{
QAngle vecTemp = vecAngles;
vecTemp[YAW] += flYawOffset;
AngleVectors( vecTemp, &vecForward );
// Randomly angle it up or down
vecForward.z = RandomFloat( -1, 1 );
}
else
{
vecForward = RandomVector( -1, 1 );
}
UTIL_TraceLine( vecOrigin, vecOrigin + (vecForward * 192), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr );
} while ( tr.fraction >= 1.0 && iTries < 3 );
Vector vecEnd = tr.endpos - (vecForward * 8);
// Only spark & glow if we hit something
if ( tr.fraction < 1.0 )
{
if ( !EffectOccluded( tr.endpos ) )
{
// Move it towards the camera
Vector vecFlash = tr.endpos;
Vector vecForward;
AngleVectors( MainViewAngles(), &vecForward );
vecFlash -= (vecForward * 8);
g_pEffects->EnergySplash( vecFlash, -vecForward, false );
// End glow
CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
pSimple->SetSortOrigin( vecFlash );
SimpleParticle *pParticle;
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash );
if ( pParticle != NULL )
{
pParticle->m_flLifetime = 0.0f;
pParticle->m_flDieTime = RandomFloat( 0.5, 1 );
pParticle->m_vecVelocity = vec3_origin;
Vector color( 1,1,1 );
float colorRamp = RandomFloat( 0.75f, 1.25f );
pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f;
pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f;
pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f;
pParticle->m_uchStartSize = RandomFloat( 6,13 );
pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2;
pParticle->m_uchStartAlpha = 255;
pParticle->m_uchEndAlpha = 10;
pParticle->m_flRoll = RandomFloat( 0,360 );
pParticle->m_flRollDelta = 0;
}
}
}
// Build the tesla
FX_BuildTesla( pEntity, vecOrigin, tr.endpos );
}
//-----------------------------------------------------------------------------
// Sorts the components of a vector
//-----------------------------------------------------------------------------
static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx )
{
Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) );
int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1;
if (absVec[2] > absVec[maxIdx])
{
maxIdx = 2;
}
// always choose something right-handed....
switch( maxIdx )
{
case 0:
pVecIdx[0] = 1;
pVecIdx[1] = 2;
pVecIdx[2] = 0;
break;
case 1:
pVecIdx[0] = 2;
pVecIdx[1] = 0;
pVecIdx[2] = 1;
break;
case 2:
pVecIdx[0] = 0;
pVecIdx[1] = 1;
pVecIdx[2] = 2;
break;
}
}
//-----------------------------------------------------------------------------
// Compute the bounding box's center, size, and basis
//-----------------------------------------------------------------------------
void C_EntityDissolve::ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec )
{
// Compute the center of the hitbox in worldspace
Vector vecHitboxCenter;
VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter );
vecHitboxCenter *= 0.5f;
VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin );
// Get the object's basis
Vector vec[3];
MatrixGetColumn( hitboxToWorld, 0, vec[0] );
MatrixGetColumn( hitboxToWorld, 1, vec[1] );
MatrixGetColumn( hitboxToWorld, 2, vec[2] );
// vec[1] *= -1.0f;
Vector vecViewDir;
VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir );
VectorNormalize( vecViewDir );
// Project the shadow casting direction into the space of the hitbox
Vector localViewDir;
localViewDir[0] = DotProduct( vec[0], vecViewDir );
localViewDir[1] = DotProduct( vec[1], vecViewDir );
localViewDir[2] = DotProduct( vec[2], vecViewDir );
// Figure out which vector has the largest component perpendicular
// to the view direction...
// Sort by how perpendicular it is
int vecIdx[3];
SortAbsVectorComponents( localViewDir, vecIdx );
// Here's our hitbox basis vectors; namely the ones that are
// most perpendicular to the view direction
*pXVec = vec[vecIdx[0]];
*pYVec = vec[vecIdx[1]];
// Project them into a plane perpendicular to the view direction
*pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec );
*pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec );
VectorNormalize( *pXVec );
VectorNormalize( *pYVec );
// Compute the hitbox size
Vector boxSize;
VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize );
// We project the two longest sides into the vectors perpendicular
// to the projection direction, then add in the projection of the perp direction
Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] );
size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) );
size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) );
// Add the third component into x and y
size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) );
size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) );
// Bloat a bit, since the shadow wants to extend outside the model a bit
size *= 2.0f;
// Clamp the minimum size
Vector2DMax( size, Vector2D(10.0f, 10.0f), size );
// Factor the size into the xvec + yvec
(*pXVec) *= size.x * 0.5f;
(*pYVec) *= size.y * 0.5f;
}
//-----------------------------------------------------------------------------
// Sparks!
//-----------------------------------------------------------------------------
void C_EntityDissolve::DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] )
{
if ( m_flNextSparkTime > gpGlobals->curtime )
return;
float dt = m_flStartTime + m_flFadeOutStart - gpGlobals->curtime;
dt = clamp( dt, 0.0f, m_flFadeOutStart );
float flNextTime;
if (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL)
{
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 2.0f * TICK_INTERVAL, 0.4f );
}
else
{
// m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT);
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 0.3f, 1.0f );
}
m_flNextSparkTime = gpGlobals->curtime + flNextTime;
// Send out beams around us
int iNumBeamsAround = 2;
int iNumRandomBeams = 1;
int iTotalBeams = iNumBeamsAround + iNumRandomBeams;
float flYawOffset = RandomFloat(0,360);
for ( int i = 0; i < iTotalBeams; i++ )
{
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
float flActualYawOffset = 0;
bool bRandom = ( i >= iNumBeamsAround );
if ( !bRandom )
{
flActualYawOffset = anglemod( flYawOffset + ((360 / iTotalBeams) * i) );
}
BuildTeslaEffect( pBox, *hitboxbones[pBox->bone], bRandom, flActualYawOffset );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityDissolve::SetupEmitter( void )
{
if ( !m_pEmitter )
{
m_pEmitter = CSimpleEmitter::Create( "C_EntityDissolve" );
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float C_EntityDissolve::GetFadeInPercentage( void )
{
float dt = gpGlobals->curtime - m_flStartTime;
if ( dt > m_flFadeOutStart )
return 1.0f;
if ( dt < m_flFadeInStart )
return 0.0f;
if ( (dt > m_flFadeInStart) && (dt < m_flFadeInStart + m_flFadeInLength) )
{
dt -= m_flFadeInStart;
return ( dt / m_flFadeInLength );
}
return 1.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float C_EntityDissolve::GetFadeOutPercentage( void )
{
float dt = gpGlobals->curtime - m_flStartTime;
if ( dt < m_flFadeInStart )
return 1.0f;
if ( dt > m_flFadeOutStart )
{
dt -= m_flFadeOutStart;
if ( dt > m_flFadeOutLength )
return 0.0f;
return 1.0f - ( dt / m_flFadeOutLength );
}
return 1.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float C_EntityDissolve::GetModelFadeOutPercentage( void )
{
float dt = gpGlobals->curtime - m_flStartTime;
if ( dt < m_flFadeOutModelStart )
return 1.0f;
if ( dt > m_flFadeOutModelStart )
{
dt -= m_flFadeOutModelStart;
if ( dt > m_flFadeOutModelLength )
return 0.0f;
return 1.0f - ( dt / m_flFadeOutModelLength );
}
return 1.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityDissolve::ClientThink( void )
{
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
if (!pAnimating)
return;
// NOTE: IsRagdoll means *client-side* ragdoll. We shouldn't be trying to fight
// the server ragdoll (or any server physics) on the client
if (( !m_pController ) && ( m_nDissolveType == ENTITY_DISSOLVE_NORMAL ) && pAnimating->IsRagdoll())
{
IPhysicsObject *ppList[VPHYSICS_MAX_OBJECT_LIST_COUNT];
int nCount = pAnimating->VPhysicsGetObjectList( ppList, ARRAYSIZE(ppList) );
if ( nCount > 0 )
{
m_pController = physenv->CreateMotionController( this );
for ( int i = 0; i < nCount; ++i )
{
m_pController->AttachObject( ppList[i], true );
}
}
}
color32 color;
color.r = color.g = color.b = ( 1.0f - GetFadeInPercentage() ) * 255.0f;
color.a = GetModelFadeOutPercentage() * 255.0f;
// Setup the entity fade
pAnimating->SetRenderMode( kRenderTransColor );
pAnimating->SetRenderColor( color.r, color.g, color.b, color.a );
if ( GetModelFadeOutPercentage() <= 0.2f )
{
m_bCoreExplode = true;
}
// If we're dead, fade out
if ( GetFadeOutPercentage() <= 0.0f )
{
// Do NOT remove from the client entity list. It'll confuse the local network backdoor, and the entity will never get destroyed
// because when the server says to destroy it, the client won't be able to find it.
// ClientEntityList().RemoveEntity( GetClientHandle() );
partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() );
RemoveFromLeafSystem();
//FIXME: Ick!
//Adrian: I'll assume we don't need the ragdoll either so I'll remove that too.
if ( m_bLinkedToServerEnt == false )
{
Release();
C_ClientRagdoll *pRagdoll = dynamic_cast <C_ClientRagdoll *> ( pAnimating );
if ( pRagdoll )
{
pRagdoll->ReleaseRagdoll();
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : flags -
// Output : int
//-----------------------------------------------------------------------------
int C_EntityDissolve::DrawModel( int flags )
{
// See if we should draw
if ( gpGlobals->frametime == 0 || m_bReadyToDraw == false )
return 0;
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
if ( pAnimating == NULL )
return 0;
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) == false )
return 0;
studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
if ( pStudioHdr == NULL )
return false;
mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
if ( set == NULL )
return false;
// Make sure the emitter is setup properly
SetupEmitter();
// Get fade percentages for the effect
float fadeInPerc = GetFadeInPercentage();
float fadeOutPerc = GetFadeOutPercentage();
float fadePerc = ( fadeInPerc >= 1.0f ) ? fadeOutPerc : fadeInPerc;
Vector vecSkew = vec3_origin;
// Do extra effects under certain circumstances
if ( ( fadePerc < 0.99f ) && ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) )
{
DoSparks( set, hitboxbones );
}
// Skew the particles in front or in back of their targets
vecSkew = CurrentViewForward() * ( 8.0f - ( ( 1.0f - fadePerc ) * 32.0f ) );
float spriteScale = ( ( gpGlobals->curtime - m_flStartTime ) / m_flFadeOutLength );
spriteScale = clamp( spriteScale, 0.75f, 1.0f );
// Cache off this material reference
if ( g_Material_Spark == NULL )
{
g_Material_Spark = ParticleMgr()->GetPMaterial( "effects/spark" );
}
if ( g_Material_AR2Glow == NULL )
{
g_Material_AR2Glow = ParticleMgr()->GetPMaterial( "effects/combinemuzzle2" );
}
SimpleParticle *sParticle;
for ( int i = 0; i < set->numhitboxes; ++i )
{
Vector vecAbsOrigin, xvec, yvec;
mstudiobbox_t *pBox = set->pHitbox(i);
ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );
Vector offset;
Vector xDir, yDir;
xDir = xvec;
float xScale = VectorNormalize( xDir ) * 0.75f;
yDir = yvec;
float yScale = VectorNormalize( yDir ) * 0.75f;
int numParticles = clamp( 3.0f * fadePerc, 0, 3 );
int iTempParts = 2;
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
{
if ( m_bCoreExplode == true )
{
numParticles = 15;
iTempParts = 20;
}
}
for ( int j = 0; j < iTempParts; j++ )
{
// Skew the origin
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
offset += vecSkew;
if ( random->RandomInt( 0, 2 ) != 0 )
continue;
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_Spark, vecAbsOrigin + offset );
if ( sParticle == NULL )
return 1;
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 16.0f, 64.0f ) );
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
{
if ( m_bCoreExplode == true )
{
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
VectorNormalize( vDirection );
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
}
}
if ( sParticle->m_vecVelocity.z > 0 )
{
sParticle->m_uchStartSize = random->RandomFloat( 4, 6 ) * spriteScale;
}
else
{
sParticle->m_uchStartSize = 2 * spriteScale;
}
sParticle->m_flDieTime = random->RandomFloat( 0.4f, 0.5f );
// If we're the last particles, last longer
if ( numParticles == 0 )
{
sParticle->m_flDieTime *= 2.0f;
sParticle->m_uchStartSize = 2 * spriteScale;
sParticle->m_flRollDelta = Helper_RandomFloat( -4.0f, 4.0f );
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
{
if ( m_bCoreExplode == true )
{
sParticle->m_flDieTime *= 2.0f;
sParticle->m_flRollDelta = Helper_RandomFloat( -1.0f, 1.0f );
}
}
}
else
{
sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f, 8.0f );
}
sParticle->m_flLifetime = 0.0f;
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
float alpha = 255;
sParticle->m_uchColor[0] = alpha;
sParticle->m_uchColor[1] = alpha;
sParticle->m_uchColor[2] = alpha;
sParticle->m_uchStartAlpha = alpha;
sParticle->m_uchEndAlpha = 0;
sParticle->m_uchEndSize = 0;
}
for ( int j = 0; j < numParticles; j++ )
{
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
offset += vecSkew;
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_AR2Glow, vecAbsOrigin + offset );
if ( sParticle == NULL )
return 1;
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -64.0f, 128.0f ) );
sParticle->m_uchStartSize = random->RandomFloat( 8, 12 ) * spriteScale;
sParticle->m_flDieTime = 0.1f;
sParticle->m_flLifetime = 0.0f;
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
float alpha = 255;
sParticle->m_uchColor[0] = alpha;
sParticle->m_uchColor[1] = alpha;
sParticle->m_uchColor[2] = alpha;
sParticle->m_uchStartAlpha = alpha;
sParticle->m_uchEndAlpha = 0;
sParticle->m_uchEndSize = 0;
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
{
if ( m_bCoreExplode == true )
{
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
VectorNormalize( vDirection );
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
sParticle->m_flDieTime = 0.5f;
}
}
}
}
return 1;
}

View File

@ -0,0 +1,77 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_ENTITY_DISSOLVE_H
#define C_ENTITY_DISSOLVE_H
#include "cbase.h"
//-----------------------------------------------------------------------------
// Entity Dissolve, client-side implementation
//-----------------------------------------------------------------------------
class C_EntityDissolve : public C_BaseEntity, public IMotionEvent
{
public:
DECLARE_CLIENTCLASS();
DECLARE_CLASS( C_EntityDissolve, C_BaseEntity );
C_EntityDissolve( void );
// Inherited from C_BaseEntity
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
virtual int DrawModel( int flags );
virtual bool ShouldDraw() { return true; }
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void UpdateOnRemove( void );
// Inherited from IMotionEvent
virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular );
void SetupEmitter( void );
void ClientThink( void );
void SetServerLinkState( bool state ) { m_bLinkedToServerEnt = state; }
float m_flStartTime;
float m_flFadeOutStart;
float m_flFadeOutLength;
float m_flFadeOutModelStart;
float m_flFadeOutModelLength;
float m_flFadeInStart;
float m_flFadeInLength;
int m_nDissolveType;
float m_flNextSparkTime;
Vector m_vDissolverOrigin;
int m_nMagnitude;
bool m_bCoreExplode;
protected:
float GetFadeInPercentage( void ); // Fade in amount (entity fading to black)
float GetFadeOutPercentage( void ); // Fade out amount (particles fading away)
float GetModelFadeOutPercentage( void );// Mode fade out amount
// Compute the bounding box's center, size, and basis
void ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec );
void BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset );
void DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] );
private:
CSmartPtr<CSimpleEmitter> m_pEmitter;
bool m_bLinkedToServerEnt;
IPhysicsMotionController *m_pController;
};
#endif // C_ENTITY_DISSOLVE_H

View File

@ -0,0 +1,250 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "baseparticleentity.h"
#include "entityparticletrail_shared.h"
#include "particlemgr.h"
#include "particle_util.h"
#include "particles_simple.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Entity particle trail, client-side implementation
//-----------------------------------------------------------------------------
class C_EntityParticleTrail : public C_BaseParticleEntity
{
public:
DECLARE_CLIENTCLASS();
DECLARE_CLASS( C_EntityParticleTrail, C_BaseParticleEntity );
C_EntityParticleTrail( );
~C_EntityParticleTrail( );
// C_BaseEntity
virtual void OnDataChanged( DataUpdateType_t updateType );
// IParticleEffect
void Update( float fTimeDelta );
virtual void RenderParticles( CParticleRenderIterator *pIterator );
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
private:
C_EntityParticleTrail( const C_EntityParticleTrail & ); // not defined, not accessible
void Start( );
void AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld );
int m_iMaterialName;
EntityParticleTrailInfo_t m_Info;
EHANDLE m_hConstraintEntity;
PMaterialHandle m_hMaterial;
TimedEvent m_teParticleSpawn;
};
//-----------------------------------------------------------------------------
// Networking
//-----------------------------------------------------------------------------
IMPLEMENT_CLIENTCLASS_DT( C_EntityParticleTrail, DT_EntityParticleTrail, CEntityParticleTrail )
RecvPropInt(RECVINFO(m_iMaterialName)),
RecvPropDataTable( RECVINFO_DT( m_Info ), 0, &REFERENCE_RECV_TABLE(DT_EntityParticleTrailInfo) ),
RecvPropEHandle(RECVINFO(m_hConstraintEntity)),
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_EntityParticleTrail::C_EntityParticleTrail( void )
{
}
C_EntityParticleTrail::~C_EntityParticleTrail()
{
ParticleMgr()->RemoveEffect( &m_ParticleEffect );
}
//-----------------------------------------------------------------------------
// On data changed
//-----------------------------------------------------------------------------
void C_EntityParticleTrail::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged( updateType );
if ( updateType == DATA_UPDATE_CREATED )
{
Start( );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pParticleMgr -
// *pArgs -
//-----------------------------------------------------------------------------
void C_EntityParticleTrail::Start( )
{
if( ParticleMgr()->AddEffect( &m_ParticleEffect, this ) == false )
return;
const char *pMaterialName = GetMaterialNameFromIndex( m_iMaterialName );
if ( !pMaterialName )
return;
m_hMaterial = ParticleMgr()->GetPMaterial( pMaterialName );
m_teParticleSpawn.Init( 150 );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityParticleTrail::AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld )
{
// Select a random point somewhere in the hitboxes of the entity.
Vector vecLocalPosition, vecWorldPosition;
vecLocalPosition.x = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.x, vecMaxs.x );
vecLocalPosition.y = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.y, vecMaxs.y );
vecLocalPosition.z = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.z, vecMaxs.z );
VectorTransform( vecLocalPosition, boxToWorld, vecWorldPosition );
// Don't emit the particle unless it's inside the model
if ( m_hConstraintEntity.Get() )
{
Ray_t ray;
trace_t tr;
ray.Init( vecWorldPosition, vecWorldPosition );
enginetrace->ClipRayToEntity( ray, MASK_ALL, m_hConstraintEntity, &tr );
if ( !tr.startsolid )
return;
}
// Make a new particle
SimpleParticle *pParticle = (SimpleParticle *)m_ParticleEffect.AddParticle( sizeof(SimpleParticle), m_hMaterial );
if ( pParticle == NULL )
return;
pParticle->m_Pos = vecWorldPosition;
pParticle->m_flRoll = Helper_RandomInt( 0, 360 );
pParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
pParticle->m_flLifetime = flInitialDeltaTime;
pParticle->m_flDieTime = m_Info.m_flLifetime;
pParticle->m_uchColor[0] = 64;
pParticle->m_uchColor[1] = 140;
pParticle->m_uchColor[2] = 225;
pParticle->m_uchStartAlpha = Helper_RandomInt( 64, 64 );
pParticle->m_uchEndAlpha = 0;
pParticle->m_uchStartSize = m_Info.m_flStartSize;
pParticle->m_uchEndSize = m_Info.m_flEndSize;
pParticle->m_vecVelocity = vec3_origin;
VectorMA( pParticle->m_Pos, flInitialDeltaTime, pParticle->m_vecVelocity, pParticle->m_Pos );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : fTimeDelta -
//-----------------------------------------------------------------------------
void C_EntityParticleTrail::Update( float fTimeDelta )
{
float tempDelta = fTimeDelta;
studiohdr_t *pStudioHdr;
mstudiohitboxset_t *set;
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
C_BaseEntity *pMoveParent = GetMoveParent();
if ( !pMoveParent )
return;
C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating();
if (!pAnimating)
goto trailNoHitboxes;
if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
goto trailNoHitboxes;
pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
if (!pStudioHdr)
goto trailNoHitboxes;
set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
if ( !set )
goto trailNoHitboxes;
//Add new particles
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
{
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
AddParticle( tempDelta, pBox->bbmin, pBox->bbmax, *hitboxbones[pBox->bone] );
}
return;
trailNoHitboxes:
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
{
AddParticle( tempDelta, pMoveParent->CollisionProp()->OBBMins(), pMoveParent->CollisionProp()->OBBMaxs(), pMoveParent->EntityToWorldTransform() );
}
}
inline void C_EntityParticleTrail::RenderParticles( CParticleRenderIterator *pIterator )
{
const SimpleParticle *pParticle = (const SimpleParticle*)pIterator->GetFirst();
while ( pParticle )
{
float t = pParticle->m_flLifetime / pParticle->m_flDieTime;
// Render
Vector tPos;
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos );
float sortKey = tPos.z;
Vector color = Vector( pParticle->m_uchColor[0] / 255.0f, pParticle->m_uchColor[1] / 255.0f, pParticle->m_uchColor[2] / 255.0f );
float alpha = Lerp( t, pParticle->m_uchStartAlpha / 255.0f, pParticle->m_uchEndAlpha / 255.0f );
float flSize = Lerp( t, pParticle->m_uchStartSize, pParticle->m_uchEndSize );
// Render it
RenderParticle_ColorSize( pIterator->GetParticleDraw(), tPos, color, alpha, flSize );
pParticle = (const SimpleParticle*)pIterator->GetNext( sortKey );
}
}
inline void C_EntityParticleTrail::SimulateParticles( CParticleSimulateIterator *pIterator )
{
SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
while ( pParticle )
{
// Update position
float flTimeDelta = pIterator->GetTimeDelta();
pParticle->m_Pos += pParticle->m_vecVelocity * flTimeDelta;
// NOTE: I'm overloading "die time" to be the actual start time.
pParticle->m_flLifetime += flTimeDelta;
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
pIterator->RemoveParticle( pParticle );
pParticle = (SimpleParticle*)pIterator->GetNext();
}
}

View File

@ -0,0 +1,46 @@
//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====
//
// An entity that allows level designer control over the fog parameters.
//
//=============================================================================
#include "cbase.h"
#include "c_env_fog_controller.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
IMPLEMENT_NETWORKCLASS_ALIASED( FogController, DT_FogController )
//-----------------------------------------------------------------------------
// Datatable
//-----------------------------------------------------------------------------
BEGIN_NETWORK_TABLE_NOBASE( CFogController, DT_FogController )
// fog data
RecvPropInt( RECVINFO( m_fog.enable ) ),
RecvPropInt( RECVINFO( m_fog.blend ) ),
RecvPropVector( RECVINFO( m_fog.dirPrimary ) ),
RecvPropInt( RECVINFO( m_fog.colorPrimary ) ),
RecvPropInt( RECVINFO( m_fog.colorSecondary ) ),
RecvPropFloat( RECVINFO( m_fog.start ) ),
RecvPropFloat( RECVINFO( m_fog.end ) ),
RecvPropFloat( RECVINFO( m_fog.farz ) ),
RecvPropFloat( RECVINFO( m_fog.maxdensity ) ),
RecvPropInt( RECVINFO( m_fog.colorPrimaryLerpTo ) ),
RecvPropInt( RECVINFO( m_fog.colorSecondaryLerpTo ) ),
RecvPropFloat( RECVINFO( m_fog.startLerpTo ) ),
RecvPropFloat( RECVINFO( m_fog.endLerpTo ) ),
RecvPropFloat( RECVINFO( m_fog.lerptime ) ),
RecvPropFloat( RECVINFO( m_fog.duration ) ),
END_NETWORK_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_FogController::C_FogController()
{
// Make sure that old maps without fog fields don't get wacked out fog values.
m_fog.enable = false;
m_fog.maxdensity = 1.0f;
}

View File

@ -0,0 +1,33 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_ENV_FOG_CONTROLLER_H
#define C_ENV_FOG_CONTROLLER_H
#define CFogController C_FogController
//=============================================================================
//
// Class Fog Controller:
// Compares a set of integer inputs to the one main input
// Outputs true if they are all equivalant, false otherwise
//
class C_FogController : public C_BaseEntity
{
public:
DECLARE_NETWORKCLASS();
DECLARE_CLASS( C_FogController, C_BaseEntity );
C_FogController();
public:
fogparams_t m_fog;
};
#endif // C_ENV_FOG_CONTROLLER_H

View File

@ -0,0 +1,304 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "c_baseanimating.h"
#include "particlemgr.h"
#include "materialsystem/imaterialvar.h"
#include "cl_animevent.h"
#include "particle_util.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// An entity which emits other entities at points
//-----------------------------------------------------------------------------
class C_EnvParticleScript : public C_BaseAnimating, public IParticleEffect
{
public:
DECLARE_CLASS( C_EnvParticleScript, C_BaseAnimating );
DECLARE_CLIENTCLASS();
C_EnvParticleScript();
// IParticleEffect overrides.
public:
virtual bool ShouldSimulate() const { return m_bSimulate; }
virtual void SetShouldSimulate( bool bSim ) { m_bSimulate = bSim; }
virtual void RenderParticles( CParticleRenderIterator *pIterator );
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
virtual const Vector &GetSortOrigin();
// C_BaseAnimating overrides
public:
// NOTE: Ths enclosed particle effect binding will do all the drawing
// But we have to return true, unlike other particle systems, for the animation events to work
virtual bool ShouldDraw() { return true; }
virtual int DrawModel( int flags ) { return 0; }
virtual int GetFxBlend( void ) { return 0; }
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
virtual void OnPreDataChanged( DataUpdateType_t updateType );
virtual void OnDataChanged( DataUpdateType_t updateType );
private:
// Creates, destroys particles attached to an attachment
void CreateParticle( const char *pAttachmentName, const char *pSpriteName );
void DestroyAllParticles( const char *pAttachmentName );
void DestroyAllParticles( );
private:
struct ParticleScriptParticle_t : public Particle
{
int m_nAttachment;
float m_flSize;
};
CParticleEffectBinding m_ParticleEffect;
float m_flMaxParticleSize;
int m_nOldSequence;
float m_flSequenceScale;
bool m_bSimulate;
};
REGISTER_EFFECT( C_EnvParticleScript );
//-----------------------------------------------------------------------------
// Datatable
//-----------------------------------------------------------------------------
IMPLEMENT_CLIENTCLASS_DT( C_EnvParticleScript, DT_EnvParticleScript, CEnvParticleScript )
RecvPropFloat( RECVINFO(m_flSequenceScale) ),
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
C_EnvParticleScript::C_EnvParticleScript()
{
m_flMaxParticleSize = 0.0f;
m_bSimulate = true;
}
//-----------------------------------------------------------------------------
// Check for changed sequence numbers
//-----------------------------------------------------------------------------
void C_EnvParticleScript::OnPreDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnPreDataChanged( updateType );
m_nOldSequence = GetSequence();
}
//-----------------------------------------------------------------------------
// Starts up the particle system
//-----------------------------------------------------------------------------
void C_EnvParticleScript::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged( updateType );
if(updateType == DATA_UPDATE_CREATED)
{
ParticleMgr()->AddEffect( &m_ParticleEffect, this );
}
if ( m_nOldSequence != GetSequence() )
{
DestroyAllParticles();
}
}
//-----------------------------------------------------------------------------
// Creates, destroys particles attached to an attachment
//-----------------------------------------------------------------------------
void C_EnvParticleScript::CreateParticle( const char *pAttachmentName, const char *pSpriteName )
{
// Find the attachment
int nAttachment = LookupAttachment( pAttachmentName );
if ( nAttachment <= 0 )
return;
// Get the sprite materials
PMaterialHandle hMat = m_ParticleEffect.FindOrAddMaterial( pSpriteName );
ParticleScriptParticle_t *pParticle =
(ParticleScriptParticle_t*)m_ParticleEffect.AddParticle(sizeof(ParticleScriptParticle_t), hMat);
if ( pParticle == NULL )
return;
// Get the sprite size from the material's materialvars
bool bFound = false;
IMaterialVar *pMaterialVar = NULL;
IMaterial *pMaterial = ParticleMgr()->PMaterialToIMaterial( hMat );
if ( pMaterial )
{
pMaterialVar = pMaterial->FindVar( "$spritesize", &bFound, false );
}
if ( bFound )
{
pParticle->m_flSize = pMaterialVar->GetFloatValue();
}
else
{
pParticle->m_flSize = 100.0f;
}
// Make sure the particle cull size reflects our particles
if ( pParticle->m_flSize > m_flMaxParticleSize )
{
m_flMaxParticleSize = pParticle->m_flSize;
m_ParticleEffect.SetParticleCullRadius( m_flMaxParticleSize );
}
// Place the particle on the attachment specified
pParticle->m_nAttachment = nAttachment;
QAngle vecAngles;
GetAttachment( nAttachment, pParticle->m_Pos, vecAngles );
if ( m_flSequenceScale != 1.0f )
{
pParticle->m_Pos -= GetAbsOrigin();
pParticle->m_Pos *= m_flSequenceScale;
pParticle->m_Pos += GetAbsOrigin();
}
}
void C_EnvParticleScript::DestroyAllParticles( const char *pAttachmentName )
{
int nAttachment = LookupAttachment( pAttachmentName );
if ( nAttachment <= 0 )
return;
int nCount = m_ParticleEffect.GetNumActiveParticles();
Particle** ppParticles = (Particle**)stackalloc( nCount * sizeof(Particle*) );
int nActualCount = m_ParticleEffect.GetActiveParticleList( nCount, ppParticles );
Assert( nActualCount == nCount );
for ( int i = 0; i < nActualCount; ++i )
{
ParticleScriptParticle_t *pParticle = (ParticleScriptParticle_t*)ppParticles[i];
if ( pParticle->m_nAttachment == nAttachment )
{
// Mark for deletion
pParticle->m_nAttachment = -1;
}
}
}
void C_EnvParticleScript::DestroyAllParticles( )
{
int nCount = m_ParticleEffect.GetNumActiveParticles();
Particle** ppParticles = (Particle**)stackalloc( nCount * sizeof(Particle*) );
int nActualCount = m_ParticleEffect.GetActiveParticleList( nCount, ppParticles );
Assert( nActualCount == nCount );
for ( int i = 0; i < nActualCount; ++i )
{
ParticleScriptParticle_t *pParticle = (ParticleScriptParticle_t*)ppParticles[i];
// Mark for deletion
pParticle->m_nAttachment = -1;
}
}
//-----------------------------------------------------------------------------
// The animation events will create particles on the attachment points
//-----------------------------------------------------------------------------
void C_EnvParticleScript::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
{
// Handle events to create + destroy particles
switch( event )
{
case CL_EVENT_SPRITEGROUP_CREATE:
{
char pAttachmentName[256];
char pSpriteName[256];
int nArgs = sscanf( options, "%255s %255s", pAttachmentName, pSpriteName );
if ( nArgs == 2 )
{
CreateParticle( pAttachmentName, pSpriteName );
}
}
return;
case CL_EVENT_SPRITEGROUP_DESTROY:
{
char pAttachmentName[256];
int nArgs = sscanf( options, "%255s", pAttachmentName );
if ( nArgs == 1 )
{
DestroyAllParticles( pAttachmentName );
}
}
return;
}
// Fall back
BaseClass::FireEvent( origin, angles, event, options );
}
//-----------------------------------------------------------------------------
// Simulate the particles
//-----------------------------------------------------------------------------
void C_EnvParticleScript::RenderParticles( CParticleRenderIterator *pIterator )
{
const ParticleScriptParticle_t* pParticle = (const ParticleScriptParticle_t*)pIterator->GetFirst();
while ( pParticle )
{
Vector vecRenderPos;
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, vecRenderPos );
float sortKey = vecRenderPos.z;
Vector color( 1, 1, 1 );
RenderParticle_ColorSize( pIterator->GetParticleDraw(), vecRenderPos, color, 1.0f, pParticle->m_flSize );
pParticle = (const ParticleScriptParticle_t*)pIterator->GetNext( sortKey );
}
}
void C_EnvParticleScript::SimulateParticles( CParticleSimulateIterator *pIterator )
{
ParticleScriptParticle_t* pParticle = (ParticleScriptParticle_t*)pIterator->GetFirst();
while ( pParticle )
{
// Here's how we retire particles
if ( pParticle->m_nAttachment == -1 )
{
pIterator->RemoveParticle( pParticle );
}
else
{
// Move the particle to the attachment point
QAngle vecAngles;
GetAttachment( pParticle->m_nAttachment, pParticle->m_Pos, vecAngles );
if ( m_flSequenceScale != 1.0f )
{
pParticle->m_Pos -= GetAbsOrigin();
pParticle->m_Pos *= m_flSequenceScale;
pParticle->m_Pos += GetAbsOrigin();
}
}
pParticle = (ParticleScriptParticle_t*)pIterator->GetNext();
}
}
const Vector &C_EnvParticleScript::GetSortOrigin()
{
return GetAbsOrigin();
}

View File

@ -0,0 +1,236 @@
//====== Copyright © 1996-2003, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "cbase.h"
#include "shareddefs.h"
#include "materialsystem/imesh.h"
#include "materialsystem/imaterial.h"
#include "view.h"
#include "iviewrender.h"
#include "view_shared.h"
#include "texture_group_names.h"
#include "tier0/icommandline.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT );
static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.0005", FCVAR_CHEAT );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class C_EnvProjectedTexture : public C_BaseEntity
{
DECLARE_CLASS( C_EnvProjectedTexture, C_BaseEntity );
public:
DECLARE_CLIENTCLASS();
virtual void OnDataChanged( DataUpdateType_t updateType );
void ShutDownLightHandle( void );
virtual void Simulate();
void UpdateLight( bool bForceUpdate );
C_EnvProjectedTexture();
~C_EnvProjectedTexture();
private:
ClientShadowHandle_t m_LightHandle;
EHANDLE m_hTargetEntity;
bool m_bState;
float m_flLightFOV;
bool m_bEnableShadows;
bool m_bLightOnlyTarget;
bool m_bLightWorld;
bool m_bCameraSpace;
Vector m_LinearFloatLightColor;
float m_flAmbient;
float m_flNearZ;
float m_flFarZ;
char m_SpotlightTextureName[ MAX_PATH ];
int m_nSpotlightTextureFrame;
int m_nShadowQuality;
};
IMPLEMENT_CLIENTCLASS_DT( C_EnvProjectedTexture, DT_EnvProjectedTexture, CEnvProjectedTexture )
RecvPropEHandle( RECVINFO( m_hTargetEntity ) ),
RecvPropBool( RECVINFO( m_bState ) ),
RecvPropFloat( RECVINFO( m_flLightFOV ) ),
RecvPropBool( RECVINFO( m_bEnableShadows ) ),
RecvPropBool( RECVINFO( m_bLightOnlyTarget ) ),
RecvPropBool( RECVINFO( m_bLightWorld ) ),
RecvPropBool( RECVINFO( m_bCameraSpace ) ),
RecvPropVector( RECVINFO( m_LinearFloatLightColor ) ),
RecvPropFloat( RECVINFO( m_flAmbient ) ),
RecvPropString( RECVINFO( m_SpotlightTextureName ) ),
RecvPropInt( RECVINFO( m_nSpotlightTextureFrame ) ),
RecvPropFloat( RECVINFO( m_flNearZ ) ),
RecvPropFloat( RECVINFO( m_flFarZ ) ),
RecvPropInt( RECVINFO( m_nShadowQuality ) ),
END_RECV_TABLE()
C_EnvProjectedTexture::C_EnvProjectedTexture( void )
{
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
C_EnvProjectedTexture::~C_EnvProjectedTexture( void )
{
ShutDownLightHandle();
}
void C_EnvProjectedTexture::ShutDownLightHandle( void )
{
// Clear out the light
if( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE )
{
g_pClientShadowMgr->DestroyFlashlight( m_LightHandle );
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : updateType -
//-----------------------------------------------------------------------------
void C_EnvProjectedTexture::OnDataChanged( DataUpdateType_t updateType )
{
UpdateLight( true );
BaseClass::OnDataChanged( updateType );
}
void C_EnvProjectedTexture::UpdateLight( bool bForceUpdate )
{
if ( m_bState == false )
{
if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE )
{
ShutDownLightHandle();
}
return;
}
Vector vForward, vRight, vUp, vPos = GetAbsOrigin();
FlashlightState_t state;
if ( m_hTargetEntity != NULL )
{
if ( m_bCameraSpace )
{
const QAngle &angles = GetLocalAngles();
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if( pPlayer )
{
const QAngle playerAngles = pPlayer->GetAbsAngles();
Vector vPlayerForward, vPlayerRight, vPlayerUp;
AngleVectors( playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp );
matrix3x4_t mRotMatrix;
AngleMatrix( angles, mRotMatrix );
VectorITransform( vPlayerForward, mRotMatrix, vForward );
VectorITransform( vPlayerRight, mRotMatrix, vRight );
VectorITransform( vPlayerUp, mRotMatrix, vUp );
float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length();
vPos = m_hTargetEntity->GetAbsOrigin() - vForward*dist;
VectorNormalize( vForward );
VectorNormalize( vRight );
VectorNormalize( vUp );
}
}
else
{
vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin();
VectorNormalize( vForward );
// JasonM - unimplemented
Assert (0);
//Quaternion q = DirectionToOrientation( dir );
//
// JasonM - set up vRight, vUp
//
// VectorNormalize( vRight );
// VectorNormalize( vUp );
}
}
else
{
AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );
}
state.m_fHorizontalFOVDegrees = m_flLightFOV;
state.m_fVerticalFOVDegrees = m_flLightFOV;
state.m_vecLightOrigin = vPos;
BasisToQuaternion( vForward, vRight, vUp, state.m_quatOrientation );
state.m_fQuadraticAtten = 0.0;
state.m_fLinearAtten = 100;
state.m_fConstantAtten = 0.0f;
state.m_Color[0] = m_LinearFloatLightColor.x;
state.m_Color[1] = m_LinearFloatLightColor.y;
state.m_Color[2] = m_LinearFloatLightColor.z;
state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient;
state.m_NearZ = m_flNearZ;
state.m_FarZ = m_flFarZ;
state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat();
state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat();
state.m_bEnableShadows = m_bEnableShadows;
state.m_pSpotlightTexture = materials->FindTexture( m_SpotlightTextureName, TEXTURE_GROUP_OTHER, false );
state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame;
state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality
if( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE )
{
m_LightHandle = g_pClientShadowMgr->CreateFlashlight( state );
}
else
{
if ( m_hTargetEntity != NULL || bForceUpdate == true )
{
g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state );
}
}
if( m_bLightOnlyTarget )
{
g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, m_hTargetEntity );
}
else
{
g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, NULL );
}
g_pClientShadowMgr->SetFlashlightLightWorld( m_LightHandle, m_bLightWorld );
if ( bForceUpdate == false )
{
g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true );
}
}
void C_EnvProjectedTexture::Simulate( void )
{
UpdateLight( false );
BaseClass::Simulate();
}

View File

@ -0,0 +1,327 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "shareddefs.h"
#include "materialsystem/imesh.h"
#include "materialsystem/imaterial.h"
#include "view.h"
#include "iviewrender.h"
#include "view_shared.h"
#include "texture_group_names.h"
#include "tier0/icommandline.h"
#include "keyvalues.h"
#include "ScreenSpaceEffects.h"
#include "materialsystem/imaterialsystemhardwareconfig.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class C_EnvScreenOverlay : public C_BaseEntity
{
DECLARE_CLASS( C_EnvScreenOverlay, C_BaseEntity );
public:
DECLARE_CLIENTCLASS();
void PreDataUpdate( DataUpdateType_t updateType );
void PostDataUpdate( DataUpdateType_t updateType );
void HandleOverlaySwitch( void );
void StartOverlays( void );
void StopOverlays( void );
void StartCurrentOverlay( void );
void ClientThink( void );
protected:
char m_iszOverlayNames[ MAX_SCREEN_OVERLAYS ][255];
float m_flOverlayTimes[ MAX_SCREEN_OVERLAYS ];
float m_flStartTime;
int m_iDesiredOverlay;
bool m_bIsActive;
bool m_bWasActive;
int m_iCachedDesiredOverlay;
int m_iCurrentOverlay;
float m_flCurrentOverlayTime;
};
IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenOverlay, DT_EnvScreenOverlay, CEnvScreenOverlay )
RecvPropArray( RecvPropString( RECVINFO( m_iszOverlayNames[0]) ), m_iszOverlayNames ),
RecvPropArray( RecvPropFloat( RECVINFO( m_flOverlayTimes[0] ) ), m_flOverlayTimes ),
RecvPropFloat( RECVINFO( m_flStartTime ) ),
RecvPropInt( RECVINFO( m_iDesiredOverlay ) ),
RecvPropBool( RECVINFO( m_bIsActive ) ),
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
// Input : updateType -
//-----------------------------------------------------------------------------
void C_EnvScreenOverlay::PreDataUpdate( DataUpdateType_t updateType )
{
BaseClass::PreDataUpdate( updateType );
m_bWasActive = m_bIsActive;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EnvScreenOverlay::PostDataUpdate( DataUpdateType_t updateType )
{
BaseClass::PostDataUpdate( updateType );
// If we have a start time now, start the overlays going
if ( m_bIsActive && m_flStartTime > 0 && view->GetScreenOverlayMaterial() == NULL )
{
StartOverlays();
}
if ( m_flStartTime == -1 )
{
StopOverlays();
}
HandleOverlaySwitch();
if ( updateType == DATA_UPDATE_CREATED &&
CommandLine()->FindParm( "-makereslists" ) )
{
for ( int i = 0; i < MAX_SCREEN_OVERLAYS; ++i )
{
if ( m_iszOverlayNames[ i ] && m_iszOverlayNames[ i ][ 0 ] )
{
materials->FindMaterial( m_iszOverlayNames[ i ], TEXTURE_GROUP_CLIENT_EFFECTS, false );
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EnvScreenOverlay::StopOverlays( void )
{
SetNextClientThink( CLIENT_THINK_NEVER );
if ( m_bWasActive && !m_bIsActive )
{
view->SetScreenOverlayMaterial( NULL );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EnvScreenOverlay::StartOverlays( void )
{
m_iCurrentOverlay = 0;
m_flCurrentOverlayTime = 0;
m_iCachedDesiredOverlay = 0;
SetNextClientThink( CLIENT_THINK_ALWAYS );
StartCurrentOverlay();
HandleOverlaySwitch();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EnvScreenOverlay::HandleOverlaySwitch( void )
{
if( m_iCachedDesiredOverlay != m_iDesiredOverlay )
{
m_iCurrentOverlay = m_iDesiredOverlay;
m_iCachedDesiredOverlay = m_iDesiredOverlay;
StartCurrentOverlay();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EnvScreenOverlay::StartCurrentOverlay( void )
{
if ( m_iCurrentOverlay == MAX_SCREEN_OVERLAYS || !m_iszOverlayNames[m_iCurrentOverlay] || !m_iszOverlayNames[m_iCurrentOverlay][0] )
{
// Hit the end of our overlays, so stop.
m_flStartTime = 0;
StopOverlays();
return;
}
if ( m_flOverlayTimes[m_iCurrentOverlay] == -1 )
m_flCurrentOverlayTime = -1;
else
m_flCurrentOverlayTime = gpGlobals->curtime + m_flOverlayTimes[m_iCurrentOverlay];
// Bring up the current overlay
IMaterial *pMaterial = materials->FindMaterial( m_iszOverlayNames[m_iCurrentOverlay], TEXTURE_GROUP_CLIENT_EFFECTS, false );
if ( !IsErrorMaterial( pMaterial ) )
{
view->SetScreenOverlayMaterial( pMaterial );
}
else
{
Warning("env_screenoverlay couldn't find overlay %s.\n", m_iszOverlayNames[m_iCurrentOverlay] );
StopOverlays();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EnvScreenOverlay::ClientThink( void )
{
// If the current overlay's run out, go to the next one
if ( m_flCurrentOverlayTime != -1 && m_flCurrentOverlayTime < gpGlobals->curtime )
{
m_iCurrentOverlay++;
StartCurrentOverlay();
}
}
// Effect types
enum
{
SCREENEFFECT_EP2_ADVISOR_STUN,
SCREENEFFECT_EP1_INTRO,
SCREENEFFECT_EP2_GROGGY,
};
// ============================================================================
// Screenspace effect
// ============================================================================
class C_EnvScreenEffect : public C_BaseEntity
{
DECLARE_CLASS( C_EnvScreenEffect, C_BaseEntity );
public:
DECLARE_CLIENTCLASS();
virtual void ReceiveMessage( int classID, bf_read &msg );
private:
float m_flDuration;
int m_nType;
};
IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenEffect, DT_EnvScreenEffect, CEnvScreenEffect )
RecvPropFloat( RECVINFO( m_flDuration ) ),
RecvPropInt( RECVINFO( m_nType ) ),
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
// Input : classID -
// &msg -
//-----------------------------------------------------------------------------
void C_EnvScreenEffect::ReceiveMessage( int classID, bf_read &msg )
{
// Make sure our IDs match
if ( classID != GetClientClass()->m_ClassID )
{
// Message is for subclass
BaseClass::ReceiveMessage( classID, msg );
return;
}
int messageType = msg.ReadByte();
switch( messageType )
{
// Effect turning on
case 0: // FIXME: Declare
{
// Create a keyvalue block to set these params
KeyValues *pKeys = new KeyValues( "keys" );
if ( pKeys == NULL )
return;
if ( m_nType == SCREENEFFECT_EP1_INTRO )
{
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
{
return;
}
// Set our keys
pKeys->SetFloat( "duration", m_flDuration );
pKeys->SetInt( "fadeout", 0 );
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_intro", pKeys );
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "episodic_intro" );
}
else if ( m_nType == SCREENEFFECT_EP2_ADVISOR_STUN )
{
// Set our keys
pKeys->SetFloat( "duration", m_flDuration );
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_stun", pKeys );
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "episodic_stun" );
}
else if ( m_nType == SCREENEFFECT_EP2_GROGGY )
{
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
return;
// Set our keys
pKeys->SetFloat( "duration", m_flDuration );
pKeys->SetInt( "fadeout", 0 );
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys );
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "ep2_groggy" );
}
pKeys->deleteThis();
}
break;
// Effect turning off
case 1: // FIXME: Declare
if ( m_nType == SCREENEFFECT_EP1_INTRO )
{
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
{
return;
}
// Create a keyvalue block to set these params
KeyValues *pKeys = new KeyValues( "keys" );
if ( pKeys == NULL )
return;
// Set our keys
pKeys->SetFloat( "duration", m_flDuration );
pKeys->SetInt( "fadeout", 1 );
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_intro", pKeys );
}
else if ( m_nType == SCREENEFFECT_EP2_ADVISOR_STUN )
{
g_pScreenSpaceEffects->DisableScreenSpaceEffect( "episodic_stun" );
}
else if ( m_nType == SCREENEFFECT_EP2_GROGGY )
{
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
{
return;
}
// Create a keyvalue block to set these params
KeyValues *pKeys = new KeyValues( "keys" );
if ( pKeys == NULL )
return;
// Set our keys
pKeys->SetFloat( "duration", m_flDuration );
pKeys->SetInt( "fadeout", 1 );
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys );
}
break;
}
}

View File

@ -0,0 +1,97 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "cbase.h"
extern bool g_bUseCustomAutoExposureMin;
extern bool g_bUseCustomAutoExposureMax;
extern bool g_bUseCustomBloomScale;
extern float g_flCustomAutoExposureMin;
extern float g_flCustomAutoExposureMax;
extern float g_flCustomBloomScale;
extern float g_flCustomBloomScaleMinimum;
EHANDLE g_hTonemapControllerInUse = NULL;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class C_EnvTonemapController : public C_BaseEntity
{
DECLARE_CLASS( C_EnvTonemapController, C_BaseEntity );
public:
DECLARE_CLIENTCLASS();
C_EnvTonemapController();
~C_EnvTonemapController();
virtual void OnDataChanged( DataUpdateType_t updateType );
private:
bool m_bUseCustomAutoExposureMin;
bool m_bUseCustomAutoExposureMax;
bool m_bUseCustomBloomScale;
float m_flCustomAutoExposureMin;
float m_flCustomAutoExposureMax;
float m_flCustomBloomScale;
float m_flCustomBloomScaleMinimum;
private:
C_EnvTonemapController( const C_EnvTonemapController & );
};
IMPLEMENT_CLIENTCLASS_DT( C_EnvTonemapController, DT_EnvTonemapController, CEnvTonemapController )
RecvPropInt( RECVINFO(m_bUseCustomAutoExposureMin) ),
RecvPropInt( RECVINFO(m_bUseCustomAutoExposureMax) ),
RecvPropInt( RECVINFO(m_bUseCustomBloomScale) ),
RecvPropFloat( RECVINFO(m_flCustomAutoExposureMin) ),
RecvPropFloat( RECVINFO(m_flCustomAutoExposureMax) ),
RecvPropFloat( RECVINFO(m_flCustomBloomScale) ),
RecvPropFloat( RECVINFO(m_flCustomBloomScaleMinimum) ),
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_EnvTonemapController::C_EnvTonemapController( void )
{
m_bUseCustomAutoExposureMin = false;
m_bUseCustomAutoExposureMax = false;
m_bUseCustomBloomScale = false;
m_flCustomAutoExposureMin = 0;
m_flCustomAutoExposureMax = 0;
m_flCustomBloomScale = 0.0f;
m_flCustomBloomScaleMinimum = 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_EnvTonemapController::~C_EnvTonemapController( void )
{
if ( g_hTonemapControllerInUse == this )
{
g_bUseCustomAutoExposureMin = false;
g_bUseCustomAutoExposureMax = false;
g_bUseCustomBloomScale = false;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EnvTonemapController::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged(updateType);
g_bUseCustomAutoExposureMin = m_bUseCustomAutoExposureMin;
g_bUseCustomAutoExposureMax = m_bUseCustomAutoExposureMax;
g_bUseCustomBloomScale = m_bUseCustomBloomScale;
g_flCustomAutoExposureMin = m_flCustomAutoExposureMin;
g_flCustomAutoExposureMax = m_flCustomAutoExposureMax;
g_flCustomBloomScale = m_flCustomBloomScale;
g_flCustomBloomScaleMinimum = m_flCustomBloomScaleMinimum;
g_hTonemapControllerInUse = this;
}

View File

@ -0,0 +1,404 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "IViewRender.h"
#include "ClientEffectPrecacheSystem.h"
#include "studio.h"
#include "bone_setup.h"
#include "engine/ivmodelinfo.h"
#include "c_fire_smoke.h"
#include "engine/IEngineSound.h"
#include "iefx.h"
#include "dlight.h"
#include "tier0/ICommandLine.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
CLIENTEFFECT_REGISTER_BEGIN( SmokeStackMaterials )
CLIENTEFFECT_MATERIAL( "particle/SmokeStack" )
CLIENTEFFECT_REGISTER_END()
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pRecvProp -
// *pStruct -
// *pVarData -
// *pIn -
// objectID -
//-----------------------------------------------------------------------------
void RecvProxy_Scale( const CRecvProxyData *pData, void *pStruct, void *pOut )
{
C_FireSmoke *pFireSmoke = (C_FireSmoke *) pStruct;
float scale = pData->m_Value.m_Float;
//If changed, update our internal information
if ( ( pFireSmoke->m_flScale != scale ) && ( pFireSmoke->m_flScaleEnd != scale ) )
{
pFireSmoke->m_flScaleStart = pFireSmoke->m_flScaleRegister;
pFireSmoke->m_flScaleEnd = scale;
}
pFireSmoke->m_flScale = scale;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pRecvProp -
// *pStruct -
// *pVarData -
// *pIn -
// objectID -
//-----------------------------------------------------------------------------
void RecvProxy_ScaleTime( const CRecvProxyData *pData, void *pStruct, void *pOut )
{
C_FireSmoke *pFireSmoke = (C_FireSmoke *) pStruct;
float time = pData->m_Value.m_Float;
//If changed, update our internal information
//if ( pFireSmoke->m_flScaleTime != time )
{
if ( time == -1.0f )
{
pFireSmoke->m_flScaleTimeStart = Helper_GetTime()-1.0f;
pFireSmoke->m_flScaleTimeEnd = pFireSmoke->m_flScaleTimeStart;
}
else
{
pFireSmoke->m_flScaleTimeStart = Helper_GetTime();
pFireSmoke->m_flScaleTimeEnd = Helper_GetTime() + time;
}
}
pFireSmoke->m_flScaleTime = time;
}
//Receive datatable
IMPLEMENT_CLIENTCLASS_DT( C_FireSmoke, DT_FireSmoke, CFireSmoke )
RecvPropFloat( RECVINFO( m_flStartScale )),
RecvPropFloat( RECVINFO( m_flScale ), 0, RecvProxy_Scale ),
RecvPropFloat( RECVINFO( m_flScaleTime ), 0, RecvProxy_ScaleTime ),
RecvPropInt( RECVINFO( m_nFlags ) ),
RecvPropInt( RECVINFO( m_nFlameModelIndex ) ),
RecvPropInt( RECVINFO( m_nFlameFromAboveModelIndex ) ),
END_RECV_TABLE()
//==================================================
// C_FireSmoke
//==================================================
C_FireSmoke::C_FireSmoke()
{
}
C_FireSmoke::~C_FireSmoke()
{
// Shut down our effect if we have it
if ( m_hEffect )
{
m_hEffect->StopEmission(false, false , true);
m_hEffect = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::Simulate( void )
{
}
#define FLAME_ALPHA_START 0.9f
#define FLAME_ALPHA_END 1.0f
#define FLAME_TRANS_START 0.75f
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::AddFlames( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : bnewentity -
//-----------------------------------------------------------------------------
void C_FireSmoke::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged( updateType );
if ( updateType == DATA_UPDATE_CREATED )
{
Start();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::UpdateEffects( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool C_FireSmoke::ShouldDraw()
{
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::Start( void )
{
const char *lpszEffectName;
int nSize = (int) floor( m_flStartScale / 36.0f );
switch ( nSize )
{
case 0:
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_tiny_smoke" : "env_fire_tiny";
break;
case 1:
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_small_smoke" : "env_fire_small";
break;
case 2:
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_medium_smoke" : "env_fire_medium";
break;
case 3:
default:
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_large_smoke" : "env_fire_large";
break;
}
// Create the effect of the correct size
m_hEffect = ParticleProp()->Create( lpszEffectName, PATTACH_ABSORIGIN );
}
//-----------------------------------------------------------------------------
// Purpose: FIXME: what's the right way to do this?
//-----------------------------------------------------------------------------
void C_FireSmoke::StartClientOnly( void )
{
Start();
ClientEntityList().AddNonNetworkableEntity( this );
CollisionProp()->CreatePartitionHandle();
AddEffects( EF_NORECEIVESHADOW | EF_NOSHADOW );
AddToLeafSystem();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::RemoveClientOnly(void)
{
ClientThinkList()->RemoveThinkable( GetClientHandle() );
// Remove from the client entity list.
ClientEntityList().RemoveEntity( GetClientHandle() );
partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() );
RemoveFromLeafSystem();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::UpdateAnimation( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::UpdateFlames( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::UpdateScale( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::Update( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_FireSmoke::FindClipPlane( void )
{
}
//-----------------------------------------------------------------------------
// Purpose: Spawn smoke (...duh)
//-----------------------------------------------------------------------------
void C_FireSmoke::SpawnSmoke( void )
{
}
IMPLEMENT_CLIENTCLASS_DT( C_EntityFlame, DT_EntityFlame, CEntityFlame )
RecvPropEHandle(RECVINFO(m_hEntAttached)),
END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_EntityFlame::C_EntityFlame( void ) :
m_hEffect( NULL )
{
m_hOldAttached = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_EntityFlame::~C_EntityFlame( void )
{
StopEffect();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityFlame::StopEffect( void )
{
if ( m_hEffect )
{
ParticleProp()->StopEmission( m_hEffect, true );
m_hEffect->SetControlPointEntity( 0, NULL );
m_hEffect->SetControlPointEntity( 1, NULL );
m_hEffect = NULL;
}
if ( m_hEntAttached )
{
m_hEntAttached->RemoveFlag( FL_ONFIRE );
m_hEntAttached->SetEffectEntity( NULL );
m_hEntAttached->StopSound( "General.BurningFlesh" );
m_hEntAttached->StopSound( "General.BurningObject" );
m_hEntAttached = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityFlame::UpdateOnRemove( void )
{
StopEffect();
BaseClass::UpdateOnRemove();
}
void C_EntityFlame::CreateEffect( void )
{
if ( m_hEffect )
{
ParticleProp()->StopEmission( m_hEffect, true );
m_hEffect->SetControlPointEntity( 0, NULL );
m_hEffect->SetControlPointEntity( 1, NULL );
m_hEffect = NULL;
}
m_hEffect = ParticleProp()->Create( "burning_character", PATTACH_ABSORIGIN_FOLLOW );
if ( m_hEffect )
{
C_BaseEntity *pEntity = m_hEntAttached;
m_hOldAttached = m_hEntAttached;
ParticleProp()->AddControlPoint( m_hEffect, 1, pEntity, PATTACH_ABSORIGIN_FOLLOW );
m_hEffect->SetControlPoint( 0, GetAbsOrigin() );
m_hEffect->SetControlPoint( 1, GetAbsOrigin() );
m_hEffect->SetControlPointEntity( 0, pEntity );
m_hEffect->SetControlPointEntity( 1, pEntity );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityFlame::OnDataChanged( DataUpdateType_t updateType )
{
if ( updateType == DATA_UPDATE_CREATED )
{
CreateEffect();
}
// FIXME: This is a bit of a shady path
if ( updateType == DATA_UPDATE_DATATABLE_CHANGED )
{
// If our owner changed, then recreate the effect
if ( m_hEntAttached != m_hOldAttached )
{
CreateEffect();
}
}
BaseClass::OnDataChanged( updateType );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityFlame::Simulate( void )
{
if ( gpGlobals->frametime <= 0.0f )
return;
#ifdef HL2_EPISODIC
if ( IsEffectActive(EF_BRIGHTLIGHT) || IsEffectActive(EF_DIMLIGHT) )
{
dlight_t *dl = effects->CL_AllocDlight ( index );
dl->origin = GetAbsOrigin();
dl->origin[2] += 16;
dl->color.r = 254;
dl->color.g = 174;
dl->color.b = 10;
dl->radius = random->RandomFloat(400,431);
dl->die = gpGlobals->curtime + 0.001;
}
#endif // HL2_EPISODIC
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_EntityFlame::ClientThink( void )
{
StopEffect();
Release();
}

302
game/client/c_fire_smoke.h Normal file
View File

@ -0,0 +1,302 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef C_FIRE_SMOKE_H
#define C_FIRE_SMOKE_H
#include "particles_simple.h"
#include "tempent.h"
#include "glow_overlay.h"
#include "view.h"
#include "particle_litsmokeemitter.h"
class CFireOverlay;
class C_FireSprite : public C_Sprite
{
DECLARE_CLASS( C_FireSprite, C_Sprite );
private:
virtual int DrawModel( int flags )
{
if ( m_bFadeFromAbove )
{
// The sprites become less visible the more you look down or up at them
Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
VectorNormalize( vToPos );
float fUpAmount = vToPos.z;
int iAlpha = 255;
if ( fUpAmount < -0.75f )
iAlpha = 0;
else if ( fUpAmount < -0.65f )
iAlpha = 255 - (int)( ( fUpAmount + 0.65f ) * 10.0f * -255.0f );
else if ( fUpAmount > 0.85f )
iAlpha = 0;
else if ( fUpAmount > 0.75f )
iAlpha = 255 - (int)( ( fUpAmount - 0.75f ) * 10.0f * 255.0f );
SetColor( iAlpha, iAlpha, iAlpha );
}
return BaseClass::DrawModel( flags );
}
public:
Vector m_vecMoveDir;
bool m_bFadeFromAbove;
};
class C_FireFromAboveSprite : public C_Sprite
{
DECLARE_CLASS( C_FireFromAboveSprite, C_Sprite );
virtual int DrawModel( int flags )
{
// The sprites become more visible the more you look down or up at them
Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
VectorNormalize( vToPos );
float fUpAmount = vToPos.z;
int iAlpha = 0;
if ( fUpAmount < -0.85f )
iAlpha = 255;
else if ( fUpAmount < -0.65f )
iAlpha = (int)( ( fUpAmount + 0.65f ) * 5.0f * -255.0f );
else if ( fUpAmount > 0.75f )
iAlpha = 255;
else if ( fUpAmount > 0.55f )
iAlpha = (int)( ( fUpAmount - 0.55f ) * 5.0f * 255.0f );
SetColor( iAlpha, iAlpha, iAlpha );
return BaseClass::DrawModel( flags );
}
};
#ifdef _XBOX
// XBox reduces the flame count
#define NUM_CHILD_FLAMES 1
#else
#define NUM_CHILD_FLAMES 4
#endif
#define SMOKE_RISE_RATE 92.0f
#define SMOKE_LIFETIME 2.0f
#define EMBER_LIFETIME 2.0f
#define FLAME_CHILD_SPREAD 64.0f
#define FLAME_SOURCE_HEIGHT 128.0f
#define FLAME_FROM_ABOVE_SOURCE_HEIGHT 32.0f
//==================================================
// C_FireSmoke
//==================================================
//NOTENOTE: Mirrored in dlls/fire_smoke.h
#define bitsFIRESMOKE_NONE 0x00000000
#define bitsFIRESMOKE_ACTIVE 0x00000001
#define bitsFIRESMOKE_SMOKE 0x00000002
#define bitsFIRESMOKE_SMOKE_COLLISION 0x00000004
#define bitsFIRESMOKE_GLOW 0x00000008
#define bitsFIRESMOKE_VISIBLE_FROM_ABOVE 0x00000010
#define OVERLAY_MAX_VISIBLE_RANGE 512.0f
class C_FireSmoke : public C_BaseEntity
{
public:
DECLARE_CLIENTCLASS();
DECLARE_CLASS( C_FireSmoke, C_BaseEntity );
C_FireSmoke();
~C_FireSmoke();
void Start( void );
void Simulate( void );
void StartClientOnly( void );
void RemoveClientOnly( void );
protected:
void Update( void );
void UpdateAnimation( void );
void UpdateScale( void );
void UpdateFlames( void );
void AddFlames( void );
void SpawnSmoke( void );
void FindClipPlane( void );
//C_BaseEntity
public:
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual bool ShouldDraw();
float GetScale( void ) const { return m_flScaleRegister; }
//From the server
public:
float m_flStartScale;
float m_flScale;
float m_flScaleTime;
int m_nFlags;
int m_nFlameModelIndex;
int m_nFlameFromAboveModelIndex;
//Client-side only
public:
float m_flScaleRegister;
float m_flScaleStart;
float m_flScaleEnd;
float m_flScaleTimeStart;
float m_flScaleTimeEnd;
float m_flChildFlameSpread;
VPlane m_planeClip;
float m_flClipPerc;
bool m_bClipTested;
bool m_bFadingOut;
protected:
void UpdateEffects( void );
//CSmartPtr<CEmberEffect> m_pEmberEmitter;
CSmartPtr<CLitSmokeEmitter> m_pSmokeEmitter;
C_FireSprite m_entFlames[NUM_CHILD_FLAMES];
C_FireFromAboveSprite m_entFlamesFromAbove[NUM_CHILD_FLAMES];
float m_entFlameScales[NUM_CHILD_FLAMES];
TimedEvent m_tParticleSpawn;
CFireOverlay *m_pFireOverlay;
// New Particle Fire Effect
CNewParticleEffect *m_hEffect;
private:
C_FireSmoke( const C_FireSmoke & );
};
//Fire overlay
class CFireOverlay : public CGlowOverlay
{
public:
//Constructor
CFireOverlay( C_FireSmoke *owner )
{
m_pOwner = owner;
m_flScale = 0.0f;
m_nGUID = random->RandomInt( -999999, 999999 );
}
//-----------------------------------------------------------------------------
// Purpose: Generate a flicker value
// Output : scalar value
//-----------------------------------------------------------------------------
float GetFlickerScale( void )
{
float result = 0.0f;
float time = Helper_GetTime() + m_nGUID;
result = sin( time * 1000.0f );
result += 0.5f * sin( time * 2000.0f );
result -= 0.5f * cos( time * 8000.0f );
return result;
}
//-----------------------------------------------------------------------------
// Purpose: Update the overlay
//-----------------------------------------------------------------------------
virtual bool Update( void )
{
if ( m_pOwner == NULL )
return false;
float scale = m_pOwner->GetScale();
float dscale = scale - m_flScale;
m_vPos[2] += dscale * FLAME_SOURCE_HEIGHT;
m_flScale = scale;
scale *= 0.75f;
float flickerScale = GetFlickerScale();
float newScale = scale + ( scale * flickerScale * 0.1f );
m_Sprites[0].m_flHorzSize = ( newScale * 0.2f ) + ( m_Sprites[0].m_flHorzSize * 0.8f );
m_Sprites[0].m_flVertSize = m_Sprites[0].m_flHorzSize * 1.5f;
float cameraDistance = ( CurrentViewOrigin() - (m_pOwner->GetAbsOrigin())).Length();
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
if ( local )
{
cameraDistance *= local->GetFOVDistanceAdjustFactor();
}
if ( cameraDistance > OVERLAY_MAX_VISIBLE_RANGE )
cameraDistance = OVERLAY_MAX_VISIBLE_RANGE;
float alpha = 1.0f - ( cameraDistance / OVERLAY_MAX_VISIBLE_RANGE );
Vector newColor = m_vBaseColors[0] + ( m_vBaseColors[0] * flickerScale * 0.5f );
m_Sprites[0].m_vColor = ( newColor * 0.1f ) + ( m_Sprites[0].m_vColor * 0.9f ) * alpha;
return true;
}
public:
C_FireSmoke *m_pOwner;
Vector m_vBaseColors[MAX_SUN_LAYERS];
float m_flScale;
int m_nGUID;
};
//
// Entity flame, client-side implementation
//
#define NUM_FLAMELETS 5
class C_EntityFlame : public C_BaseEntity
{
public:
DECLARE_CLIENTCLASS();
DECLARE_CLASS( C_EntityFlame, C_BaseEntity );
C_EntityFlame( void );
~C_EntityFlame( void );
virtual void Simulate( void );
virtual void UpdateOnRemove( void );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void ClientThink( void );
CNewParticleEffect *m_hEffect;
EHANDLE m_hEntAttached; // The entity that we are burning (attached to).
EHANDLE m_hOldAttached;
protected:
void CreateEffect( void );
void StopEffect( void );
};
#endif //C_FIRE_SMOKE_H

352
game/client/c_fish.cpp Normal file
View File

@ -0,0 +1,352 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// c_fish.cpp
// Simple fish client-side logic
// Author: Michael S. Booth, April 2005
#include "cbase.h"
#include <bitbuf.h>
#include "engine/IVDebugOverlay.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz );
ConVar FishDebug( "fish_debug", "0", FCVAR_CHEAT, "Show debug info for fish" );
//-----------------------------------------------------------------------------
/**
* Client-side fish entity
*/
class C_Fish : public C_BaseAnimating
{
public:
DECLARE_CLASS( C_Fish, C_BaseAnimating );
DECLARE_CLIENTCLASS();
virtual void Spawn( void );
virtual void ClientThink();
virtual void OnDataChanged( DataUpdateType_t type );
private:
friend void RecvProxy_FishOriginX( const CRecvProxyData *pData, void *pStruct, void *pOut );
friend void RecvProxy_FishOriginY( const CRecvProxyData *pData, void *pStruct, void *pOut );
Vector m_pos; ///< local position
Vector m_vel; ///< local velocity
QAngle m_angles; ///< local angles
int m_localLifeState; ///< our version of m_lifeState
float m_deathDepth; ///< water depth when we died
float m_deathAngle; ///< angle to float at when dead
float m_buoyancy; ///< so each fish floats at a different rate when dead
CountdownTimer m_wiggleTimer; ///< for simulating swimming motions
float m_wigglePhase; ///< where in the wiggle sinusoid we are
float m_wiggleRate; ///< the speed of our wiggling
Vector m_actualPos; ///< position from server
QAngle m_actualAngles; ///< angles from server
Vector m_poolOrigin;
float m_waterLevel; ///< Z coordinate of water surface
bool m_gotUpdate; ///< true after we have received a network update
enum { MAX_ERROR_HISTORY = 20 };
float m_errorHistory[ MAX_ERROR_HISTORY ]; ///< error history samples
int m_errorHistoryIndex;
int m_errorHistoryCount;
float m_averageError;
};
//-----------------------------------------------------------------------------
void RecvProxy_FishOriginX( const CRecvProxyData *pData, void *pStruct, void *pOut )
{
C_Fish *fish = (C_Fish *)pStruct;
float *out = (float *)pOut;
*out = pData->m_Value.m_Float + fish->m_poolOrigin.x;
}
void RecvProxy_FishOriginY( const CRecvProxyData *pData, void *pStruct, void *pOut )
{
C_Fish *fish = (C_Fish *)pStruct;
float *out = (float *)pOut;
*out = pData->m_Value.m_Float + fish->m_poolOrigin.y;
}
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_Fish, DT_CFish, CFish )
RecvPropVector( RECVINFO(m_poolOrigin) ),
RecvPropFloat( RECVINFO_NAME( m_actualPos.x, m_x ), 0, RecvProxy_FishOriginX ),
RecvPropFloat( RECVINFO_NAME( m_actualPos.y, m_y ), 0, RecvProxy_FishOriginY ),
RecvPropFloat( RECVINFO_NAME( m_actualPos.z, m_z ) ),
RecvPropFloat( RECVINFO_NAME( m_actualAngles.y, m_angle ) ),
RecvPropInt( RECVINFO(m_nModelIndex) ),
RecvPropInt( RECVINFO(m_lifeState) ),
RecvPropFloat( RECVINFO(m_waterLevel) ), ///< get this from the server in case we die when slightly out of the water due to error correction
END_RECV_TABLE()
//-----------------------------------------------------------------------------
void C_Fish::Spawn( void )
{
BaseClass::Spawn();
m_angles = QAngle( 0, 0, 0 );
m_actualAngles = m_angles;
m_vel = Vector( 0, 0, 0 );
m_gotUpdate = false;
m_localLifeState = LIFE_ALIVE;
m_buoyancy = RandomFloat( 0.4f, 1.0f );
m_errorHistoryIndex = 0;
m_errorHistoryCount = 0;
m_averageError = 0.0f;
SetNextClientThink( CLIENT_THINK_ALWAYS );
}
//-----------------------------------------------------------------------------
void C_Fish::ClientThink()
{
if (FishDebug.GetBool())
{
debugoverlay->AddLineOverlay( m_pos, m_actualPos, 255, 0, 0, true, 0.1f );
switch( m_localLifeState )
{
case LIFE_DYING:
debugoverlay->AddTextOverlay( m_pos, 0.1f, "DYING" );
break;
case LIFE_DEAD:
debugoverlay->AddTextOverlay( m_pos, 0.1f, "DEAD" );
break;
}
}
float deltaT = gpGlobals->frametime;
// check if we just died
if (m_localLifeState == LIFE_ALIVE && m_lifeState != LIFE_ALIVE)
{
// we have died
m_localLifeState = LIFE_DYING;
m_deathDepth = m_pos.z;
// determine surface float angle
m_deathAngle = RandomFloat( 87.0f, 93.0f ) * ((RandomInt( 0, 100 ) < 50) ? 1.0f : -1.0f);
}
switch( m_localLifeState )
{
case LIFE_DYING:
{
// depth parameter
float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
t *= t;
// roll onto side
m_angles.z = m_deathAngle * t;
// float to surface
const float fudge = 2.0f;
if (m_pos.z < m_waterLevel - fudge)
{
m_vel.z += (1.0f - t) * m_buoyancy * deltaT;
}
else
{
m_localLifeState = LIFE_DEAD;
}
break;
}
case LIFE_DEAD:
{
// depth parameter
float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
t *= t;
// roll onto side
m_angles.z = m_deathAngle * t;
// keep near water surface
const float sub = 0.5f;
m_vel.z += 10.0f * (m_waterLevel - m_pos.z - sub) * deltaT;
// bob on surface
const float rollAmp = 5.0f;
const float rollFreq = 2.33f;
m_angles.z += rollAmp * sin( rollFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
const float rollAmp2 = 7.0f;
const float rollFreq2 = 4.0f;
m_angles.x += rollAmp2 * sin( rollFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
const float bobAmp = 0.75f;
const float bobFreq = 4.0f;
m_vel.z += bobAmp * sin( bobFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
const float bobAmp2 = 0.75f;
const float bobFreq2 = 3.333f;
m_vel.z += bobAmp2 * sin( bobFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
// decay movement speed to zero
const float drag = 1.0f;
m_vel.z -= drag * m_vel.z * deltaT;
break;
}
case LIFE_ALIVE:
{
// use server-side Z coordinate directly
m_pos.z = m_actualPos.z;
// use server-side angles
m_angles = m_actualAngles;
// fishy wiggle based on movement
if (!m_wiggleTimer.IsElapsed())
{
float swimPower = 1.0f - (m_wiggleTimer.GetElapsedTime() / m_wiggleTimer.GetCountdownDuration());
const float amp = 6.0f * swimPower;
float wiggle = amp * sin( m_wigglePhase );
m_wigglePhase += m_wiggleRate * deltaT;
// wiggle decay
const float wiggleDecay = 5.0f;
m_wiggleRate -= wiggleDecay * deltaT;
m_angles.y += wiggle;
}
break;
}
}
// compute error between our local position and actual server position
Vector error = m_actualPos - m_pos;
error.z = 0.0f;
float errorLen = error.Length();
if (m_localLifeState == LIFE_ALIVE)
{
// if error is far above average, start swimming
const float wiggleThreshold = 2.0f;
if (errorLen - m_averageError > wiggleThreshold)
{
// if error is large, we must have started swimming
const float swimTime = 5.0f;
m_wiggleTimer.Start( swimTime );
m_wiggleRate = 2.0f * errorLen;
const float maxWiggleRate = 30.0f;
if (m_wiggleRate > maxWiggleRate)
{
m_wiggleRate = maxWiggleRate;
}
}
// update average error
m_errorHistory[ m_errorHistoryIndex++ ] = errorLen;
if (m_errorHistoryIndex >= MAX_ERROR_HISTORY)
{
m_errorHistoryIndex = 0;
m_errorHistoryCount = MAX_ERROR_HISTORY;
}
else if (m_errorHistoryCount < MAX_ERROR_HISTORY)
{
++m_errorHistoryCount;
}
m_averageError = 0.0f;
if (m_errorHistoryCount)
{
for( int r=0; r<m_errorHistoryCount; ++r )
{
m_averageError += m_errorHistory[r];
}
m_averageError /= (float)m_errorHistoryCount;
}
}
// keep fish motion smooth by correcting towards actual server position
// NOTE: This only tracks XY motion
const float maxError = 20.0f;
float errorT = errorLen / maxError;
if (errorT > 1.0f)
{
errorT = 1.0f;
}
// we want a nonlinear spring force for tracking
errorT *= errorT;
// as fish move faster, their error increases - use a stiffer spring when fast, and a weak one when slow
const float trackRate = 0.0f + errorT * 115.0f;
m_vel.x += trackRate * error.x * deltaT;
m_vel.y += trackRate * error.y * deltaT;
const float trackDrag = 2.0f + errorT * 6.0f;
m_vel.x -= trackDrag * m_vel.x * deltaT;
m_vel.y -= trackDrag * m_vel.y * deltaT;
// euler integration
m_pos += m_vel * deltaT;
SetNetworkOrigin( m_pos );
SetAbsOrigin( m_pos );
SetNetworkAngles( m_angles );
SetAbsAngles( m_angles );
}
//-----------------------------------------------------------------------------
void C_Fish::OnDataChanged( DataUpdateType_t type )
{
//if (!m_gotUpdate)
if (type == DATA_UPDATE_CREATED)
{
// initial update
m_gotUpdate = true;
m_pos = m_actualPos;
m_vel = Vector( 0, 0, 0 );
return;
}
}

View File

@ -0,0 +1,301 @@
#include "cbase.h"
#include "forcefeedback.h"
#include "hud_macros.h"
#include "input.h"
#define FF_CLIENT_FLAG 0x8000
class FFParams
{
public:
FORCEFEEDBACK_t m_nEffectType;
FFBaseParams_t m_BaseParams;
};
struct FFEffectInfo_t
{
FORCEFEEDBACK_t effectType;
char const *name;
};
#define DECLARE_FFEFFECT( name ) { name, #name }
static FFEffectInfo_t g_EffectTypes[] =
{
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_SINGLE ),
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_DOUBLE ),
DECLARE_FFEFFECT( FORCE_FEEDBACK_TAKEDAMAGE ),
DECLARE_FFEFFECT( FORCE_FEEDBACK_SCREENSHAKE ),
DECLARE_FFEFFECT( FORCE_FEEDBACK_SKIDDING ),
DECLARE_FFEFFECT( FORCE_FEEDBACK_BREAKING )
};
//-----------------------------------------------------------------------------
// Purpose:
// Input : effect -
// Output : char const
//-----------------------------------------------------------------------------
char const *NameForForceFeedbackEffect( FORCEFEEDBACK_t effect )
{
int c = ARRAYSIZE( g_EffectTypes );
if ( (int)effect < 0 || (int)effect >= c )
return "???";
const FFEffectInfo_t& info = g_EffectTypes[ (int)effect ];
Assert( info.effectType == effect );
return info.name;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *name -
// Output : FORCEFEEDBACK_t
//-----------------------------------------------------------------------------
FORCEFEEDBACK_t ForceFeedbackEffectForName( const char *name )
{
int c = ARRAYSIZE( g_EffectTypes );
for ( int i = 0 ; i < c; ++i )
{
const FFEffectInfo_t& info = g_EffectTypes[ i ];
if ( !Q_stricmp( info.name, name ) )
return info.effectType;
}
return ( FORCEFEEDBACK_t )-1;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CForceFeedback : public IForceFeedback, public CAutoGameSystem
{
public:
virtual bool Init();
virtual void Shutdown();
// API
virtual void StopAllEffects( CBasePlayer *player );
virtual void StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect );
virtual void StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params );
virtual void PauseAll( CBasePlayer *player );
virtual void ResumeAll( CBasePlayer *player );
void MsgFunc_ForceFeedback( bf_read &msg );
private:
void Internal_StopAllEffects();
void Internal_StopEffect( FORCEFEEDBACK_t effect );
void Internal_StartEffect( FORCEFEEDBACK_t, const FFBaseParams_t& params );
void Internal_PauseAll();
void Internal_ResumeAll();
};
static CForceFeedback g_ForceFeedbackSingleton;
IForceFeedback *forcefeedback = &g_ForceFeedbackSingleton;
//-----------------------------------------------------------------------------
// Purpose:
// Input : &msg -
//-----------------------------------------------------------------------------
void __MsgFunc_ForceFeedback( bf_read &msg )
{
g_ForceFeedbackSingleton.MsgFunc_ForceFeedback( msg );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CForceFeedback::Init()
{
HOOK_MESSAGE( ForceFeedback );
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CForceFeedback::Shutdown()
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *player -
//-----------------------------------------------------------------------------
void CForceFeedback::StopAllEffects( CBasePlayer *player )
{
if ( !player )
return;
Internal_StopAllEffects();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *player -
// effect -
//-----------------------------------------------------------------------------
void CForceFeedback::StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect )
{
if ( !player )
return;
Internal_StopEffect( effect );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *player -
// effect -
// params -
//-----------------------------------------------------------------------------
void CForceFeedback::StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params )
{
if ( !player )
{
return;
}
Internal_StartEffect( effect, params );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *player -
//-----------------------------------------------------------------------------
void CForceFeedback::PauseAll( CBasePlayer *player )
{
if ( !player )
return;
Internal_PauseAll();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *player -
//-----------------------------------------------------------------------------
void CForceFeedback::ResumeAll( CBasePlayer *player )
{
if ( !player )
return;
Internal_ResumeAll();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CForceFeedback::Internal_StopAllEffects()
{
input->ForceFeedback_StopAll();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : heffect -
//-----------------------------------------------------------------------------
void CForceFeedback::Internal_StopEffect( FORCEFEEDBACK_t effect )
{
input->ForceFeedback_Stop( effect );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : effect -
//-----------------------------------------------------------------------------
void CForceFeedback::Internal_StartEffect( FORCEFEEDBACK_t effect, const FFBaseParams_t& params)
{
char const *name = NameForForceFeedbackEffect( effect );
Msg( "Starting FF effect '%s'\n", name );
FFParams p;
p.m_nEffectType = effect;
p.m_BaseParams = params;
input->ForceFeedback_Start( effect, params );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CForceFeedback::Internal_PauseAll()
{
input->ForceFeedback_Pause();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CForceFeedback::Internal_ResumeAll()
{
input->ForceFeedback_Resume();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pszName -
// iSize -
// *pbuf -
//-----------------------------------------------------------------------------
void CForceFeedback::MsgFunc_ForceFeedback( bf_read &msg )
{
byte msgType = msg.ReadByte();
switch ( msgType )
{
default:
{
Warning( "Bad parse in MsgFunc_ForceFeedback!\n" );
}
break;
case FFMSG_STOPALL:
{
Internal_StopAllEffects();
}
break;
case FFMSG_START:
{
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
FFBaseParams_t params;
params.m_flDirection = 360.0f * ( (byte)msg.ReadByte() / 255.0f );
params.m_flDuration = (float)msg.ReadLong() / 1000.0f;
params.m_flGain = ( (byte)msg.ReadByte() / 255.0f );
params.m_nPriority = msg.ReadByte();
params.m_bSolo = msg.ReadByte() == 0 ? false : true;
if ( effectType >= 0 && effectType < NUM_FORCE_FEEDBACK_PRESETS )
{
Internal_StartEffect( effectType, params );
}
else
{
Warning( "Bad parse in MsgFunc_ForceFeedback, FFMSG_START (%i)!\n", effectType );
}
}
break;
case FFMSG_STOP:
{
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
Internal_StopEffect( effectType );
}
break;
case FFMSG_PAUSE:
{
Internal_PauseAll();
}
break;
case FFMSG_RESUME:
{
Internal_ResumeAll();
}
break;
}
}

View File

@ -0,0 +1,140 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "view.h"
#include "model_types.h"
#include "IVRenderView.h"
#include "engine/ivmodelinfo.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define VIEWER_PADDING 80.0f
class C_FuncAreaPortalWindow : public C_BaseEntity
{
public:
DECLARE_CLIENTCLASS();
DECLARE_CLASS( C_FuncAreaPortalWindow, C_BaseEntity );
// Overrides.
public:
virtual void ComputeFxBlend();
virtual bool IsTransparent();
virtual int DrawModel( int flags );
virtual bool ShouldReceiveProjectedTextures( int flags );
private:
float GetDistanceBlend();
public:
float m_flFadeStartDist; // Distance at which it starts fading (when <= this, alpha=m_flTranslucencyLimit).
float m_flFadeDist; // Distance at which it becomes solid.
// 0-1 value - minimum translucency it's allowed to get to.
float m_flTranslucencyLimit;
int m_iBackgroundModelIndex;
};
IMPLEMENT_CLIENTCLASS_DT( C_FuncAreaPortalWindow, DT_FuncAreaPortalWindow, CFuncAreaPortalWindow )
RecvPropFloat( RECVINFO( m_flFadeStartDist ) ),
RecvPropFloat( RECVINFO( m_flFadeDist ) ),
RecvPropFloat( RECVINFO( m_flTranslucencyLimit ) ),
RecvPropInt( RECVINFO( m_iBackgroundModelIndex ) )
END_RECV_TABLE()
void C_FuncAreaPortalWindow::ComputeFxBlend()
{
// We reset our blend down below so pass anything except 0 to the renderer.
m_nRenderFXBlend = 255;
#ifdef _DEBUG
m_nFXComputeFrame = gpGlobals->framecount;
#endif
}
bool C_FuncAreaPortalWindow::IsTransparent()
{
return true;
}
int C_FuncAreaPortalWindow::DrawModel( int flags )
{
if ( !m_bReadyToDraw )
return 0;
if( !GetModel() )
return 0;
// Make sure we're a brush model.
int modelType = modelinfo->GetModelType( GetModel() );
if( modelType != mod_brush )
return 0;
// Draw the fading version.
render->SetBlend( GetDistanceBlend() );
render->DrawBrushModel(
this,
(model_t *)GetModel(),
GetAbsOrigin(),
GetAbsAngles(),
!!(flags & STUDIO_TRANSPARENCY) );
// Draw the optional foreground model next.
// Only use the alpha in the texture from the thing in the front.
if (m_iBackgroundModelIndex >= 0)
{
render->SetBlend( 1 );
model_t *pBackground = ( model_t * )modelinfo->GetModel( m_iBackgroundModelIndex );
if( pBackground && modelinfo->GetModelType( pBackground ) == mod_brush )
{
render->DrawBrushModel(
this,
pBackground,
GetAbsOrigin(),
GetAbsAngles(),
!!(flags & STUDIO_TRANSPARENCY) );
}
}
return 1;
}
float C_FuncAreaPortalWindow::GetDistanceBlend()
{
// Get the viewer's distance to us.
float flDist = CollisionProp()->CalcDistanceFromPoint( CurrentViewOrigin() );
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
if ( local )
{
flDist *= local->GetFOVDistanceAdjustFactor();
}
return RemapValClamped( flDist, m_flFadeStartDist, m_flFadeDist, m_flTranslucencyLimit, 1 );
}
bool C_FuncAreaPortalWindow::ShouldReceiveProjectedTextures( int flags )
{
return false;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#include "cbase.h"
#include "materialsystem/IMaterialProxy.h"
#include "materialsystem/IMaterial.h"
#include "materialsystem/IMaterialVar.h"
#include "FunctionProxy.h"
#include <KeyValues.h>
#include "mathlib/VMatrix.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
class C_FuncConveyor : public C_BaseEntity
{
public:
DECLARE_CLASS( C_FuncConveyor, C_BaseEntity );
DECLARE_CLIENTCLASS();
C_FuncConveyor();
float GetConveyorSpeed() { return m_flConveyorSpeed; }
private:
float m_flConveyorSpeed;
};
IMPLEMENT_CLIENTCLASS_DT( C_FuncConveyor, DT_FuncConveyor, CFuncConveyor )
RecvPropFloat( RECVINFO( m_flConveyorSpeed ) ),
END_RECV_TABLE()
C_FuncConveyor::C_FuncConveyor()
{
m_flConveyorSpeed = 0.0;
}
class CConveyorMaterialProxy : public IMaterialProxy
{
public:
CConveyorMaterialProxy();
virtual ~CConveyorMaterialProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pC_BaseEntity );
virtual void Release( void ) { delete this; }
virtual IMaterial *GetMaterial();
private:
C_BaseEntity *BindArgToEntity( void *pArg );
IMaterialVar *m_pTextureScrollVar;
};
CConveyorMaterialProxy::CConveyorMaterialProxy()
{
m_pTextureScrollVar = NULL;
}
CConveyorMaterialProxy::~CConveyorMaterialProxy()
{
}
bool CConveyorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
char const* pScrollVarName = pKeyValues->GetString( "textureScrollVar" );
if( !pScrollVarName )
return false;
bool foundVar;
m_pTextureScrollVar = pMaterial->FindVar( pScrollVarName, &foundVar, false );
if( !foundVar )
return false;
return true;
}
C_BaseEntity *CConveyorMaterialProxy::BindArgToEntity( void *pArg )
{
IClientRenderable *pRend = (IClientRenderable *)pArg;
return pRend->GetIClientUnknown()->GetBaseEntity();
}
void CConveyorMaterialProxy::OnBind( void *pC_BaseEntity )
{
if( !pC_BaseEntity )
return;
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
if ( !pEntity )
return;
C_FuncConveyor *pConveyor = dynamic_cast<C_FuncConveyor*>(pEntity);
if ( !pConveyor )
return;
if ( !m_pTextureScrollVar )
{
return;
}
float flConveyorSpeed = pConveyor->GetConveyorSpeed();
float flRate = abs( flConveyorSpeed ) / 128.0;
float flAngle = (flConveyorSpeed >= 0) ? 180 : 0;
float sOffset = gpGlobals->curtime * cos( flAngle * ( M_PI / 180.0f ) ) * flRate;
float tOffset = gpGlobals->curtime * sin( flAngle * ( M_PI / 180.0f ) ) * flRate;
// make sure that we are positive
if( sOffset < 0.0f )
{
sOffset += 1.0f + -( int )sOffset;
}
if( tOffset < 0.0f )
{
tOffset += 1.0f + -( int )tOffset;
}
// make sure that we are in a [0,1] range
sOffset = sOffset - ( int )sOffset;
tOffset = tOffset - ( int )tOffset;
if (m_pTextureScrollVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)
{
VMatrix mat;
MatrixBuildTranslation( mat, sOffset, tOffset, 0.0f );
m_pTextureScrollVar->SetMatrixValue( mat );
}
else
{
m_pTextureScrollVar->SetVecValue( sOffset, tOffset, 0.0f );
}
if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}
IMaterial *CConveyorMaterialProxy::GetMaterial()
{
return m_pTextureScrollVar ? m_pTextureScrollVar->GetOwningMaterial() : NULL;
}
EXPOSE_INTERFACE( CConveyorMaterialProxy, IMaterialProxy, "ConveyorScroll" IMATERIAL_PROXY_INTERFACE_VERSION );

365
game/client/c_func_dust.cpp Normal file
View File

@ -0,0 +1,365 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "fx.h"
#include "c_func_dust.h"
#include "func_dust_shared.h"
#include "c_te_particlesystem.h"
#include "env_wind_shared.h"
#include "engine/IEngineTrace.h"
#include "tier0/vprof.h"
#include "ClientEffectPrecacheSystem.h"
#include "particles_ez.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_Func_Dust, DT_Func_Dust, CFunc_Dust )
RecvPropInt( RECVINFO(m_Color) ),
RecvPropInt( RECVINFO(m_SpawnRate) ),
RecvPropFloat( RECVINFO(m_flSizeMin) ),
RecvPropFloat( RECVINFO(m_flSizeMax) ),
RecvPropInt( RECVINFO(m_LifetimeMin) ),
RecvPropInt( RECVINFO(m_LifetimeMax) ),
RecvPropInt( RECVINFO(m_DustFlags) ),
RecvPropInt( RECVINFO(m_SpeedMax) ),
RecvPropInt( RECVINFO(m_DistMax) ),
RecvPropInt( RECVINFO( m_nModelIndex ) ),
RecvPropFloat( RECVINFO( m_FallSpeed ) ),
RecvPropDataTable( RECVINFO_DT( m_Collision ), 0, &REFERENCE_RECV_TABLE(DT_CollisionProperty) ),
END_RECV_TABLE()
// ------------------------------------------------------------------------------------ //
// CDustEffect implementation.
// ------------------------------------------------------------------------------------ //
#define DUST_ACCEL 50
void CDustEffect::RenderParticles( CParticleRenderIterator *pIterator )
{
const CFuncDustParticle *pParticle = (const CFuncDustParticle*)pIterator->GetFirst();
while ( pParticle )
{
// Velocity.
float flAlpha;
if( m_pDust->m_DustFlags & DUSTFLAGS_FROZEN )
{
flAlpha = 1;
}
else
{
// Alpha.
float flAngle = (pParticle->m_flLifetime / pParticle->m_flDieTime) * M_PI * 2;
flAlpha = sin( flAngle - (M_PI * 0.5f) ) * 0.5f + 0.5f;
}
Vector tPos;
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos );
float sortKey = (int) tPos.z;
if( -tPos.z <= m_pDust->m_DistMax )
{
flAlpha *= 1 + (tPos.z / m_pDust->m_DistMax);
// Draw it.
float flSize = pParticle->m_flSize;
if( m_pDust->m_DustFlags & DUSTFLAGS_SCALEMOTES )
flSize *= -tPos.z;
RenderParticle_Color255Size(
pIterator->GetParticleDraw(),
tPos,
Vector( m_pDust->m_Color.r, m_pDust->m_Color.g, m_pDust->m_Color.b ),
flAlpha * m_pDust->m_Color.a,
flSize
);
}
pParticle = (const CFuncDustParticle*)pIterator->GetNext( sortKey );
}
}
void CDustEffect::SimulateParticles( CParticleSimulateIterator *pIterator )
{
Vector vecWind;
GetWindspeedAtTime( gpGlobals->curtime, vecWind );
CFuncDustParticle *pParticle = (CFuncDustParticle*)pIterator->GetFirst();
while ( pParticle )
{
// Velocity.
if( !(m_pDust->m_DustFlags & DUSTFLAGS_FROZEN) )
{
// Kill the particle?
pParticle->m_flLifetime += pIterator->GetTimeDelta();
if( pParticle->m_flLifetime >= pParticle->m_flDieTime )
{
pIterator->RemoveParticle( pParticle );
}
else
{
for ( int i = 0 ; i < 2 ; i++ )
{
if ( pParticle->m_vVelocity[i] < vecWind[i] )
{
pParticle->m_vVelocity[i] += ( gpGlobals->frametime * DUST_ACCEL );
// clamp
if ( pParticle->m_vVelocity[i] > vecWind[i] )
pParticle->m_vVelocity[i] = vecWind[i];
}
else if (pParticle->m_vVelocity[i] > vecWind[i] )
{
pParticle->m_vVelocity[i] -= ( gpGlobals->frametime * DUST_ACCEL );
// clamp.
if ( pParticle->m_vVelocity[i] < vecWind[i] )
pParticle->m_vVelocity[i] = vecWind[i];
}
}
// Apply velocity.
pParticle->m_Pos.MulAdd( pParticle->m_Pos, pParticle->m_vVelocity, pIterator->GetTimeDelta() );
}
}
pParticle = (CFuncDustParticle*)pIterator->GetNext();
}
}
// ------------------------------------------------------------------------------------ //
// C_Func_Dust implementation.
// ------------------------------------------------------------------------------------ //
C_Func_Dust::C_Func_Dust() : m_Effect( "C_Func_Dust" )
{
m_Effect.m_pDust = this;
m_Effect.SetDynamicallyAllocated( false ); // So it doesn't try to delete itself.
}
C_Func_Dust::~C_Func_Dust()
{
}
void C_Func_Dust::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged( updateType );
if( updateType == DATA_UPDATE_CREATED )
{
m_hMaterial = m_Effect.GetPMaterial( "particle/sparkles" );
m_Effect.SetSortOrigin( WorldSpaceCenter( ) );
// Let us think each frame.
SetNextClientThink( CLIENT_THINK_ALWAYS );
// If we're setup to be frozen, just make a bunch of particles initially.
if( m_DustFlags & DUSTFLAGS_FROZEN )
{
for( int i=0; i < m_SpawnRate; i++ )
{
AttemptSpawnNewParticle();
}
}
}
m_Spawner.Init( m_SpawnRate ); // N particles per second
}
void C_Func_Dust::ClientThink()
{
// If frozen, don't make new particles.
if( m_DustFlags & DUSTFLAGS_FROZEN )
return;
// Spawn particles?
if( m_DustFlags & DUSTFLAGS_ON )
{
float flDelta = min( gpGlobals->frametime, 0.1f );
while( m_Spawner.NextEvent( flDelta ) )
{
AttemptSpawnNewParticle();
}
}
// Tell the particle manager our bbox.
Vector vWorldMins, vWorldMaxs;
CollisionProp()->WorldSpaceAABB( &vWorldMins, &vWorldMaxs );
vWorldMins -= Vector( m_flSizeMax, m_flSizeMax, m_flSizeMax );
vWorldMaxs += Vector( m_flSizeMax, m_flSizeMax, m_flSizeMax );
m_Effect.GetBinding().SetBBox( vWorldMins, vWorldMaxs );
}
bool C_Func_Dust::ShouldDraw()
{
return false;
}
void C_Func_Dust::AttemptSpawnNewParticle()
{
// Find a random spot inside our bmodel.
static int nTests=10;
for( int iTest=0; iTest < nTests; iTest++ )
{
Vector vPercent = RandomVector( 0, 1 );
Vector vTest = WorldAlignMins() + (WorldAlignMaxs() - WorldAlignMins()) * vPercent;
int contents = enginetrace->GetPointContents_Collideable( GetCollideable(), vTest );
if( contents & CONTENTS_SOLID )
{
CFuncDustParticle *pParticle = (CFuncDustParticle*)m_Effect.AddParticle( 10, m_hMaterial, vTest );
if( pParticle )
{
pParticle->m_vVelocity = RandomVector( -m_SpeedMax, m_SpeedMax );
pParticle->m_vVelocity.z -= m_FallSpeed;
pParticle->m_flLifetime = 0;
pParticle->m_flDieTime = RemapVal( rand(), 0, RAND_MAX, m_LifetimeMin, m_LifetimeMax );
if( m_DustFlags & DUSTFLAGS_SCALEMOTES )
pParticle->m_flSize = RemapVal( rand(), 0, RAND_MAX, m_flSizeMin/10000.0f, m_flSizeMax/10000.0f );
else
pParticle->m_flSize = RemapVal( rand(), 0, RAND_MAX, m_flSizeMin, m_flSizeMax );
pParticle->m_Color = m_Color;
}
break;
}
}
}
//
// Dust
//
//-----------------------------------------------------------------------------
// Spew out dust!
//-----------------------------------------------------------------------------
void FX_Dust( const Vector &vecOrigin, const Vector &vecDirection, float flSize, float flSpeed )
{
VPROF_BUDGET( "FX_Dust", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
int numPuffs = (flSize*0.5f);
if ( numPuffs < 1 )
numPuffs = 1;
if ( numPuffs > 32 )
numPuffs = 32;
float speed = flSpeed * 0.1f;
if ( speed < 0 )
speed = 1.0f;
if (speed > 48.0f )
speed = 48.0f;
//FIXME: Better sampling area
Vector offset = vecOrigin + ( vecDirection * flSize );
//Find area ambient light color and use it to tint smoke
Vector worldLight = WorldGetLightForPoint( offset, true );
// Throw puffs
SimpleParticle particle;
for ( int i = 0; i < numPuffs; i++ )
{
offset.Random( -(flSize*0.25f), flSize*0.25f );
offset += vecOrigin + ( vecDirection * flSize );
particle.m_Pos = offset;
particle.m_flLifetime = 0.0f;
particle.m_flDieTime = random->RandomFloat( 0.4f, 1.0f );
particle.m_vecVelocity = vecDirection * random->RandomFloat( speed*0.5f, speed ) * i;
particle.m_vecVelocity[2] = 0.0f;
int color = random->RandomInt( 48, 64 );
particle.m_uchColor[0] = (color+16) + ( worldLight[0] * (float) color );
particle.m_uchColor[1] = (color+8) + ( worldLight[1] * (float) color );
particle.m_uchColor[2] = color + ( worldLight[2] * (float) color );
particle.m_uchStartAlpha= random->RandomInt( 64, 128 );
particle.m_uchEndAlpha = 0;
particle.m_uchStartSize = random->RandomInt( 2, 8 );
particle.m_uchEndSize = random->RandomInt( 24, 48 );
particle.m_flRoll = random->RandomInt( 0, 360 );
particle.m_flRollDelta = random->RandomFloat( -0.5f, 0.5f );
AddSimpleParticle( &particle, g_Mat_DustPuff[random->RandomInt(0,1)] );
}
}
class C_TEDust: public C_TEParticleSystem
{
public:
DECLARE_CLASS( C_TEDust, C_TEParticleSystem );
DECLARE_CLIENTCLASS();
C_TEDust();
virtual ~C_TEDust();
public:
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual bool ShouldDraw() { return true; }
public:
float m_flSize;
float m_flSpeed;
Vector m_vecDirection;
protected:
void GetDustColor( Vector &color );
};
IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEDust, DT_TEDust, CTEDust )
RecvPropFloat(RECVINFO(m_flSize)),
RecvPropFloat(RECVINFO(m_flSpeed)),
RecvPropVector(RECVINFO(m_vecDirection)),
END_RECV_TABLE()
//==================================================
// C_TEDust
//==================================================
C_TEDust::C_TEDust()
{
}
C_TEDust::~C_TEDust()
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : bNewEntity - whether or not to start a new entity
//-----------------------------------------------------------------------------
void C_TEDust::PostDataUpdate( DataUpdateType_t updateType )
{
FX_Dust( m_vecOrigin, m_vecDirection, m_flSize, m_flSpeed );
}
void TE_Dust( IRecipientFilter& filter, float delay,
const Vector &pos, const Vector &dir, float size, float speed )
{
FX_Dust( pos, dir, size, speed );
}

112
game/client/c_func_dust.h Normal file
View File

@ -0,0 +1,112 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef C_FUNC_DUST_H
#define C_FUNC_DUST_H
#ifdef _WIN32
#pragma once
#endif
#include "c_baseentity.h"
#include "particles_simple.h"
#include "particle_util.h"
#include "bspflags.h"
// ------------------------------------------------------------------------------------ //
// CDustEffect particle renderer.
// ------------------------------------------------------------------------------------ //
class C_Func_Dust;
class CFuncDustParticle : public Particle
{
public:
Vector m_vVelocity;
float m_flLifetime;
float m_flDieTime;
float m_flSize;
color32 m_Color;
};
class CDustEffect : public CParticleEffect
{
public:
CDustEffect( const char *pDebugName ) : CParticleEffect( pDebugName ) {}
virtual void RenderParticles( CParticleRenderIterator *pIterator );
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
C_Func_Dust *m_pDust;
private:
CDustEffect( const CDustEffect & ); // not defined, not accessible
};
// ------------------------------------------------------------------------------------ //
// C_Func_Dust class.
// ------------------------------------------------------------------------------------ //
class C_Func_Dust : public C_BaseEntity
{
public:
DECLARE_CLASS( C_Func_Dust, C_BaseEntity );
DECLARE_CLIENTCLASS();
C_Func_Dust();
virtual ~C_Func_Dust();
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void ClientThink();
virtual bool ShouldDraw();
private:
void AttemptSpawnNewParticle();
// Vars from server.
public:
color32 m_Color;
int m_SpawnRate;
float m_flSizeMin;
float m_flSizeMax;
int m_SpeedMax;
int m_LifetimeMin;
int m_LifetimeMax;
int m_DistMax;
float m_FallSpeed; // extra 'gravity'
public:
int m_DustFlags; // Combination of DUSTFLAGS_
public:
CDustEffect m_Effect;
PMaterialHandle m_hMaterial;
TimedEvent m_Spawner;
private:
C_Func_Dust( const C_Func_Dust & ); // not defined, not accessible
};
#endif // C_FUNC_DUST_H

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